本帖最后由 狡诈师 于 2021-1-16 14:01 编辑 
相关链接
对于ProtocolLib用法我摸索了很久才慢慢懂了(苦了娃),不过还不完全掌握
从这里你可以学到:
阅读前
了解ProtocolLib作用
在Wiki可以看到ProtocolLib可以做些什么
比如[SPAWN ENTITY],向某个玩家显示该实体而其它玩家没有看到(也就是说发送了[生成实体"SPAWN ENTITY"]包给某个玩家客户端,而服务器和未收到该包的玩家客户端不知道这个实体的存在)
引用 @梨子:https://www.mcbbs.net/thread-568714-1-1.html
发送欺骗服务端/客户端数据包
了解Wiki的格式表
看看Wiki数据包描述,以[SPAWN ENTITY]为例
该数据包目的:发送生成实体的数据包(注:纯发包的实体不能通过Bukkit获取实体,毕竟服务端不知道它的存在)

首栏解析
下面必须用到,你可以想象,你要是不填,会发生什么事
实践发送包,以发送数据包盔甲架为例
既然了解了格式,那么如何使用呢?
2020/10/17:本文基于1.16.X预览版(部分不适用于旧版)
Kotlin复制代码
复制代码复制代码这个event事件包含的方法你可以通过doc看:
当然,你可以监听客户端接收的数据包
这里以交互数据包盔甲架为例子
Kotlin(喂?Java呢?你看上面不就行吗,只是有一些不同罢了防伸手党滑稽)
和上面一样,需要被onEnable调用
在此之前,请翻阅wiki:https://wiki.vg/Protocol#Interact_Entity
复制代码
注意值得一提的是,若数据包盔甲架关闭了碰撞箱,是不会被交互,无法监听到
来自群组: Server CT
相关链接
对于ProtocolLib用法我摸索了很久才慢慢懂了(
从这里你可以学到:
- 了解ProtocolLib作用
- 了解Wiki的格式表
- 实践发送包-> 发送数据包盔甲架
- 实践监听包-> 交互数据包盔甲架
 
阅读前
- 请具备 Java or Kotlin 基础知识
 
了解ProtocolLib作用
在Wiki可以看到ProtocolLib可以做些什么
比如[SPAWN ENTITY],向某个玩家显示该实体而其它玩家没有看到(也就是说发送了[生成实体"SPAWN ENTITY"]包给某个玩家客户端,而服务器和未收到该包的玩家客户端不知道这个实体的存在)
引用 @梨子:https://www.mcbbs.net/thread-568714-1-1.html
- 给玩家发送一个伪造的数据包
- 让服务端认为接收到了一个玩家发送的数据包
- 监听/修改 客户端发送给服务端 的数据包
- 监听/修改 服务端发送给客户端 的数据包
 
- 实际上,你可以不需要ProtocolLib进行发送数据包,但是你会受到版本限制,而ProtocolLib更新很快,而且兼容超多版本,并且提供了Wiki详细的数据包描述
- 拦截数据包
- 还有什么..?
 
发送欺骗服务端/客户端数据包
了解Wiki的格式表
看看Wiki数据包描述,以[SPAWN ENTITY]为例
该数据包目的:发送生成实体的数据包(注:纯发包的实体不能通过Bukkit获取实体,毕竟服务端不知道它的存在)

首栏解析
- Packet ID:在?还需要解释吗
- State:状态(这里是Play,其它还有Login等等)
- Bound To:发送目标(这里指发送给客户端)
- Field Name:字段名称
- Field Type:字段类型
- Notes:显而易见,别跟我说你不懂,雾
 
下面必须用到,你可以想象,你要是不填,会发生什么事
- Entity ID[实体ID,唯一,否则直接覆盖] -> VarInt[int类型]
- Object UUID -> UUID (懂的都懂)
- Type[实体类型] -> 请在此处查找相关实体类型:https://wiki.vg/Entity_metadata#Mobs
- X[位置的X值] -> Double类型
- Y [位置的Y值] -> Double类型
- Z[位置的Z值] - > Double类型
 
- Pitch[向量] -> Angle值
- Yaw[向量] -> Angle值
- Data[数据] -> Int值,含义取决于 Type 值,相关内容请看:https://wiki.vg/Object_Data
- Velocity X[速度] -> Short值
- Velocity Y[速度] -> Short值
- Velocity Z[速度] -> Short值
 
实践发送包,以发送数据包盔甲架为例
既然了解了格式,那么如何使用呢?
2020/10/17:本文基于1.16.X预览版(部分不适用于旧版)
Kotlin
- 我用Kotlin不反对吧?(这样我可以防止Java复制党,滑稽)
- 如果你是Java使用者,实际上你还是能看得出来,诸如 integers 在Java中是 getIntegers
 
- fun spawnAS(player: Player, entityID: Int, loc: Location) { // 构造方法,在Java中是void型
 
-         val packet = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY) // 示例一个PacketContainer
 
-         packet.modifier.writeDefaults() // 写入默认值
 
 
-         packet.integers.write(0, entityID) // 对integers的第0个写入实体ID,注意这里,实体ID不要重叠,否则会被覆盖
 
-         packet.uuiDs.write(0, UUID.randomUUID()) // 对UUID的第0个写入UUID值,这里使用了随机生成UUID值
 
-         packet.entityTypeModifier.write(0, EntityType.ARMOR_STAND) 对entityType的第0个写入实体类型,这里写入了盔甲架类型
 
-         packet.doubles.write(0, loc.x) // 对Double的第0个写入位置的X值,不写的话,你知道它在哪个角落躲着吗
 
-         packet.doubles.write(1, loc.y) // 对Double的第1个写入位置的Y值
 
-         packet.doubles.write(2, loc.z) // 对Double的第2个写入位置的Z值,这些顺序参照格式表(自己回去看格式表,第三个出现的Double就是位置的Z值)
 
 
-         sendServerPacket(player, packet) // 发送数据包
 
-     }
 
 
- fun sendServerPacket(player: Player, packet: PacketContainer) { // 发送数据包方法
 
-         ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
 
- }
这里我补充下数据包类型PacketType内容吧
https://ci.dmulloy2.net/job/ProtocolLib/javadoc/com/comphenix/protocol/PacketType.html
- ForceAsync:数据包是否必须异步处理
- Handshake:握手时发送的数据包
- Login:登录时发送和接收的数据包
- Play:在游戏时发送和接收的数据包
- Protocol:不同的协议或连接状态
- Sender:数据包类型的发送者
- Status:[不太懂the multiplayer menu指什么菜单?]
 
- Client:来自客户端的数据包
- Server:来自服务端的数据包
 
数据包监听器
若要监听服务器向客户端发送的数据包
Java
首先在onEbale中实例化
- private ProtocolManager protocolManager;
 
 
- public void onLoad() {
 
-     protocolManager = ProtocolLibrary.getProtocolManager();
 
- }
- protocolManager.addPacketListener(
 
-   new PacketAdapter(主类, ListenerPriority.NORMAL, /*监听器级别*/
 
-           PacketType.Play.Server.NAMED_SOUND_EFFECT/*数据包类型,具体看wiki*/) {
 
-     @Override // 覆写发送的包,必须是onPacketSending,不然叫什么覆写
 
-     public void onPacketSending(PacketEvent event) { // 监听服务器发送数据包
 
-         if (event.getPacketType() == PacketType.Play.Server.NAMED_SOUND_EFFECT) { // 判断数据包类型,若是音乐数据包
 
-             event.setCancelled(true); // 取消该事件,也就是说,服务器发送的音乐数据包被被拦截,客户端不会收到该数据包
 
-         }
 
-     }
 
- });
- https://ci.dmulloy2.net/job/ProtocolLib/javadoc/com/comphenix/protocol/events/PacketEvent.html
 
这方面梨子讲解过了,我就不重复了:
- https://www.mcbbs.net/thread-568714-1-1.html
 
这里以交互数据包盔甲架为例子
Kotlin(喂?Java呢?你看上面不就行吗,只是有一些不同罢了
和上面一样,需要被onEnable调用
在此之前,请翻阅wiki:https://wiki.vg/Protocol#Interact_Entity
- protocolManager.getProtocolManager().addPacketListener(object :
 
-             PacketAdapter(主类,
 
-                 ListenerPriority.NORMAL,
 
-                 PacketType.Play.Client.USE_ENTITY) { // 数据包类型为交互实体
 
-             override fun onPacketReceiving(ev: PacketEvent) { // 覆写接收的包,必须是onPacketReceiving,不然叫什么覆写
 
-                 val packet = ev.packet // 获得数据包
 
-                 packet.integers.read(0) // 读取数据包
 
-                 if (packet.entityUseActions.values[0] != EnumWrappers.EntityUseAction.INTERACT) return // 判断交互动作
 
-                 // 做你想做的事情
 
-             }
 
- })
注意值得一提的是,若数据包盔甲架关闭了碰撞箱,是不会被交互,无法监听到
来自群组: Server CT
666666666666666
我方Java党人间大炮已瞄准作者
        MCBBS有你更精彩~
插件的inventory gui 如何发包给玩家.传统gui老是有各种刷物品的问题
冲冲冲冲冲冲冲冲冲
丶米饭 发表于 2021-1-13 18:08
插件的inventory gui 如何发包给玩家.传统gui老是有各种刷物品的问题
A哥的以下源码可以参考:
TrMenu:https://github.com/TrMenu/TrMenu
虚拟库存API:https://github.com/Arasple/Receptacle
这个教程有点简陋,还需要补充
插件的inventory gui 如何发包给玩家.传统gui老是有各种刷物品的问题
想知道怎么获得玩家的mods列表