狡诈师
本帖最后由 狡诈师 于 2021-2-8 21:48 编辑





                              [ ! ] 阅读本文需要具备
                                         -  Kotlin 编程语言
                                         -  熟悉Bukkit开发
                                         -  搭起TabooLib为基础的项目

                              [ ! ] 相关链接
                                         -  [前置][开源][PCD]TabooLib ——  老坏黑的祖传病毒 [1.8-1.16]
                                         -  TabooLib Doc
                                         -  [SCT]玩转ProtocolLib数据包发包,将它玩出花样吧[发包|监听]

                              [ ! ] 本文采用
                                         -  编程语言:Kotlin
                                         -  内置依赖:TabooLib
                                         -  游戏版本:1.16.4



相信有一部分的人愁于

那么,一个强大的TabooLib值得你拥有
为什么呢?



前言
我是翻阅一些基于TabooLib相关数据包项目找到规律的,自己动手后发现并不难,并且于ProtocolLib的Wiki有很大的相关性,当然,NMS也不例外
此教程初衷让开发者学用TabooLib NMS发包




包名、类名没有特别要求
  1. abstract class NMS { // 抽象类,注意类名无特别要求
  2. companion object { // 伴生对象,静态那种懂吗

  3.         @TInject(asm = "cn.inrhor.nms.impl.NMSImpl") // asm是版本转换(坏黑说的),不懂就接着阅读就知道了
  4.         lateinit var INSTANCE: NMS // 声明变量,让外部访问操纵NMS
  5.         internal val version = Version.getCurrentVersionInt() // 声明变量,为了判断版本

  6.         /**
  7.          * 发送数据包方法
  8.          *
  9.          * @param player 玩家
  10.          * @param packet 数据包
  11.          * @param fields vararg指可变参数,fields 为了将数据包中各个值写入包
  12.          */
  13.         fun sendPacket(player: Player, packet: Any, vararg fields: Pair<String, Any>) {
  14.             TPacketHandler.sendPacket(player, setFields(packet, *fields))
  15.         }

  16.         /**
  17.          * 为了将数据包中各个值写入包
  18.          */
  19.         fun setFields(any: Any, vararg fields: Pair<String, Any>): Any {
  20.             fields.forEach { (key, value) ->
  21.                 Reflex.from(any.javaClass, any).set(key, value)
  22.             }
  23.             return any
  24.         }
  25.     }
  26. }
复制代码
另外,Reflex反射工具不在TabooLib本体项目而在另一个项目,其中关于 Reflex 源码在:https://github.com/TabooLib/Tabo ... ib/kotlin/Reflex.kt




拿生成数据包盔甲架为例吧
我在 [SCT]玩转ProtocolLib数据包发包,将它玩出花样吧[发包|监听] 写过有关发送生成数据包盔甲架例子:
  1. fun spawnAS(player: Player, entityID: Int, loc: Location) { // 构造方法,在Java中是void型
  2.         val packet = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY) // 示例一个PacketContainer
  3.         packet.modifier.writeDefaults() // 写入默认值

  4.         packet.integers.write(0, entityID) // 对integers的第0个写入实体ID,注意这里,实体ID不要重叠,否则会被覆盖
  5.         packet.uuiDs.write(0, UUID.randomUUID()) // 对UUID的第0个写入UUID值,这里使用了随机生成UUID值
  6.         packet.entityTypeModifier.write(0, EntityType.ARMOR_STAND) 对entityType的第0个写入实体类型,这里写入了盔甲架类型
  7.         packet.doubles.write(0, loc.x) // 对Double的第0个写入位置的X值,不写的话,你知道它在哪个角落躲着吗
  8.         packet.doubles.write(1, loc.y) // 对Double的第1个写入位置的Y值
  9.         packet.doubles.write(2, loc.z) // 对Double的第2个写入位置的Z值,这些顺序参照格式表(自己回去看格式表,第三个出现的Double就是位置的Z值)

  10.         sendServerPacket(player, packet) // 发送数据包
  11.     }
复制代码

从中可以看到需要最基本东西是 Player、EntitiIDUUIDXYZ
不过,在抽象方法中,我们可以简化下方法参数,只需要:Player、EntityIDLoaction(当然你可以加上UUID参数)
由继承它的类中完成具体的实现
于是写下这样的方法
  1.     /**
  2.      * 生成盔甲架
  3.      */
  4.     abstract fun spawnAS(player: Player, entityId: Int, location: Location)
复制代码

顺便一提,方法名没有特别要求




类名、包名没有特别要求
但要与 NMS.kt@TInject(asm = "cn.inrhor.nms.impl.NMSImpl") 包名和类名一致
即,创建包名 cn.inrhor.nms.impl ,创建类 NMSImpl
创建好后需要继承 NMS
  1. class NMSImpl : NMS() {
  2. |
复制代码




根据 NMS.ktspawnAS 方法那么要写一致的方法名、参数,然后在方法里做具体的实现
  1. override fun spawnAS(player: Player, entityId: Int, location: Location) {
  2.         sendPacket(
  3.             player,
  4.             PacketPlayOutSpawnEntity(),
  5.             "a" to entityId,
  6.             "b" to UUID.randomUUID(),
  7.             "c" to location.x,
  8.             "d" to location.y,
  9.             "e" to location.z,
  10.             "k" to EntityTypes.ARMOR_STAND
  11.         )
  12.     }
复制代码

解释:

然后一个发送数据包盔甲架方法完成了



  1. val player = ev.player
  2. val entitiID = 2333
  3. val loc = player.location
  4. NMS.INSTANCE.spawnAS(player, entitiID , loc)
复制代码



未完,待更




来自群组: Server CT