PlayerCommands.java 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package me.km.snuviscript.commands;
  2. import com.mojang.authlib.GameProfile;
  3. import java.util.ArrayList;
  4. import me.hammerle.snuviscript.code.ScriptManager;
  5. import me.hammerle.snuviscript.code.SnuviUtils;
  6. import me.km.inventory.InventoryUtils;
  7. import me.km.overrides.ModEntityPlayerMP;
  8. import me.km.permissions.Permissions;
  9. import me.km.playerbank.IPlayerBank;
  10. import me.km.scheduler.SnuviScheduler;
  11. import me.km.snuviscript.Scripts;
  12. import static me.km.snuviscript.commands.CommandUtils.*;
  13. import me.km.utils.Location;
  14. import me.km.utils.ReflectionUtils;
  15. import me.km.utils.Utils;
  16. import net.minecraft.entity.Entity;
  17. import net.minecraft.entity.player.PlayerEntity;
  18. import net.minecraft.entity.player.ServerPlayerEntity;
  19. import net.minecraft.inventory.EnderChestInventory;
  20. import net.minecraft.inventory.container.ChestContainer;
  21. import net.minecraft.inventory.container.SimpleNamedContainerProvider;
  22. import net.minecraft.item.ItemStack;
  23. import net.minecraft.item.Items;
  24. import net.minecraft.nbt.CompoundNBT;
  25. import net.minecraft.nbt.NBTUtil;
  26. import net.minecraft.network.ThreadQuickExitException;
  27. import net.minecraft.network.play.client.CChatMessagePacket;
  28. import net.minecraft.network.play.client.CClientStatusPacket;
  29. import net.minecraft.network.play.server.SPlayerListItemPacket;
  30. import net.minecraft.network.play.server.SSpawnPositionPacket;
  31. import net.minecraft.server.MinecraftServer;
  32. import net.minecraft.tileentity.SkullTileEntity;
  33. import net.minecraft.util.DamageSource;
  34. import net.minecraft.util.math.BlockRayTraceResult;
  35. import net.minecraft.util.math.RayTraceContext;
  36. import net.minecraft.util.math.RayTraceResult;
  37. import net.minecraft.util.math.Vec3d;
  38. import net.minecraft.util.text.StringTextComponent;
  39. import net.minecraft.world.GameType;
  40. import net.minecraft.world.World;
  41. import net.minecraft.world.server.ServerWorld;
  42. public class PlayerCommands {
  43. public static void registerFunctions(ScriptManager sm, Scripts scripts,
  44. Permissions perms, SnuviScheduler scheduler, MinecraftServer server,
  45. IPlayerBank playerBank) {
  46. sm.registerFunction("player.getitemamount", (sc, in) -> (double) InventoryUtils.searchInventoryFor(((PlayerEntity) in[0].get(sc)).inventory, (ItemStack) in[2].get(sc), in[1].getBoolean(sc)));
  47. sm.registerFunction("player.removeitem", (sc, in) -> {
  48. ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
  49. stack.setCount(InventoryUtils.removeFromInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
  50. return stack;
  51. });
  52. sm.registerFunction("player.giveitem", (sc, in) -> {
  53. ItemStack stack = ((ItemStack) in[1].get(sc)).copy();
  54. stack.setCount(InventoryUtils.addToInventory(((PlayerEntity) in[0].get(sc)).inventory, stack));
  55. return stack;
  56. });
  57. sm.registerConsumer("player.respawn", (sc, in) -> {
  58. final ServerPlayerEntity p = ((ServerPlayerEntity) in[0].get(sc));
  59. scheduler.scheduleTask(() -> {
  60. try {
  61. p.connection.processClientStatus(new CClientStatusPacket(CClientStatusPacket.State.PERFORM_RESPAWN));
  62. } catch(ThreadQuickExitException ex) {
  63. // Minecraft needs this for canceling and queueing into main thread
  64. }
  65. });
  66. });
  67. sm.registerConsumer("player.clearinventory", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory.clear());
  68. sm.registerFunction("player.inventorytolist", (sc, in) -> ((PlayerEntity) in[1].get(sc)).inventory.mainInventory);
  69. sm.registerFunction("player.getnearest", (sc, in) -> {
  70. Location l = (Location) in[0].get(sc);
  71. return l.getWorld().getClosestPlayer(l.getX(), l.getY(), l.getZ(), -1, p -> true);
  72. });
  73. sm.registerConsumer("player.say", (sc, in) -> {
  74. try {
  75. ((ServerPlayerEntity) in[0].get(sc)).connection.processChatMessage(new CChatMessagePacket(SnuviUtils.connect(sc, in, 1)));
  76. } catch(ThreadQuickExitException ex) {
  77. // Minecraft needs this for canceling and queueing into main thread
  78. }
  79. });
  80. sm.registerConsumer("player.speak", (sc, in) -> {
  81. sendMessageToGroup(server, scripts, perms, in[0].get(sc), sc, concat(sc, 2, "[" + in[1].getString(sc) + "§r] ", in));
  82. });
  83. sm.registerConsumer("player.setcompass", (sc, in) -> {
  84. ((ServerPlayerEntity) in[0].get(sc)).connection.sendPacket(new SSpawnPositionPacket(((Location) in[1].get(sc)).getBlockPos()));
  85. });
  86. sm.registerFunction("player.gethunger", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getFoodLevel());
  87. sm.registerConsumer("player.sethunger", (sc, in) -> {
  88. ((PlayerEntity) in[0].get(sc)).getFoodStats().setFoodLevel(in[1].getInt(sc));
  89. });
  90. sm.registerFunction("player.getsaturation", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).getFoodStats().getSaturationLevel());
  91. sm.registerConsumer("player.setsaturation", (sc, in) -> {
  92. ReflectionUtils.setSaturation(((PlayerEntity) in[0].get(sc)).getFoodStats(), in[1].getFloat(sc));
  93. });
  94. sm.registerFunction("player.getname", (sc, in) -> {
  95. Object o = in[0].get(sc);
  96. if(o instanceof PlayerEntity) {
  97. return ((PlayerEntity) o).getName().getFormattedText();
  98. }
  99. return server.getPlayerProfileCache().getProfileByUUID(getUUID(o.toString())).getName();
  100. });
  101. sm.registerFunction("player.getuuid", (sc, in) -> {
  102. Object o = in[0].get(sc);
  103. if(o instanceof PlayerEntity) {
  104. return ((PlayerEntity) o).getUniqueID();
  105. }
  106. return playerBank.getUUID(o.toString());
  107. });
  108. sm.registerFunction("player.getid", (sc, in) -> (double) getId(playerBank, in[0].get(sc)));
  109. sm.registerFunction("player.get", (sc, in) -> server.getPlayerList().getPlayerByUUID(getUUID(in[0].get(sc))));
  110. sm.registerFunction("player.getuuidfromid", (sc, in) -> playerBank.getUUIDfromID(in[0].getInt(sc)));
  111. sm.registerFunction("player.getnamefromid", (sc, in) -> playerBank.getNamefromID(in[0].getInt(sc)));
  112. sm.registerFunction("player.getip", (sc, in) -> ((ServerPlayerEntity) in[0].get(sc)).connection.netManager.getRemoteAddress().toString());
  113. sm.registerFunction("player.iscreative", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isCreative());
  114. sm.registerFunction("player.isspectator", (sc, in) -> ((PlayerEntity) in[0].get(sc)).isSpectator());
  115. sm.registerFunction("player.issurvival", (sc, in) -> {
  116. PlayerEntity p = (PlayerEntity) in[0].get(sc);
  117. return !p.isCreative() && !p.isSpectator();
  118. });
  119. sm.registerFunction("player.isadventure", (sc, in) -> !((PlayerEntity) in[0].get(sc)).abilities.allowEdit);
  120. sm.registerConsumer("player.setfly", (sc, in) -> {
  121. PlayerEntity p = ((PlayerEntity) in[0].get(sc));
  122. boolean b = in[1].getBoolean(sc);
  123. p.abilities.allowFlying = b;
  124. p.abilities.isFlying = b;
  125. p.sendPlayerAbilities();
  126. });
  127. sm.registerFunction("player.hasfly", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.allowFlying);
  128. sm.registerFunction("player.isflying", (sc, in) -> ((PlayerEntity) in[0].get(sc)).abilities.isFlying);
  129. sm.registerConsumer("player.setgamemode", (sc, in) -> {
  130. PlayerEntity p = (PlayerEntity) in[0].get(sc);
  131. switch(in[1].get(sc).toString()) {
  132. case "survival":
  133. case "s":
  134. case "0":
  135. p.setGameType(GameType.SURVIVAL);
  136. break;
  137. case "creative":
  138. case "c":
  139. case "1":
  140. p.setGameType(GameType.CREATIVE);
  141. break;
  142. case "adventure":
  143. case "a":
  144. case "2":
  145. p.setGameType(GameType.ADVENTURE);
  146. break;
  147. case "spectator":
  148. case "w":
  149. case "3":
  150. p.setGameType(GameType.SPECTATOR);
  151. break;
  152. default:
  153. p.setGameType(GameType.CREATIVE);
  154. break;
  155. }
  156. });
  157. sm.registerFunction("player.getlastdamager", (sc, in) -> {
  158. DamageSource ds = ((PlayerEntity) in[0].get(sc)).getLastDamageSource();
  159. if(ds == null) {
  160. return null;
  161. }
  162. return ds.getImmediateSource();
  163. });
  164. sm.registerConsumer("player.dropinventory", (sc, in) -> {
  165. ((PlayerEntity) in[0].get(sc)).inventory.dropAllItems();
  166. });
  167. sm.registerFunction("player.gettarget", (sc, in) -> {
  168. PlayerEntity p = (PlayerEntity) in[0].get(sc);
  169. double radius = in[1].getDouble(sc);
  170. if(radius > 128.0) {
  171. radius = 128.0;
  172. }
  173. RayTraceContext.BlockMode bm = RayTraceContext.BlockMode.OUTLINE;
  174. if(in.length >= 3 && in[2].getBoolean(sc)) {
  175. bm = RayTraceContext.BlockMode.COLLIDER;
  176. }
  177. RayTraceContext.FluidMode fm = RayTraceContext.FluidMode.NONE;
  178. if(in.length >= 4 && in[3].getBoolean(sc)) {
  179. fm = RayTraceContext.FluidMode.ANY;
  180. }
  181. Vec3d start = p.getEyePosition(0.0f);
  182. Vec3d unit = p.getLook(0.0f);
  183. Vec3d end = start.add(unit.x * radius, unit.y * radius, unit.z * radius);
  184. BlockRayTraceResult result = p.world.rayTraceBlocks(new RayTraceContext(start, end, bm, fm, p));
  185. if(result.getType() == RayTraceResult.Type.BLOCK) {
  186. return new Location(p.world, result.getPos());
  187. }
  188. return new Location(p.world, end);
  189. });
  190. sm.registerFunction("player.gettargetentity", (sc, in) -> {
  191. return Utils.getTargetedEntity((PlayerEntity) in[0].get(sc), in[1].getDouble(sc), getNamedClass(in[2].getString(sc)));
  192. });
  193. sm.registerAlias("player.hasscript", "player.hasquest");
  194. sm.registerConsumer("player.action", (sc, in) -> {
  195. StringTextComponent text = new StringTextComponent(SnuviUtils.connect(sc, in, 1));
  196. doForGroup(server, scripts, perms, in[0].get(sc), sc, p -> ((ServerPlayerEntity) p).sendStatusMessage(text, true));
  197. });
  198. sm.registerConsumer("player.disconnect", (sc, in) -> {
  199. ((ServerPlayerEntity) in[0].get(sc)).connection.disconnect(new StringTextComponent(in[1].getString(sc)));
  200. });
  201. sm.registerFunction("player.getspawn", (sc, in) -> {
  202. ServerWorld ws = (ServerWorld) in[1].get(sc);
  203. return new Location(ws, ((PlayerEntity) in[0].get(sc)).getBedLocation(ws.getDimension().getType()));
  204. });
  205. sm.registerAlias("player.getspawn", "player.getbedspawn");
  206. sm.registerConsumer("player.setspawn", (sc, in) -> {
  207. Location l = (Location) in[1].get(sc);
  208. ((ServerPlayerEntity) in[0].get(sc)).setSpawnPoint(l.getBlockPos(), true, false, l.getWorld().getDimension().getType());
  209. });
  210. sm.registerAlias("player.setspawn", "player.setbedspawn");
  211. sm.registerConsumer("player.damageitem", (sc, in) -> {
  212. PlayerEntity p = (PlayerEntity) in[0].get(sc);
  213. p.getHeldItemMainhand().damageItem(in[1].getInt(sc), p, (c) -> {
  214. });
  215. });
  216. sm.registerConsumer("player.damagearmor", (sc, in) -> {
  217. ((PlayerEntity) in[0].get(sc)).inventory.damageArmor(in[1].getFloat(sc));
  218. });
  219. sm.registerConsumer("player.openenderchest", (sc, in) -> {
  220. PlayerEntity p1 = (PlayerEntity) in[0].get(sc);
  221. PlayerEntity p2 = (PlayerEntity) in[1].get(sc);
  222. EnderChestInventory inv = p2.getInventoryEnderChest();
  223. p1.openContainer(new SimpleNamedContainerProvider((id, pInv, p) -> {
  224. return ChestContainer.createGeneric9X3(id, pInv, inv);
  225. }, new StringTextComponent(in[2].getString(sc))));
  226. });
  227. sm.registerConsumer("player.addtotalexp", (sc, in) -> {
  228. ((ServerPlayerEntity) in[0].get(sc)).giveExperiencePoints(in[1].getInt(sc));
  229. });
  230. sm.registerFunction("player.getlevel", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experienceLevel);
  231. sm.registerConsumer("player.setlevel", (sc, in) -> {
  232. ((ServerPlayerEntity) in[0].get(sc)).setExperienceLevel(in[1].getInt(sc));
  233. });
  234. sm.registerFunction("player.getexp", (sc, in) -> (double) ((PlayerEntity) in[0].get(sc)).experience);
  235. sm.registerConsumer("player.setexp", (sc, in) -> {
  236. ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
  237. p.func_195394_a((int) (in[1].getDouble(sc) * p.xpBarCap()));
  238. });
  239. sm.registerFunction("player.gethead", (sc, in) -> {
  240. ItemStack stack = new ItemStack(Items.PLAYER_HEAD);
  241. CompoundNBT com = stack.getOrCreateTag();
  242. GameProfile gp = new GameProfile(getUUID(in[0].get(sc)), in[1].getString(sc));
  243. gp = SkullTileEntity.updateGameProfile(gp);
  244. com.put("SkullOwner", NBTUtil.writeGameProfile(new CompoundNBT(), gp));
  245. return stack;
  246. });
  247. sm.registerFunction("player.setspeed", (sc, in) -> {
  248. PlayerEntity p = (PlayerEntity) in[0].get(sc);
  249. float f = in[1].getFloat(sc);
  250. ReflectionUtils.setFlySpeed(p.abilities, f);
  251. ReflectionUtils.setWalkSpeed(p.abilities, f * 2);
  252. p.sendPlayerAbilities();
  253. return true;
  254. });
  255. sm.registerFunction("player.near", (sc, in) -> Utils.getPlayers((Entity) in[0].get(sc), in[1].getDouble(sc)));
  256. sm.registerFunction("player.getinv", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory);
  257. sm.registerFunction("player.getinvslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.get(in[1].getInt(sc)));
  258. sm.registerConsumer("player.setinvslot", (sc, in) -> {
  259. ((PlayerEntity) in[0].get(sc)).inventory.mainInventory.set(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
  260. });
  261. sm.registerFunction("player.getenderinv", (sc, in) -> ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest());
  262. sm.registerFunction("player.getenderslot", (sc, in) -> ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().getStackInSlot(in[1].getInt(sc)));
  263. sm.registerConsumer("player.setenderslot", (sc, in) -> {
  264. ((PlayerEntity) in[0].get(sc)).getInventoryEnderChest().setInventorySlotContents(in[1].getInt(sc), ((ItemStack) in[2].get(sc)).copy());
  265. });
  266. sm.registerConsumer("player.setdisplayname", (sc, in) -> {
  267. ((ModEntityPlayerMP) in[0].get(sc)).setTabListDisplayName(in[1].getString(sc), scheduler);
  268. });
  269. sm.registerConsumer("player.hide", (sc, in) -> {
  270. ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
  271. GameType type = p.interactionManager.getGameType();
  272. ReflectionUtils.setGameType(p.interactionManager, GameType.SPECTATOR);
  273. SPlayerListItemPacket packet = new SPlayerListItemPacket(SPlayerListItemPacket.Action.UPDATE_GAME_MODE, p);
  274. ReflectionUtils.setGameType(p.interactionManager, type);
  275. for(ServerPlayerEntity other : server.getPlayerList().getPlayers()) {
  276. if(other == p) {
  277. continue;
  278. }
  279. other.connection.sendPacket(packet);
  280. }
  281. p.setInvisible(true);
  282. });
  283. sm.registerConsumer("player.show", (sc, in) -> {
  284. ServerPlayerEntity p = (ServerPlayerEntity) in[0].get(sc);
  285. p.setInvisible(false);
  286. SPlayerListItemPacket packet = new SPlayerListItemPacket(SPlayerListItemPacket.Action.UPDATE_GAME_MODE, p);
  287. for(ServerPlayerEntity other : server.getPlayerList().getPlayers()) {
  288. if(other == p) {
  289. continue;
  290. }
  291. other.connection.sendPacket(packet);
  292. }
  293. });
  294. sm.registerFunction("players.getamount", (sc, in) -> (double) server.getCurrentPlayerCount());
  295. sm.registerFunction("players.tolist", (sc, in) -> new ArrayList(server.getPlayerList().getPlayers()));
  296. sm.registerFunction("players.toworldlist", (sc, in) -> new ArrayList(((World) in[0].get(sc)).getPlayers()));
  297. sm.registerFunction("players.near", (sc, in) -> {
  298. Location l = (Location) in[0].get(sc);
  299. return Utils.getPlayers(l.getWorld(), l.getX(), l.getY(), l.getZ(), in[1].getDouble(sc));
  300. });
  301. }
  302. }