Skip to content

16 网络包和Painter API


一、网络包

事件:

客户端从服务端侧接收脚本player.data_from_server.<信道ID>

服务端从客户端侧接收脚本player.data_from_server.<信道ID>

// 监听玩家物品右键事件
// 你可以把下面这段脚本放到服务端或客户端脚本中,取决于你想从哪一侧发包
onEvent('item.right_click', event => {
  // 监听物品右键事件
  if (event.server) {
    // 发送 {test: 123} 到信道 "test_channel_1". 信道ID可以为任何字符串, 但还是推荐使用蛇形命名方法
    // 接收端为客户端 (发送端为服务端).
    event.player.sendData('test_channel_1', { test: 123 });// 发包
  } else {
    // 推荐使用不同信道 尽管这不是必须的
    // 收包 (发送端为客户端).
    event.player.sendData('test_channel_2', { test: 456 })// 发包
  }
})

// 监听从服务端收到网络包时的事件
// 这段是客户端脚本
onEvent('player.data_from_server.test_channel_1', event => {
  log.info(event.data.test) // 打印网络包信息到日志(123)
  event.player.tell(`来自客户端的网络包信息:${event.data.test}`)
})

// 监听从客户端收到网络包时的事件
// 这段是服务端脚本
onEvent('player.data_from_client.test_channel_2', event => {
  log.info(event.data.test) // 打印网络包信息到日志(456)
  event.server.runCommand(`say 来自服务端的网络包信息:${event.data.test}`)
})

二、Painter API

Painter API允许你在客户端屏幕上绘制内容,其可以从服务端控制也可以从客户端直接触发

目前(2022年5月10日)它不支持玩家输入/交互,但以后可能会支持游戏内菜单甚至是渲染引擎

Painter对象是以NBT/Json对象建立的,并且每一个都有自己的ID. 如果你没有提供一个的话,KubeJS就会随机生成一个. xz 是对象在屏幕上的的绝对坐标, 但你能将元素对齐到屏幕的给定位置。你可以在一个json对象中添加多个对象. 所有的属性都是可选的,但是显然你至少应该填写坐标和大小等信息。

paint({...})遵守更新插入法则,如果对象不存在则创建,若存在则更新其属性:

event.player.paint({example: {type: 'rectangle', x: 10, y: 10, w: 20, h: 20}}); // 新建矩形
event.player.paint({example: {x: 50}}); // 更新先前ID为example的Painter对象的x属性

你可以批量新建/修改Painter对象:

event.player.paint({a: {x: 10}, b: {x: 30}, c: {type: 'rectangle', x: 10}});

你可以使用remove来移除Painter对象:

event.player.paint({a: {remove: true}}); // 移除ID为a的Painter对象
event.player.paint({a: {remove: true}, b: {remove: true}}); // 批量移除多个对象
event.player.paint({'*': {remove: true}}); //移除全部

还记得在1.1中提到的/kubejs painter <玩家名称> <PainterJS对象>指令吗?它和上述的函数功能是一样的

/kubejs painter @p {example: {type: 'rectangle', x: 10, y: 10, w: 20, h: 20}}

如果创建对象时多次重复出现,推荐在玩家登录时创建对象并为其设置属性visible: false,之后在合适时间将该属性改为true以取消隐藏。值得注意的是,Painter对象在玩家离开服务器时会被清除,所以你需要在每次玩家登录时重新为其添加Painter对象。

可用对象

Underlined objects are not something you can create

(可用于所有对象)

  • Boolean visible

屏幕对象

(可用于所有屏幕/2D内容)

  • Unit x // x坐标
  • Unit y // y坐标
  • Unit z // z坐标
  • Unit w // 宽度
  • Unit h // 高度
  • Enum alignX (支持 'left', 'center', 'right') // x方向对齐参数
  • Enum alignY (支持 'top', 'center', 'bottom') // y方向对齐参数
  • Enum draw (支持 'ingame', 'gui', 'always') // 绘制场景
  • Unit moveX
  • Unit moveY
  • Unit expandW
  • Unit expandH

正方形

  • Color color
  • String texture
  • Float u0
  • Float v0
  • Float u1
  • Float v1

渐变(gradient)

  • Color color
  • Color colorT
  • Color colorB
  • Color colorL
  • Color colorR
  • Color colorTL
  • Color colorTR
  • Color colorBL
  • Color colorBR
  • String texture
  • Float u0
  • Float v0
  • Float u1
  • Float v1

文本

  • Text text
  • Boolean shadow
  • Float scale
  • Color color
  • Boolean centered

官方示例

onEvent('player.logged_in', event => {
	// 初始化Painter对象
	event.player.paint({
		example_rectangle: {
			type: 'rectangle',
			x: 10,
			y: 10,
			w: 50,
			h: 20,
			color: '#00FF00',
			draw: 'always'
		},
		last_message: {
			type: 'text',
			text: 'No last message',
			scale: 1.5,
			x: -4,
			y: -4,
			alignX: 'right',
			alignY: 'bottom',
			draw: 'always'
		}
	})
})

onEvent('player.chat', event => {
	// 更新 example_rectangle 的 x 值 和 last_message 文本的值为上次聊天文本
	event.player.paint({example_rectangle: {x: '(sin((time() * 1.1)) * (($screenW - 32) / 2))', w: 32, h: 32, alignX: 'center', texture: 'kubejs:textures/item/diamond_ore.png'}})
	event.player.paint({last_message: {text: `Last message: ${event.message}`}})
	// 一次更新两个对象,这两种方式没有区别,你想用哪个都行
	// event.player.paint({example_rectangle: {x: 120}, last_message: {text: `Last message: ${event.message}`}})
	event.player.paint({lava: {type: 'atlas_texture', texture: 'minecraft:block/lava_flow'}})
})

// TODO: 18.3 Painter API示例:服务器挖掘排行榜(显示挖掘方块最多的人)

Contributors

Changelog