ScriptEvents.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852
  1. package me.km.snuviscript;
  2. import java.util.*;
  3. import java.util.function.Consumer;
  4. import java.util.stream.Collectors;
  5. import me.hammerle.snuviscript.code.*;
  6. import me.hammerle.snuviscript.inputprovider.Variable;
  7. import me.kcm.BlockHarvest;
  8. import me.kcm.Craft;
  9. import me.kcm.ContainerClick;
  10. import me.km.utils.Utils;
  11. import me.km.Server;
  12. import me.km.entities.*;
  13. import me.km.events.CommandEvent;
  14. import me.km.inventory.ModInventory;
  15. import me.km.utils.*;
  16. import net.minecraft.block.*;
  17. import net.minecraft.command.ICommandSource;
  18. import net.minecraft.entity.*;
  19. import net.minecraft.entity.player.*;
  20. import net.minecraft.inventory.*;
  21. import net.minecraft.inventory.container.ClickType;
  22. import net.minecraft.inventory.container.Container;
  23. import net.minecraft.item.ItemStack;
  24. import net.minecraft.item.crafting.ICraftingRecipe;
  25. import net.minecraft.item.crafting.IRecipeType;
  26. import net.minecraft.loot.LootContext;
  27. import net.minecraft.loot.LootParameters;
  28. import net.minecraft.network.play.server.SSetSlotPacket;
  29. import net.minecraft.server.MinecraftServer;
  30. import net.minecraft.server.management.PlayerList;
  31. import net.minecraft.tileentity.TileEntity;
  32. import net.minecraft.util.math.*;
  33. import net.minecraft.util.math.vector.Vector3d;
  34. import net.minecraft.util.text.*;
  35. import net.minecraft.world.*;
  36. import net.minecraft.world.server.ServerWorld;
  37. import net.minecraftforge.event.*;
  38. import net.minecraftforge.event.entity.*;
  39. import net.minecraftforge.event.entity.item.ItemTossEvent;
  40. import net.minecraftforge.event.entity.living.*;
  41. import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
  42. import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
  43. import net.minecraftforge.event.entity.player.*;
  44. import net.minecraftforge.event.world.*;
  45. import net.minecraftforge.eventbus.api.*;
  46. import net.minecraftforge.event.entity.player.PlayerEvent;
  47. import net.minecraftforge.eventbus.api.Event.Result;
  48. public class ScriptEvents implements BlockHarvest, Craft, ContainerClick {
  49. private static class WrappedBool {
  50. public boolean wrapped;
  51. }
  52. private static void setLiving(Script sc, LivingEntity ent) {
  53. sc.setVar("living_entity", ent);
  54. }
  55. private static void setItem(Script sc, ItemStack stack) {
  56. sc.setVar("item", stack);
  57. }
  58. private static void setPlayer(Script sc, PlayerEntity p) {
  59. sc.setVar("player", p);
  60. }
  61. @SuppressWarnings("")
  62. private static void setBlock(Script sc, World w, BlockPos pos, BlockState state) {
  63. sc.setVar("block_loc", new Location(w, pos));
  64. sc.setVar("block_type", state.getBlock().getRegistryName().toString());
  65. sc.setVar("block", state.getBlock());
  66. }
  67. @SuppressWarnings("")
  68. private static void setBlock(Script sc, World w, BlockPos pos) {
  69. BlockState state = w.getBlockState(pos);
  70. sc.setVar("block_loc", new Location(w, pos));
  71. sc.setVar("block_type", state.getBlock().getRegistryName().toString());
  72. sc.setVar("block", state.getBlock());
  73. }
  74. private static void setEntity(Script sc, Entity ent) {
  75. sc.setVar("entity", ent);
  76. }
  77. private final Scripts scripts;
  78. private final MinecraftServer server;
  79. public ScriptEvents(Scripts scripts, MinecraftServer server) {
  80. this.scripts = scripts;
  81. this.server = server;
  82. }
  83. private static void nothing(Script sc) {}
  84. private void handleEvent(Event e, String event, Consumer<Script> before,
  85. Consumer<Script> after) {
  86. if(e.isCancelable()) {
  87. scripts.getScriptManager().callEvent(event, sc -> {
  88. before.accept(sc);
  89. sc.setVar("cancel", e.isCanceled());
  90. }, sc -> {
  91. after.accept(sc);
  92. handleVar(sc, event, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  93. });
  94. } else {
  95. scripts.getScriptManager().callEvent(event, before, after);
  96. }
  97. }
  98. private void handleEvent(Event e, String event, Consumer<Script> before) {
  99. handleEvent(e, event, before, ScriptEvents::nothing);
  100. }
  101. private void handleEvent(String event, Consumer<Script> before, Consumer<Script> after) {
  102. scripts.getScriptManager().callEvent(event, before, after);
  103. }
  104. private void handleEvent(String event, Consumer<Script> before) {
  105. handleEvent(event, before, ScriptEvents::nothing);
  106. }
  107. private void handleVar(Script sc, String event, String name, Consumer<Variable> c) {
  108. try {
  109. ifVarNotNull(sc, name, c);
  110. } catch(Exception ex) {
  111. scripts.getLogger().print(String.format("invalid var in '%s' event", event), ex, null,
  112. sc.getName(), sc, sc.getStackTrace());
  113. }
  114. }
  115. private void ifVarNotNull(Script sc, String name, Consumer<Variable> c) {
  116. Variable v = sc.getVar(name);
  117. if(v != null) {
  118. c.accept(v);
  119. }
  120. }
  121. private void simpleCancel(Script sc, Event e, String name) {
  122. try {
  123. ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  124. } catch(Exception ex) {
  125. scripts.getLogger().print(String.format("invalid var in '%s' event", name), ex, null,
  126. sc.getName(), sc, sc.getStackTrace());
  127. }
  128. }
  129. public void onPlayerDataTick(PlayerEntity p, String var) {
  130. handleEvent("player_data_tick", sc -> {
  131. setPlayer(sc, p);
  132. sc.setVar("var", var);
  133. });
  134. }
  135. public void onPlayerStartElytra(PlayerEntity p) {
  136. handleEvent("player_elytra_start", sc -> {
  137. setPlayer(sc, p);
  138. });
  139. }
  140. public void onPlayerStopElytra(PlayerEntity p) {
  141. handleEvent("player_elytra_stop", sc -> {
  142. setPlayer(sc, p);
  143. });
  144. }
  145. public void onPlayerMove(PlayerEntity p, int id) {
  146. handleEvent("player_move", sc -> {
  147. setPlayer(sc, p);
  148. sc.setVar("id", (double) id);
  149. });
  150. }
  151. public boolean onInventoryClick(Script script, ITextComponent text, ModInventory inv, int slot,
  152. ClickType click, PlayerEntity p) {
  153. scripts.getScriptManager().callEvent("inv_click", script, sc -> {
  154. setPlayer(sc, p);
  155. sc.setVar("inv", inv);
  156. sc.setVar("inv_id", (double) inv.getModId());
  157. sc.setVar("inv_name", text.getString());
  158. sc.setVar("inv_slot", (double) slot);
  159. sc.setVar("click_type", click.toString());
  160. setItem(sc, inv.getStackInSlot(slot));
  161. sc.setVar("cancel", false);
  162. }, ScriptEvents::nothing);
  163. Variable v = script.getVar("cancel");
  164. return v != null && v.getBoolean(script);
  165. }
  166. public void onInventoryClose(Script script, ITextComponent text, ModInventory inv,
  167. PlayerEntity p) {
  168. scripts.getScriptManager().callEvent("inv_close", script, sc -> {
  169. setPlayer(sc, p);
  170. sc.setVar("inv", inv);
  171. sc.setVar("inv_id", (double) inv.getModId());
  172. sc.setVar("inv_name", text.getString());
  173. }, ScriptEvents::nothing);
  174. }
  175. public void onHumanHurt(Entity attacker, EntityHuman h) {
  176. handleEvent("human_hurt", sc -> {
  177. setEntity(sc, attacker);
  178. sc.setVar("human", h);
  179. });
  180. }
  181. @SubscribeEvent(receiveCanceled = true)
  182. public void onPlayerPostRespawn(PlayerEvent.PlayerRespawnEvent e) {
  183. handleEvent("player_post_respawn", sc -> setPlayer(sc, e.getPlayer()));
  184. }
  185. public void onPlayerPreRespawn(PlayerEntity p) {
  186. handleEvent("player_pre_respawn", sc -> setPlayer(sc, p));
  187. }
  188. @SubscribeEvent(receiveCanceled = true)
  189. public void onLivingDamage(LivingDamageEvent e) {
  190. handleEvent(e, "living_damage", (sc) -> {
  191. setLiving(sc, e.getEntityLiving());
  192. sc.setVar("damage_source", e.getSource());
  193. sc.setVar("damage_amount", (double) e.getAmount());
  194. }, (sc) -> {
  195. handleVar(sc, "living_damage", "damage_amount", v -> e.setAmount(v.getFloat(sc)));
  196. });
  197. }
  198. @SubscribeEvent(receiveCanceled = true)
  199. public void onLivingHurt(LivingHurtEvent e) {
  200. handleEvent(e, "living_hurt", (sc) -> {
  201. setLiving(sc, e.getEntityLiving());
  202. sc.setVar("damage_source", e.getSource());
  203. sc.setVar("damage_amount", (double) e.getAmount());
  204. }, (sc) -> {
  205. handleVar(sc, "living_hurt", "damage_amount", v -> e.setAmount(v.getFloat(sc)));
  206. });
  207. }
  208. @SubscribeEvent(receiveCanceled = true)
  209. public void onLivingAttacked(LivingAttackEvent e) {
  210. handleEvent(e, "living_pre_hurt", (sc) -> {
  211. setLiving(sc, e.getEntityLiving());
  212. sc.setVar("damage_source", e.getSource());
  213. sc.setVar("damage_amount", (double) e.getAmount());
  214. });
  215. }
  216. @SubscribeEvent(receiveCanceled = true)
  217. public void onLivingHeal(LivingHealEvent e) {
  218. handleEvent(e, "living_heal", (sc) -> {
  219. setLiving(sc, e.getEntityLiving());
  220. sc.setVar("heal_amount", (double) e.getAmount());
  221. }, (sc) -> {
  222. handleVar(sc, "living_heal", "heal_amount", v -> e.setAmount(v.getFloat(sc)));
  223. });
  224. }
  225. @SubscribeEvent(receiveCanceled = true)
  226. public void onLivingDeath(LivingDeathEvent e) {
  227. handleEvent(e, "living_death", (sc) -> {
  228. setLiving(sc, e.getEntityLiving());
  229. sc.setVar("damage_source", e.getSource());
  230. });
  231. }
  232. @SubscribeEvent(receiveCanceled = true)
  233. public void onLivingDrop(LivingDropsEvent e) {
  234. handleEvent(e, "living_drop", (sc) -> {
  235. setLiving(sc, e.getEntityLiving());
  236. sc.setVar("drops", e.getDrops());
  237. sc.setVar("damage_source", e.getSource());
  238. sc.setVar("looting", (double) e.getLootingLevel());
  239. });
  240. }
  241. @SubscribeEvent(receiveCanceled = true)
  242. public void onLivingExperienceDrop(LivingExperienceDropEvent e) {
  243. handleEvent(e, "living_experience_drop", (sc) -> {
  244. setLiving(sc, e.getEntityLiving());
  245. sc.setVar("experience", (double) e.getDroppedExperience());
  246. }, (sc) -> {
  247. handleVar(sc, "living_experience_drop", "experience",
  248. v -> e.setDroppedExperience(v.getInt(sc)));
  249. });
  250. }
  251. @SubscribeEvent(receiveCanceled = true)
  252. public void onProjectileHit(ProjectileImpactEvent e) {
  253. final Entity hitEntity;
  254. final Location loc;
  255. RayTraceResult ray = e.getRayTraceResult();
  256. switch(ray.getType()) {
  257. case ENTITY:
  258. hitEntity = ((EntityRayTraceResult) e.getRayTraceResult()).getEntity();
  259. loc = null;
  260. break;
  261. case BLOCK:
  262. loc = new Location(e.getEntity().world,
  263. ((BlockRayTraceResult) e.getRayTraceResult()).getPos());
  264. hitEntity = null;
  265. break;
  266. default:
  267. return;
  268. }
  269. handleEvent(e, "projectile_hit", (sc) -> {
  270. sc.setVar("projectile", e.getEntity());
  271. sc.setVar("entity_hit", hitEntity);
  272. sc.setVar("loc_hit", loc);
  273. sc.setVar("shooter", Utils.getEntityFromProjectile(e.getEntity()));
  274. });
  275. }
  276. public void onEntityItemProjectileHit(EntityItemProjectile ent, LivingEntity liv,
  277. ItemStack stack, Entity hitEntity, BlockPos pos) {
  278. Location loc = (pos == null) ? null : new Location(ent.world, pos);
  279. handleEvent("item_hit", (sc) -> {
  280. sc.setVar("projectile", ent);
  281. setItem(sc, stack);
  282. sc.setVar("entity_hit", hitEntity);
  283. sc.setVar("loc_hit", loc);
  284. sc.setVar("shooter", liv);
  285. });
  286. }
  287. @Override
  288. public List<ItemStack> onBlockHarvest(BlockState state, ServerWorld w, BlockPos pos,
  289. TileEntity tileEnt, Entity ent, ItemStack stack) {
  290. LootContext.Builder loot = new LootContext.Builder(w).withRandom(w.getRandom())
  291. .withParameter(LootParameters.field_237457_g_, Vector3d.copyCentered(pos))
  292. .withParameter(LootParameters.TOOL, stack == null ? ItemStack.EMPTY : stack)
  293. .withNullableParameter(LootParameters.THIS_ENTITY, ent)
  294. .withNullableParameter(LootParameters.BLOCK_ENTITY, tileEnt);
  295. List<ItemStack> list = state.getDrops(loot);
  296. try {
  297. final Block b = state.getBlock();
  298. final String name = b.getRegistryName().toString();
  299. scripts.getScriptManager().callEvent("block_drop", sc -> {
  300. sc.setVar("drops", list);
  301. sc.setVar("block_type", name);
  302. sc.setVar("block", b);
  303. sc.setVar("location", new Location(w, pos));
  304. setEntity(sc, ent);
  305. setItem(sc, stack);
  306. }, ScriptEvents::nothing);
  307. } catch(Exception ex) {
  308. ex.printStackTrace();
  309. }
  310. return list;
  311. }
  312. @SubscribeEvent(receiveCanceled = true)
  313. public void onBlockBreak(BlockEvent.BreakEvent e) {
  314. handleEvent("block_break", (sc) -> {
  315. setPlayer(sc, e.getPlayer());
  316. setBlock(sc, (World) e.getWorld(), e.getPos(), e.getState());
  317. sc.setVar("cancel", e.isCanceled());
  318. }, (sc) -> {
  319. simpleCancel(sc, e, "block_break");
  320. });
  321. }
  322. @SubscribeEvent(receiveCanceled = true)
  323. public void onBlockPlace(BlockEvent.EntityPlaceEvent e) {
  324. if(!(e.getEntity() instanceof PlayerEntity)) {
  325. return;
  326. }
  327. PlayerEntity p = (PlayerEntity) e.getEntity();
  328. handleEvent("block_place", (sc) -> {
  329. setPlayer(sc, p);
  330. sc.setVar("block_type_after", e.getPlacedBlock().getBlock().getRegistryName());
  331. setBlock(sc, (World) e.getWorld(), e.getPos(), e.getState());
  332. sc.setVar("cancel", e.isCanceled());
  333. }, (sc) -> {
  334. simpleCancel(sc, e, "block_place");
  335. });
  336. }
  337. @SubscribeEvent(receiveCanceled = true)
  338. public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent e) {
  339. PlayerEntity p = e.getPlayer();
  340. if(p == null) {
  341. return;
  342. }
  343. PlayerList list = server.getPlayerList();
  344. boolean banned = list.getBannedPlayers().isBanned(p.getGameProfile());
  345. boolean whitelisted = list.getWhitelistedPlayers().isWhitelisted(p.getGameProfile());
  346. handleEvent("player_login", (sc) -> {
  347. setPlayer(sc, p);
  348. sc.setVar("is_banned", banned);
  349. sc.setVar("is_whitelisted", whitelisted);
  350. });
  351. }
  352. @SubscribeEvent(receiveCanceled = true)
  353. public void onPlayerLogout(PlayerEvent.PlayerLoggedOutEvent e) {
  354. PlayerEntity p = e.getPlayer();
  355. if(p == null || e.getPlayer().ticksExisted < 20) {
  356. return;
  357. }
  358. handleEvent("player_logout", sc -> setPlayer(sc, p));
  359. }
  360. @SubscribeEvent(receiveCanceled = true)
  361. public void onBucketFill(FillBucketEvent e) {
  362. handleEvent("bucket_use", (sc) -> {
  363. setPlayer(sc, e.getPlayer());
  364. RayTraceResult ray = e.getTarget();
  365. if(ray != null && ray instanceof BlockRayTraceResult
  366. && ray.getType() == RayTraceResult.Type.BLOCK) {
  367. sc.setVar("has_block", true);
  368. ScriptEvents.setBlock(sc, e.getWorld(), ((BlockRayTraceResult) ray).getPos());
  369. } else {
  370. sc.setVar("has_block", false);
  371. }
  372. sc.setVar("cancel", e.isCanceled());
  373. }, (sc) -> {
  374. simpleCancel(sc, e, "bucket_use");
  375. });
  376. }
  377. @SubscribeEvent(receiveCanceled = true)
  378. public void onRightClickBlock(PlayerInteractEvent.RightClickBlock e) {
  379. handleEvent("block_click", (sc) -> {
  380. setPlayer(sc, e.getPlayer());
  381. sc.setVar("action", "right");
  382. sc.setVar("hand", e.getHand().name());
  383. ScriptEvents.setBlock(sc, e.getWorld(), e.getPos());
  384. sc.setVar("cancel", e.isCanceled());
  385. }, (sc) -> {
  386. handleVar(sc, "block_click", "cancel", v -> {
  387. boolean b = v.getBoolean(sc);
  388. e.setCanceled(b);
  389. if(!b) {
  390. e.setUseBlock(Result.DEFAULT);
  391. e.setUseItem(Result.DEFAULT);
  392. }
  393. });
  394. });
  395. }
  396. @SubscribeEvent(receiveCanceled = true)
  397. public void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock e) {
  398. handleEvent("block_click", (sc) -> {
  399. setPlayer(sc, e.getPlayer());
  400. sc.setVar("action", "left");
  401. sc.setVar("hand", e.getHand().name());
  402. ScriptEvents.setBlock(sc, e.getWorld(), e.getPos());
  403. sc.setVar("cancel", e.isCanceled());
  404. }, (sc) -> {
  405. handleVar(sc, "block_click", "cancel", v -> {
  406. boolean b = v.getBoolean(sc);
  407. e.setCanceled(b);
  408. if(!b) {
  409. e.setUseBlock(Result.DEFAULT);
  410. e.setUseItem(Result.DEFAULT);
  411. }
  412. });
  413. });
  414. }
  415. @SubscribeEvent(receiveCanceled = true)
  416. public void onEntityClick(PlayerInteractEvent.EntityInteract e) {
  417. handleEvent("entity_click", (sc) -> {
  418. setPlayer(sc, e.getPlayer());
  419. sc.setVar("hand", e.getHand().name());
  420. setEntity(sc, e.getTarget());
  421. sc.setVar("cancel", e.isCanceled());
  422. }, (sc) -> {
  423. simpleCancel(sc, e, "entity_click");
  424. });
  425. }
  426. public void onEmptyLeftClick(PlayerEntity p) {
  427. handleEvent("left_click_air", sc -> setPlayer(sc, p));
  428. }
  429. @SubscribeEvent(receiveCanceled = true)
  430. public void onItemClick(PlayerInteractEvent.RightClickItem e) {
  431. handleEvent("item_air_click", (sc) -> {
  432. setPlayer(sc, e.getPlayer());
  433. setItem(sc, e.getItemStack());
  434. sc.setVar("hand", e.getHand().toString());
  435. sc.setVar("cancel", e.isCanceled());
  436. }, (sc) -> {
  437. simpleCancel(sc, e, "item_air_click");
  438. });
  439. }
  440. @SubscribeEvent(receiveCanceled = true)
  441. public void onItemUseStart(LivingEntityUseItemEvent.Start e) {
  442. handleEvent(e, "item_use_start", (sc) -> {
  443. setLiving(sc, e.getEntityLiving());
  444. sc.setVar("duration", (double) e.getDuration());
  445. setItem(sc, e.getItem());
  446. }, (sc) -> {
  447. handleVar(sc, "item_use_start", "duration", v -> e.setDuration(v.getInt(sc)));
  448. });
  449. }
  450. @SubscribeEvent(receiveCanceled = true)
  451. public void onConsuming(LivingEntityUseItemEvent.Finish e) {
  452. handleEvent(e, "item_use_finish", (sc) -> {
  453. setLiving(sc, e.getEntityLiving());
  454. setItem(sc, e.getItem());
  455. sc.setVar("result", e.getResultStack());
  456. }, (sc) -> {
  457. handleVar(sc, "item_use_finish", "result", v -> {
  458. ItemStack stack = (ItemStack) v.get(sc);
  459. if(stack == null) {
  460. e.setResultStack(ItemStack.EMPTY);
  461. } else {
  462. e.setResultStack(stack);
  463. }
  464. });
  465. });
  466. }
  467. @SubscribeEvent(receiveCanceled = true)
  468. public void onFishing(ItemFishedEvent e) {
  469. handleEvent("fishing", (sc) -> {
  470. setPlayer(sc, e.getPlayer());
  471. sc.setVar("drops", e.getDrops());
  472. sc.setVar("hook", e.getHookEntity());
  473. sc.setVar("rod_damage", (double) e.getRodDamage());
  474. sc.setVar("cancel", e.isCanceled());
  475. }, (sc) -> {
  476. simpleCancel(sc, e, "fishing");
  477. handleVar(sc, "fishing", "rod_damage", v -> e.damageRodBy(v.getInt(sc)));
  478. });
  479. }
  480. @SubscribeEvent(receiveCanceled = true)
  481. public void onCrafting(PlayerEvent.ItemCraftedEvent e) {
  482. handleEvent("craft", (sc) -> {
  483. setPlayer(sc, e.getPlayer());
  484. setItem(sc, e.getCrafting());
  485. });
  486. }
  487. @SubscribeEvent(receiveCanceled = true)
  488. public void onItemDrop(ItemTossEvent e) {
  489. handleEvent("player_toss", (sc) -> {
  490. setPlayer(sc, e.getPlayer());
  491. setItem(sc, e.getEntityItem().getItem());
  492. sc.setVar("cancel", e.isCanceled());
  493. }, (sc) -> {
  494. simpleCancel(sc, e, "player_toss");
  495. });
  496. }
  497. @SubscribeEvent(receiveCanceled = true)
  498. public void onItemPickup(EntityItemPickupEvent e) {
  499. handleEvent("player_pickup", (sc) -> {
  500. setPlayer(sc, e.getPlayer());
  501. setEntity(sc, e.getItem());
  502. setItem(sc, e.getItem().getItem());
  503. sc.setVar("cancel", e.isCanceled());
  504. }, (sc) -> {
  505. simpleCancel(sc, e, "player_pickup");
  506. });
  507. }
  508. @SubscribeEvent(receiveCanceled = true)
  509. public void onEntityMount(EntityMountEvent e) {
  510. handleEvent(e, "entity_mount", (sc) -> {
  511. sc.setVar("mounting", e.isMounting());
  512. setEntity(sc, e.getEntityBeingMounted());
  513. sc.setVar("rider", e.getEntityMounting());
  514. });
  515. }
  516. @SubscribeEvent(receiveCanceled = true)
  517. public void onPlayerUsePortal(PlayerEvent.PlayerChangedDimensionEvent e) {
  518. handleEvent("portal", (sc) -> {
  519. setPlayer(sc, e.getPlayer());
  520. sc.setVar("from", e.getFrom().getRegistryName().getPath());
  521. sc.setVar("to", e.getTo().getRegistryName().getPath());
  522. });
  523. }
  524. public void onCommand(CommandEvent e) {
  525. handleEvent("command", (sc) -> {
  526. setPlayer(sc, e.getPlayer());
  527. sc.setVar("command", e.getName());
  528. sc.setVar("cancel", e.isCanceled());
  529. }, (sc) -> {
  530. handleVar(sc, "command", "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  531. });
  532. }
  533. public void onCustomCommand(PlayerEntity p, String command, String[] args) {
  534. handleEvent("custom_command", (sc) -> {
  535. setPlayer(sc, p);
  536. sc.setVar("command", command);
  537. if(args.length == 0) {
  538. sc.setVar("args", new ArrayList<>());
  539. sc.setVar("text_args", new ArrayList<>());
  540. } else {
  541. sc.setVar("args", Arrays.stream(args).map(s -> SnuviUtils.convert(s))
  542. .collect(Collectors.toList()));
  543. sc.setVar("text_args", Arrays.stream(args).collect(Collectors.toList()));
  544. }
  545. });
  546. }
  547. public void onFunctionKey(ServerPlayerEntity p, int key) {
  548. handleEvent("function_key", (sc) -> {
  549. setPlayer(sc, p);
  550. sc.setVar("key", (double) key);
  551. });
  552. }
  553. @SubscribeEvent(receiveCanceled = true)
  554. public void onChatEvent(ServerChatEvent e) {
  555. handleEvent("chat", (sc) -> {
  556. setPlayer(sc, e.getPlayer());
  557. sc.setVar("message", e.getMessage());
  558. sc.setVar("cancel", e.isCanceled());
  559. }, (sc) -> {
  560. handleVar(sc, "chat", "message",
  561. v -> e.setComponent(new StringTextComponent(v.getString(sc))));
  562. handleVar(sc, "chat", "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  563. });
  564. }
  565. @SubscribeEvent(receiveCanceled = true, priority = EventPriority.HIGHEST)
  566. public void onPreExplosion(ExplosionEvent.Start e) {
  567. e.setCanceled(true);
  568. handleEvent(e, "pre_explosion", sc -> {
  569. sc.setVar("damage_source", e.getExplosion().getDamageSource());
  570. sc.setVar("location", new Location(e.getWorld(), e.getExplosion().getPosition()));
  571. });
  572. }
  573. @SubscribeEvent
  574. public void onExplosion(ExplosionEvent.Detonate e) {
  575. ReflectionUtils.setNoBreakMode(e.getExplosion());
  576. handleEvent(e, "explosion", sc -> {
  577. sc.setVar("affected_blocks", e.getAffectedBlocks());
  578. sc.setVar("affected_entities", e.getAffectedEntities());
  579. sc.setVar("damage_source", e.getExplosion().getDamageSource());
  580. sc.setVar("location", new Location(e.getWorld(), e.getExplosion().getPosition()));
  581. });
  582. }
  583. private static String getName(ICommandSource cs) {
  584. if(cs instanceof PlayerEntity) {
  585. return ((PlayerEntity) cs).getName().getString();
  586. } else if(cs instanceof MinecraftServer) {
  587. return "Server";
  588. }
  589. return null;
  590. }
  591. public void onMissingCommand(ICommandSource cs, String command) {
  592. PlayerEntity p = (cs instanceof PlayerEntity) ? (PlayerEntity) cs : null;
  593. handleEvent("missing_command", (sc) -> {
  594. setPlayer(sc, p);
  595. sc.setVar("command_name", command);
  596. sc.setVar("sender_name", getName(cs));
  597. });
  598. }
  599. public void onMissingPermission(ICommandSource cs, String command) {
  600. PlayerEntity p = (cs instanceof PlayerEntity) ? (PlayerEntity) cs : null;
  601. handleEvent("missing_perm", (sc) -> {
  602. setPlayer(sc, p);
  603. sc.setVar("command_name", command);
  604. sc.setVar("sender_name", getName(cs));
  605. });
  606. }
  607. @SubscribeEvent(receiveCanceled = true)
  608. public void onEntityJoinWorld(EntityJoinWorldEvent e) {
  609. Entity ent = e.getEntity();
  610. BlockPos pos = ent.getPosition();
  611. Server.scheduler.scheduleTask("onEntityJoinWorld", () -> {
  612. World w = ent.getEntityWorld();
  613. if(w.isAreaLoaded(pos, 1) && ent.getEntityWorld().getBlockState(ent.getPosition())
  614. .getBlock() == Blocks.NETHER_PORTAL) {
  615. ent.setLocationAndAngles(pos.getX(), pos.getY() + 10, pos.getZ(), ent.rotationYaw,
  616. ent.rotationPitch);
  617. return;
  618. }
  619. });
  620. if(!ent.isPassenger() && !scripts.getEntityLimits().isAllowedToSpawn(ent.getType())
  621. && !ent.getTags().contains("mod_spawned")) {
  622. ent.getPassengers().forEach(rider -> {
  623. if(rider == null || rider instanceof PlayerEntity) {
  624. return;
  625. }
  626. rider.remove();
  627. });
  628. ent.removePassengers();
  629. e.setCanceled(true);
  630. return;
  631. }
  632. handleEvent(e, "entity_join", (sc) -> {
  633. setEntity(sc, ent);
  634. });
  635. }
  636. @SubscribeEvent(receiveCanceled = true)
  637. public void onLivingUpdate(LivingUpdateEvent e) {
  638. if(e.getEntity().getTags().contains("no_tick")) {
  639. e.setCanceled(true);
  640. }
  641. }
  642. @SubscribeEvent(receiveCanceled = true)
  643. public void onEntityLeaveWorld(EntityLeaveWorldEvent e) {
  644. Entity ent = e.getEntity();
  645. handleEvent(e, "entity_leave", (sc) -> {
  646. setEntity(sc, ent);
  647. });
  648. }
  649. @SubscribeEvent
  650. public void onServerTick(TickEvent.ServerTickEvent e) {
  651. if(e.phase == TickEvent.Phase.END) {
  652. scripts.getEntityLimits().tick(server.getWorlds());
  653. }
  654. }
  655. @SubscribeEvent(receiveCanceled = true)
  656. public void onAnimalTame(AnimalTameEvent e) {
  657. handleEvent(e, "animal_tame", (sc) -> {
  658. sc.setVar("animal", e.getAnimal());
  659. sc.setVar("tamer", e.getTamer());
  660. });
  661. }
  662. @SubscribeEvent(receiveCanceled = true)
  663. public void onJump(LivingJumpEvent e) {
  664. handleEvent(e, "living_jump", (sc) -> {
  665. setLiving(sc, e.getEntityLiving());
  666. });
  667. }
  668. public void onSneak(PlayerEntity p, boolean sneak) {
  669. handleEvent("player_sneak", (sc) -> {
  670. setPlayer(sc, p);
  671. sc.setVar("sneak", sneak);
  672. });
  673. }
  674. @SubscribeEvent(receiveCanceled = true)
  675. public void onMobGriefing(EntityMobGriefingEvent e) {
  676. handleEvent(e, "mob_griefing", (sc) -> {
  677. Entity ent = e.getEntity();
  678. setEntity(sc, ent);
  679. boolean b = true;
  680. if(ent != null) {
  681. World w = ent.world;
  682. if(w != null) {
  683. GameRules rules = w.getGameRules();
  684. if(rules != null) {
  685. try {
  686. b = !rules.getBoolean(GameRules.MOB_GRIEFING);
  687. } catch(Exception ex) {
  688. System.out.println("onMobGriefing Exception");
  689. ex.printStackTrace();
  690. }
  691. } else {
  692. System.out.println("Rules are null");
  693. }
  694. } else {
  695. System.out.println("World is null");
  696. }
  697. } else {
  698. System.out.println("Entity is null");
  699. }
  700. sc.setVar("cancel", b);
  701. }, (sc) -> {
  702. handleVar(sc, "mob_griefing", "cancel", (v) -> {
  703. e.setResult(v.getBoolean(sc) ? Result.DENY : Result.ALLOW);
  704. });
  705. });
  706. }
  707. @SubscribeEvent(receiveCanceled = true)
  708. public void onWorldLoad(WorldEvent.Load e) {
  709. handleEvent(e, "world_load", (sc) -> {
  710. sc.setVar("world", e.getWorld());
  711. });
  712. }
  713. @Override
  714. public void onCraft(int id, World w, PlayerEntity p, CraftingInventory inv,
  715. CraftResultInventory result) {
  716. if(w.isRemote) {
  717. return;
  718. }
  719. ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) p;
  720. Wrapper<ItemStack> wrapper = new Wrapper<>(ItemStack.EMPTY);
  721. Optional<ICraftingRecipe> optional =
  722. w.getServer().getRecipeManager().getRecipe(IRecipeType.CRAFTING, inv, w);
  723. if(optional.isPresent()) {
  724. ICraftingRecipe icraftingrecipe = optional.get();
  725. if(result.canUseRecipe(w, serverplayerentity, icraftingrecipe)) {
  726. wrapper.set(icraftingrecipe.getCraftingResult(inv));
  727. scripts.getScriptManager().callEvent("craft", (sc) -> {
  728. setPlayer(sc, p);
  729. sc.setVar("result", wrapper.get());
  730. }, (sc) -> {
  731. handleVar(sc, "craft", "result", (v) -> {
  732. ItemStack stack = (ItemStack) v.get(sc);
  733. if(stack == null) {
  734. wrapper.set(ItemStack.EMPTY);
  735. } else {
  736. wrapper.set(stack);
  737. }
  738. });
  739. });
  740. }
  741. }
  742. result.setInventorySlotContents(0, wrapper.get());
  743. serverplayerentity.connection.sendPacket(new SSetSlotPacket(id, 0, wrapper.get()));
  744. }
  745. public void onVote(String[] data) {
  746. if(data.length < 5) {
  747. return;
  748. }
  749. handleEvent("vote", sc -> {
  750. sc.setVar("from", data[1]);
  751. sc.setVar("name", data[2]);
  752. sc.setVar("ip", data[3]);
  753. sc.setVar("timestamp", SnuviUtils.convert(data[4]));
  754. });
  755. }
  756. @Override
  757. public boolean onClick(Container c, int slot, int dragType, ClickType ct, PlayerEntity p) {
  758. String name = c.getClass().getSimpleName();
  759. WrappedBool b = new WrappedBool();
  760. b.wrapped = false;
  761. scripts.getScriptManager().callEvent("container_click", sc -> {
  762. setPlayer(sc, p);
  763. sc.setVar("slot", (double) slot);
  764. sc.setVar("item_list", c.getInventory());
  765. sc.setVar("type", name);
  766. sc.setVar("drag_type", (double) dragType);
  767. sc.setVar("click_type", ct.toString());
  768. sc.setVar("cancel", b.wrapped);
  769. }, sc -> {
  770. handleVar(sc, "container_click", "cancel", v -> b.wrapped = v.getBoolean(sc));
  771. });
  772. return b.wrapped;
  773. }
  774. }