20.3.4 global[] 的使用


global[] 可以允许你在不重启游戏的情况下重新加载部分Startup阶段的脚本,或用于储存信息等。

一、Forge事件

以1.16.5中的Forge事件为例,其可改写为

// 使用global改写前
onForgeEvent("net.minecraftforge.event.entity.player.PlayerEvent$PlayerChangedDimensionEvent", event=>{
    event.player.sendStatusMessage("你来到了" + event.getTo().getLocation(), false)
})


// 使用global改写后
onForgeEvent('net.minecraftforge.event.entity.player.PlayerEvent$PlayerChangedDimensionEvent', event => {
    global['test_id'](event);
});

global['test_id'] = (event) => {
    event.player.sendStatusMessage("你来到了" + event.getTo().getLocation(), false)
}

改写后,你可以修改 global['test_id']的内容来在不重启游戏的情况下重新加载Forge事件内容,你可以使用 /kubejs reload startup_scripts 来重载该函数。

二、内容注册中的部分事件

类似地,部分内容注册中的事件也可以使用global改写(例如第七章 自定义方块中使用到的RandomTickEvent ):

// 使用global改写前
onEvent('block.registry', event => {
  event.create('test_block_randomTickEvent').displayName('Test Block randomTickEvent').randomTick(randomTickEvent => {
        randomTickEvent.block.set('minecraft:dirt');
      })
  })
})

// 使用global改写后
onEvent('block.registry', event => {
  event.create('test_block_randomTickEvent').displayName('Test Block randomTickEvent').randomTick(randomTickEvent => {
        global['test_id'](event);
      })
  })
})

global['test_id'] = (event) => {
    randomTickEvent.block.set('minecraft:dirt');
}

与之类似的还有食用食物的ItemFoodEatenEvent等,在此就不再赘述了。

三、存储数据

以下以存储玩家登入信息为例:

global['login_info'] = {}

// 获取格式化时间
var getFormattedTime = function(date){
    let currYear = date.getFullYear();
    let currMonth = date.getMonth() + 1;
    let currDay = date.getDate();
    let currHour = date.getHours();
    let currMinutes = date.getMinutes();
    let currSeconds = date.getSeconds();
    
    currMonth = (currMonth > 9) ? currMonth:"0" + currMonth;
    currDay = (currDay > 9) ? currDay:"0" + currDay;
    currHour = (currHour > 9) ? currHour:"0" + currHour;
    currMinutes = (currMinutes > 9) ? currMinutes:"0" + currMinutes;
    currSeconds = (currSeconds > 9) ? currSeconds:"0" + currSeconds;

    return `${currYear}-${currMonth}-${currDay} ${currHour}:${currMinutes}:${currSeconds}`;
}

// 玩家登入时记录信息
onEvent('player.logged_in',event => {
    let date = getFormattedTime(new Date());
    let p = event.player;
    global['login_info'][event.player.profile.name] = {time : date, pos: {x : p.x, y : p.y, z : p.z, dim : p.level.dimension}};
})

// 玩家退出时记录信息
onEvent('player.logged_out',event => {
    global['login_info'][event.player.profile.name] = null;
})

// 聊天信息获取
onEvent('player.chat',event => {
    let input = event.message.trim();
    if(input.substring(0,8) == "gameinfo"){
        // 传入登入信息对象
        event.server.scheduleInTicks(1, global['login_info'], function (callback) {
            let playerID = input.substring(9,);
            if(callback.data[playerID] == undefined){
                event.player.tell(Component.gold('====查询结果===='))
                event.player.tell(Component.red("未查询到该玩家在线信息!"));
                return;
            }
            let info = callback.data[playerID];
            let playerTime = info.time;
            let pos = info.pos;
            event.player.tell(Component.gold('====查询结果===='));
            event.player.tell(`玩家id:${playerID}\n登入时间:${playerTime}\n登入坐标:x = ${pos.x}, y = ${pos.y}, z = ${pos.z}\n登入维度:${pos.dim}`);
        })
        
    }
})

效果: