本帖最后由 QingyuOvO 于 2022-1-7 00:31 编辑 
在1.12.2中我们是这么做的:
复制代码
原理大概就是把死前玩家的数据赋值给新的玩家,但是在1.14.3中使用类似的代码:
复制代码
却失效了。经过查看源代码发现forge的net.minecraftforge.common.capabilities.CapabilityProvider类的获取cap信息的方法是这样的:
复制代码而valid字段在这个Clone方法被调用很久之前就已经标记了false(在玩家死的时候就调用了,但是Clone是要点击“重生”按钮才会触发),这样我们似乎永远都不可能获取到玩家以前的Capability信息了。下面贴出这个类的全部代码,valid和getCapabilities()全都是protected,没法访问,而且由于这是forge的代码,at也没法用(看来就只能反射了?)
如果各位大佬以前也遇到过这个问题麻烦解惑一下,没遇到的也欢迎讨论。我将继续寻找解决方式,直至问题解决,其间过程都直接更新在帖子里。
问题解决了,最好用1.14.4,如果非要用1.14.3,那就反射。
——————————————————————————————————————————————————————————
刚才看了一下1.14.4的代码,果然,1.14.4他们认识到了这问题,把valid删除了。毁灭吧,赶紧的,累了。
感觉就好像是1.14forge换人开发了,新来的人对原来的逻辑不了解,结果把数据控制流程写坏了似的
——————————————————————————————————————————————————————————
用了一下反射,结果:

——————————————————————————————————————————————————————————
奇怪了,我什么都没做,但是bug消失了,不管怎么调试都不会出现被踢出游戏的问题了.....= =蒙了,这种隐患太难受了
——————————————————————————————————————————————————————————
问题解决了,看了日志,被踢出游戏的原因是我用的是kill指令,但是手按tab按得有点快,自动补全出来的是 kick,我真是佛了,真想抽死自己
在1.12.2中我们是这么做的:
- @SubscribeEvent
 
-     public void onPlayerClone(PlayerEvent.Clone event) {
 
-         Capability<SkillData> capability = SkillData.CAPABILITY_TYPE;
 
-         Capability.IStorage<SkillData> storage = capability.getStorage();
 
 
-         if (event.getOriginal().hasCapability(capability, null) && event.getEntityPlayer().hasCapability(capability, null)) {
 
-             NBTBase nbt = storage.writeNBT(capability, event.getOriginal().getCapability(capability, null), null);
 
-             storage.readNBT(capability, event.getEntityPlayer().getCapability(capability, null), null, nbt);
 
-         }
 
- }
原理大概就是把死前玩家的数据赋值给新的玩家,但是在1.14.3中使用类似的代码:
- @SubscribeEvent
 
-     public void cloneEvent(PlayerEvent.Clone event) {
 
-         Capability<ShikongData> capability = CapabilityProvider.CAPABILITY_TYPE;
 
-         Capability.IStorage<ShikongData> storage = capability.getStorage();
 
 
-         ShikongData stale = ShiKongInfoUtil.getPlayerShikongData(event.getOriginal());
 
-         ShikongData fresh = ShiKongInfoUtil.getPlayerShikongData(event.getEntityPlayer());
 
 
-         INBT nbt = storage.writeNBT(capability, stale, null);
 
-         storage.readNBT(capability, fresh, null, nbt);
 
- }
却失效了。经过查看源代码发现forge的net.minecraftforge.common.capabilities.CapabilityProvider类的获取cap信息的方法是这样的:
- @Override
 
-     @Nonnull
 
-     public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side)
 
-     {
 
-         final CapabilityDispatcher disp = getCapabilities();
 
-         return !valid || disp == null ? LazyOptional.empty() : disp.getCapability(cap, side);
 
- }
如果各位大佬以前也遇到过这个问题麻烦解惑一下,没遇到的也欢迎讨论。我将继续寻找解决方式,直至问题解决,其间过程都直接更新在帖子里。
问题解决了,最好用1.14.4,如果非要用1.14.3,那就反射。
——————————————————————————————————————————————————————————
刚才看了一下1.14.4的代码,果然,1.14.4他们认识到了这问题,把valid删除了。毁灭吧,赶紧的,累了。
感觉就好像是1.14forge换人开发了,新来的人对原来的逻辑不了解,结果把数据控制流程写坏了似的
——————————————————————————————————————————————————————————
用了一下反射,结果:

——————————————————————————————————————————————————————————
奇怪了,我什么都没做,但是bug消失了,不管怎么调试都不会出现被踢出游戏的问题了.....= =蒙了,这种隐患太难受了
——————————————————————————————————————————————————————————
问题解决了,看了日志,被踢出游戏的原因是我用的是kill指令,但是手按tab按得有点快,自动补全出来的是 kick,我真是佛了,真想抽死自己