PlayerCommands.java 16 KB

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