ScriptEvents.java 32 KB

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