ModPlayerList.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. package me.km.overrides;
  2. import com.google.common.collect.Lists;
  3. import com.mojang.authlib.GameProfile;
  4. import io.netty.buffer.Unpooled;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Optional;
  8. import java.util.UUID;
  9. import me.km.Server;
  10. import me.km.utils.ReflectionUtils;
  11. import net.minecraft.entity.Entity;
  12. import net.minecraft.entity.EntityType;
  13. import net.minecraft.entity.player.PlayerEntity;
  14. import net.minecraft.entity.player.ServerPlayerEntity;
  15. import net.minecraft.nbt.CompoundNBT;
  16. import net.minecraft.network.NetworkManager;
  17. import net.minecraft.network.PacketBuffer;
  18. import net.minecraft.network.play.ServerPlayNetHandler;
  19. import net.minecraft.network.play.server.SChangeGameStatePacket;
  20. import net.minecraft.network.play.server.SCustomPayloadPlayPacket;
  21. import net.minecraft.network.play.server.SHeldItemChangePacket;
  22. import net.minecraft.network.play.server.SJoinGamePacket;
  23. import net.minecraft.network.play.server.SPlayEntityEffectPacket;
  24. import net.minecraft.network.play.server.SPlayerAbilitiesPacket;
  25. import net.minecraft.network.play.server.SPlayerListItemPacket;
  26. import net.minecraft.network.play.server.SRespawnPacket;
  27. import net.minecraft.network.play.server.SServerDifficultyPacket;
  28. import net.minecraft.network.play.server.SSetExperiencePacket;
  29. import net.minecraft.network.play.server.SSpawnPositionPacket;
  30. import net.minecraft.network.play.server.STagsListPacket;
  31. import net.minecraft.network.play.server.SUpdateRecipesPacket;
  32. import net.minecraft.potion.EffectInstance;
  33. import net.minecraft.server.dedicated.DedicatedPlayerList;
  34. import net.minecraft.server.dedicated.DedicatedServer;
  35. import net.minecraft.server.management.DemoPlayerInteractionManager;
  36. import net.minecraft.server.management.PlayerInteractionManager;
  37. import net.minecraft.server.management.PlayerList;
  38. import net.minecraft.server.management.PlayerProfileCache;
  39. import net.minecraft.util.math.BlockPos;
  40. import net.minecraft.util.math.Vec3d;
  41. import net.minecraft.util.text.ITextComponent;
  42. import net.minecraft.util.text.TranslationTextComponent;
  43. import net.minecraft.world.GameRules;
  44. import net.minecraft.world.IWorld;
  45. import net.minecraft.world.server.ServerWorld;
  46. import net.minecraft.world.dimension.DimensionType;
  47. import net.minecraft.world.storage.WorldInfo;
  48. import org.apache.logging.log4j.LogManager;
  49. public final class ModPlayerList extends DedicatedPlayerList
  50. {
  51. private final DedicatedServer server;
  52. private final List<ServerPlayerEntity> players;
  53. private final Map<UUID, ServerPlayerEntity> uuidToPlayerMap;
  54. public ModPlayerList(DedicatedServer server)
  55. {
  56. super(server);
  57. this.server = server;
  58. this.players = getPlayers();
  59. this.uuidToPlayerMap = ReflectionUtils.getFieldValue(Map.class, PlayerList.class, this, "field_177454_f");
  60. }
  61. @Override
  62. public void initializeConnectionToPlayer(NetworkManager netManager, ServerPlayerEntity p)
  63. {
  64. GameProfile profile = p.getGameProfile();
  65. PlayerProfileCache cache = this.server.getPlayerProfileCache();
  66. cache.addEntry(profile);
  67. CompoundNBT compoundnbt = this.readPlayerDataFromFile(p);
  68. ServerWorld sw = this.server.getWorld(p.dimension);
  69. if (sw == null)
  70. {
  71. p.dimension = DimensionType.OVERWORLD;
  72. sw = this.server.getWorld(p.dimension);
  73. p.setPosition(sw.getWorldInfo().getSpawnX(), sw.getWorldInfo().getSpawnY(), sw.getWorldInfo().getSpawnZ());
  74. }
  75. p.setWorld(sw);
  76. p.interactionManager.setWorld((ServerWorld) p.world);
  77. String s1 = "local";
  78. if(netManager.getRemoteAddress() != null)
  79. {
  80. s1 = netManager.getRemoteAddress().toString();
  81. }
  82. LogManager.getLogger().info("{}[{}] logged in with entity id {} at ({}, {}, {})", p.getName().getString(), s1, p.getEntityId(), p.getPosX(), p.getPosY(), p.getPosZ());
  83. WorldInfo wi = sw.getWorldInfo();
  84. setPlayerGameTypeBasedOnOther(p, null, sw);
  85. ServerPlayNetHandler spnh = new ServerPlayNetHandler(server, netManager, p);
  86. net.minecraftforge.fml.network.NetworkHooks.sendMCRegistryPackets(netManager, "PLAY_TO_CLIENT");
  87. net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(netManager, p);
  88. GameRules gamerules = sw.getGameRules();
  89. spnh.sendPacket(new SJoinGamePacket(p.getEntityId(), p.interactionManager.getGameType(), WorldInfo.byHashing(wi.getSeed()), wi.isHardcore(), sw.dimension.getType(), this.getMaxPlayers(), wi.getGenerator(), getViewDistance(), gamerules.getBoolean(GameRules.REDUCED_DEBUG_INFO), !gamerules.getBoolean(GameRules.DO_IMMEDIATE_RESPAWN)));
  90. spnh.sendPacket(new SCustomPayloadPlayPacket(SCustomPayloadPlayPacket.BRAND, (new PacketBuffer(Unpooled.buffer())).writeString(this.getServer().getServerModName())));
  91. spnh.sendPacket(new SServerDifficultyPacket(wi.getDifficulty(), wi.isDifficultyLocked()));
  92. spnh.sendPacket(new SPlayerAbilitiesPacket(p.abilities));
  93. spnh.sendPacket(new SHeldItemChangePacket(p.inventory.currentItem));
  94. spnh.sendPacket(new SUpdateRecipesPacket(server.getRecipeManager().getRecipes()));
  95. spnh.sendPacket(new STagsListPacket(server.getNetworkTagManager()));
  96. this.updatePermissionLevel(p);
  97. p.getStats().markAllDirty();
  98. p.getRecipeBook().init(p);
  99. this.sendScoreboard(sw.getScoreboard(), p);
  100. this.server.refreshStatusNextTick();
  101. spnh.setPlayerLocation(p.getPosX(), p.getPosY(), p.getPosZ(), p.rotationYaw, p.rotationPitch);
  102. this.addPlayer(p);
  103. this.uuidToPlayerMap.put(p.getUniqueID(), p);
  104. this.sendPacketToAllPlayers(new SPlayerListItemPacket(SPlayerListItemPacket.Action.ADD_PLAYER, p));
  105. for(int i = 0; i < this.players.size(); i++)
  106. {
  107. p.connection.sendPacket(new SPlayerListItemPacket(SPlayerListItemPacket.Action.ADD_PLAYER, players.get(i)));
  108. }
  109. sw.addNewPlayer(p);
  110. server.getCustomBossEvents().onPlayerLogin(p);
  111. sendWorldInfo(p, sw);
  112. if(!this.server.getResourcePackUrl().isEmpty())
  113. {
  114. p.loadResourcePack(server.getResourcePackUrl(), server.getResourcePackHash());
  115. }
  116. for(EffectInstance effectinstance : p.getActivePotionEffects())
  117. {
  118. spnh.sendPacket(new SPlayEntityEffectPacket(p.getEntityId(), effectinstance));
  119. }
  120. if(compoundnbt != null && compoundnbt.contains("RootVehicle", 10))
  121. {
  122. CompoundNBT compoundnbt1 = compoundnbt.getCompound("RootVehicle");
  123. final ServerWorld worldf = sw;
  124. Entity entity1 = EntityType.func_220335_a(compoundnbt1.getCompound("Entity"), sw, (p_217885_1_) ->
  125. {
  126. return !worldf.summonEntity(p_217885_1_) ? null : p_217885_1_;
  127. });
  128. if(entity1 != null)
  129. {
  130. UUID uuid = compoundnbt1.getUniqueId("Attach");
  131. if(entity1.getUniqueID().equals(uuid))
  132. {
  133. p.startRiding(entity1, true);
  134. }
  135. else
  136. {
  137. for(Entity entity : entity1.getRecursivePassengers())
  138. {
  139. if(entity.getUniqueID().equals(uuid))
  140. {
  141. p.startRiding(entity, true);
  142. break;
  143. }
  144. }
  145. }
  146. if(!p.isPassenger())
  147. {
  148. LogManager.getLogger().warn("Couldn't reattach entity to player");
  149. p.removeEntity(entity1);
  150. for(Entity entity2 : entity1.getRecursivePassengers())
  151. {
  152. sw.removeEntity(entity2);
  153. }
  154. }
  155. }
  156. }
  157. p.addSelfToInternalCraftingInventory();
  158. net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerLoggedIn(p);
  159. }
  160. @Override
  161. public ServerPlayerEntity createPlayerForUser(GameProfile profile)
  162. {
  163. UUID uuid = PlayerEntity.getUUID(profile);
  164. List<ServerPlayerEntity> list = Lists.newArrayList();
  165. for(int i = 0; i < this.players.size(); i++)
  166. {
  167. ServerPlayerEntity p = this.players.get(i);
  168. if(p.getUniqueID().equals(uuid))
  169. {
  170. list.add(p);
  171. }
  172. }
  173. ServerPlayerEntity p2 = this.uuidToPlayerMap.get(profile.getId());
  174. if(p2 != null && !list.contains(p2))
  175. {
  176. list.add(p2);
  177. }
  178. for(ServerPlayerEntity p : list)
  179. {
  180. p.connection.disconnect(new TranslationTextComponent("multiplayer.disconnect.duplicate_login"));
  181. }
  182. PlayerInteractionManager playerinteractionmanager;
  183. if(server.isDemo())
  184. {
  185. playerinteractionmanager = new DemoPlayerInteractionManager(server.getWorld(DimensionType.OVERWORLD));
  186. }
  187. else
  188. {
  189. playerinteractionmanager = new PlayerInteractionManager(server.getWorld(DimensionType.OVERWORLD));
  190. }
  191. return new ModEntityPlayerMP(this.server, this.server.getWorld(DimensionType.OVERWORLD), profile, playerinteractionmanager);
  192. }
  193. @Override
  194. public ServerPlayerEntity recreatePlayerEntity(ServerPlayerEntity pIn, DimensionType dim, boolean conqueredEnd)
  195. {
  196. Server.scriptEvents.onPlayerPreRespawn(pIn);
  197. ServerWorld world = server.getWorld(dim);
  198. if(world == null)
  199. {
  200. dim = pIn.getSpawnDimension();
  201. }
  202. else if(!world.getDimension().canRespawnHere())
  203. {
  204. dim = world.getDimension().getRespawnDimension(pIn);
  205. }
  206. if(server.getWorld(dim) == null)
  207. {
  208. dim = DimensionType.OVERWORLD;
  209. }
  210. this.removePlayer(pIn);
  211. pIn.getServerWorld().removePlayer(pIn, true); // Forge: keep data until copyFrom called
  212. BlockPos blockpos = pIn.getBedLocation(dim);
  213. boolean flag = pIn.isSpawnForced(dim);
  214. pIn.dimension = dim;
  215. PlayerInteractionManager playerinteractionmanager;
  216. if(this.server.isDemo())
  217. {
  218. playerinteractionmanager = new DemoPlayerInteractionManager(this.server.getWorld(pIn.dimension));
  219. }
  220. else
  221. {
  222. playerinteractionmanager = new PlayerInteractionManager(this.server.getWorld(pIn.dimension));
  223. }
  224. ServerPlayerEntity p = new ModEntityPlayerMP(this.server, this.server.getWorld(pIn.dimension), pIn.getGameProfile(), playerinteractionmanager, (ModEntityPlayerMP) pIn);
  225. p.connection = pIn.connection;
  226. p.copyFrom(pIn, conqueredEnd);
  227. pIn.remove(false); // Forge: clone event had a chance to see old data, now discard it
  228. p.dimension = dim;
  229. p.setEntityId(pIn.getEntityId());
  230. p.setPrimaryHand(pIn.getPrimaryHand());
  231. for(String s : pIn.getTags())
  232. {
  233. p.addTag(s);
  234. }
  235. ServerWorld sw = this.server.getWorld(pIn.dimension);
  236. setPlayerGameTypeBasedOnOther(p, pIn, sw);
  237. if(blockpos != null)
  238. {
  239. Optional<Vec3d> optional = PlayerEntity.func_213822_a(server.getWorld(pIn.dimension), blockpos, flag);
  240. if(optional.isPresent())
  241. {
  242. Vec3d vec3d = optional.get();
  243. p.setLocationAndAngles(vec3d.x, vec3d.y, vec3d.z, 0.0f, 0.0f);
  244. p.setSpawnPoint(blockpos, flag, false, dim);
  245. }
  246. else
  247. {
  248. p.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f));
  249. }
  250. }
  251. while(!sw.func_226669_j_(p) && p.getPosY() < 256.0D)
  252. {
  253. p.setPosition(p.getPosX(), p.getPosY() + 1.0, p.getPosZ());
  254. }
  255. WorldInfo wi = p.world.getWorldInfo();
  256. net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(p.connection.netManager, p);
  257. p.connection.sendPacket(new SRespawnPacket(p.dimension, WorldInfo.byHashing(wi.getSeed()), wi.getGenerator(), p.interactionManager.getGameType()));
  258. BlockPos pos = sw.getSpawnPoint();
  259. p.connection.setPlayerLocation(p.getPosX(), p.getPosY(), p.getPosZ(), p.rotationYaw, p.rotationPitch);
  260. p.connection.sendPacket(new SSpawnPositionPacket(pos));
  261. p.connection.sendPacket(new SServerDifficultyPacket(wi.getDifficulty(), wi.isDifficultyLocked()));
  262. p.connection.sendPacket(new SSetExperiencePacket(p.experience, p.experienceTotal, p.experienceLevel));
  263. sendWorldInfo(p, sw);
  264. updatePermissionLevel(p);
  265. sw.addRespawnedPlayer(p);
  266. this.addPlayer(p);
  267. this.uuidToPlayerMap.put(p.getUniqueID(), p);
  268. p.addSelfToInternalCraftingInventory();
  269. p.setHealth(p.getHealth());
  270. net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(p, conqueredEnd);
  271. return p;
  272. }
  273. private void setPlayerGameTypeBasedOnOther(ServerPlayerEntity target, ServerPlayerEntity source, IWorld w)
  274. {
  275. ReflectionUtils.setPlayerGameTypeBasedOnOther(this, target, source, w);
  276. }
  277. @Override
  278. public void sendMessage(ITextComponent component)
  279. {
  280. // filter multiplayer leave text
  281. if(component instanceof TranslationTextComponent && ((TranslationTextComponent) component).getKey().equals("multiplayer.player.left"))
  282. {
  283. return;
  284. }
  285. super.sendMessage(component);
  286. }
  287. }