diff --git a/prismarine-minecraft-data b/prismarine-minecraft-data index fc2078a40..bf55e7257 160000 --- a/prismarine-minecraft-data +++ b/prismarine-minecraft-data @@ -1 +1 @@ -Subproject commit fc2078a404b7b6041a1d60f15b6b2b482890bbfb +Subproject commit bf55e7257113471e1d6a8116e83edb6cf5011cca diff --git a/src/autogenerated/java/net/minestom/server/instance/block/Block.java b/src/autogenerated/java/net/minestom/server/instance/block/Block.java index 5bf592062..f9fb5f1e4 100644 --- a/src/autogenerated/java/net/minestom/server/instance/block/Block.java +++ b/src/autogenerated/java/net/minestom/server/instance/block/Block.java @@ -1276,6 +1276,10 @@ public enum Block { return defaultID; } + public String getName() { + return namespaceID; + } + public boolean isAir() { return isAir; } diff --git a/src/generators/java/net/minestom/codegen/blocks/BlockEnumGenerator.java b/src/generators/java/net/minestom/codegen/blocks/BlockEnumGenerator.java index 0a967c972..bb8890d69 100644 --- a/src/generators/java/net/minestom/codegen/blocks/BlockEnumGenerator.java +++ b/src/generators/java/net/minestom/codegen/blocks/BlockEnumGenerator.java @@ -250,6 +250,7 @@ public class BlockEnumGenerator extends MinestomEnumGenerator { generator.addHardcodedField("List", "alternatives", "new ArrayList()"); generator.setParams("String namespaceID", "short defaultID", "double hardness", "double resistance", "boolean isAir", "boolean isSolid", "NamespaceID blockEntity", "boolean singleState"); generator.addMethod("getBlockId", "()", "short", "return defaultID;"); + generator.addMethod("getName", "()", "String", "return namespaceID;"); generator.addMethod("isAir", "()", "boolean", "return isAir;"); generator.addMethod("hasBlockEntity", "()", "boolean", "return blockEntity != null;"); generator.addMethod("getBlockEntityName", "()", "NamespaceID", "return blockEntity;"); diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 061836253..b2cbf7e13 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -27,6 +27,7 @@ import net.minestom.server.scoreboard.TeamManager; import net.minestom.server.storage.StorageFolder; import net.minestom.server.storage.StorageManager; import net.minestom.server.timer.SchedulerManager; +import net.minestom.server.utils.thread.MinestomThread; import net.minestom.server.world.Difficulty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -251,6 +252,10 @@ public class MinecraftServer { nettyServer.stop(); schedulerManager.shutdown(); storageManager.getLoadedFolders().forEach(StorageFolder::close); + LOGGER.info("Shutting down all thread pools."); + MinestomThread.shutdownAll(); + benchmarkManager.disable(); + commandManager.stopConsoleThread(); LOGGER.info("Minestom server stopped successfully."); } diff --git a/src/main/java/net/minestom/server/command/CommandManager.java b/src/main/java/net/minestom/server/command/CommandManager.java index f74b5ea9f..1627e07dc 100644 --- a/src/main/java/net/minestom/server/command/CommandManager.java +++ b/src/main/java/net/minestom/server/command/CommandManager.java @@ -13,6 +13,7 @@ import java.util.*; public class CommandManager { + private boolean running; private String commandPrefix = "/"; private ConsoleSender consoleSender = new ConsoleSender(); @@ -21,18 +22,26 @@ public class CommandManager { private Map commandProcessorMap = new HashMap<>(); public CommandManager() { + running = true; // Setup console thread - new Thread(() -> { + Thread consoleThread = new Thread(() -> { Scanner scanner = new Scanner(System.in); - while (true) { - String command = scanner.nextLine(); - if (!command.startsWith(commandPrefix)) - continue; - command = command.replaceFirst(commandPrefix, ""); - execute(consoleSender, command); - + while (running) { + if(scanner.hasNext()) { + String command = scanner.nextLine(); + if (!command.startsWith(commandPrefix)) + continue; + command = command.replaceFirst(commandPrefix, ""); + execute(consoleSender, command); + } } - }, "ConsoleCommand-Thread").start(); + }, "ConsoleCommand-Thread"); + consoleThread.setDaemon(true); + consoleThread.start(); + } + + public void stopConsoleThread() { + running = false; } public void register(Command command) { diff --git a/src/main/java/net/minestom/server/inventory/Inventory.java b/src/main/java/net/minestom/server/inventory/Inventory.java index 706c1f7ff..4a710b883 100644 --- a/src/main/java/net/minestom/server/inventory/Inventory.java +++ b/src/main/java/net/minestom/server/inventory/Inventory.java @@ -90,8 +90,8 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View @Override public synchronized boolean addItemStack(ItemStack itemStack) { StackingRule stackingRule = itemStack.getStackingRule(); - for (int i = 0; i < getItemStacks().length; i++) { - ItemStack item = getItemStacks()[i]; + for (int i = 0; i < getSize(); i++) { + ItemStack item = getItemStack(i); StackingRule itemStackingRule = item.getStackingRule(); if (itemStackingRule.canBeStacked(itemStack, item)) { int itemAmount = itemStackingRule.getAmount(item); @@ -216,7 +216,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View private synchronized void safeItemInsert(int slot, ItemStack itemStack) { itemStack = ItemStackUtils.notNull(itemStack); - this.itemStacks[slot] = itemStack; + setItemStackInternal(slot, itemStack); SetSlotPacket setSlotPacket = new SetSlotPacket(); setSlotPacket.windowId = getWindowId(); setSlotPacket.slot = (short) slot; @@ -224,10 +224,15 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View sendPacketToViewers(setSlotPacket); } + protected void setItemStackInternal(int slot, ItemStack itemStack) { + itemStacks[slot] = itemStack; + } + private WindowItemsPacket createWindowItemsPacket() { WindowItemsPacket windowItemsPacket = new WindowItemsPacket(); windowItemsPacket.windowId = getWindowId(); - windowItemsPacket.items = itemStacks; + windowItemsPacket.count = (short) getSize(); + windowItemsPacket.items = getItemStacks(); return windowItemsPacket; } @@ -328,7 +333,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View } else { clickResult = clickProcessor.shiftClick(this, player, slot, clicked, cursor, // Window loop - new InventoryClickLoopHandler(0, itemStacks.length, 1, + new InventoryClickLoopHandler(0, getSize(), 1, i -> i, index -> isClickInWindow(index) ? getItemStack(index) : playerInventory.getItemStack(index, offset), (index, itemStack) -> { @@ -462,9 +467,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryClickResult clickResult = clickProcessor.doubleClick(this, player, slot, cursor, // Start by looping through the opened inventory - new InventoryClickLoopHandler(0, itemStacks.length, 1, + new InventoryClickLoopHandler(0, getSize(), 1, i -> i, - index -> itemStacks[index], + index -> getItemStack(index), (index, itemStack) -> setItemStack(index, itemStack)), // Looping through player inventory new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE - 9, 1, diff --git a/src/main/java/net/minestom/server/utils/Direction.java b/src/main/java/net/minestom/server/utils/Direction.java index dc33a675a..b07481aea 100644 --- a/src/main/java/net/minestom/server/utils/Direction.java +++ b/src/main/java/net/minestom/server/utils/Direction.java @@ -1,15 +1,37 @@ package net.minestom.server.utils; public enum Direction { - NORTH, - EAST, - SOUTH, - WEST, - UP, - DOWN; + NORTH(0, 0, -1), + EAST(1, 0, 0), + SOUTH(0, 0, 1), + WEST(-1, 0, 0), + UP(0, 1, 0), + DOWN(0, -1, 0); public static final Direction[] HORIZONTAL = { SOUTH, WEST, NORTH, EAST }; + private final int normalX; + private final int normalY; + private final int normalZ; + + Direction(int normalX, int normalY, int normalZ) { + this.normalX = normalX; + this.normalY = normalY; + this.normalZ = normalZ; + } + + public int normalX() { + return normalX; + } + + public int normalY() { + return normalY; + } + + public int normalZ() { + return normalZ; + } + public Direction opposite() { switch (this) { case UP: diff --git a/src/main/java/net/minestom/server/utils/thread/MinestomThread.java b/src/main/java/net/minestom/server/utils/thread/MinestomThread.java index c2f7b1976..8b247015a 100644 --- a/src/main/java/net/minestom/server/utils/thread/MinestomThread.java +++ b/src/main/java/net/minestom/server/utils/thread/MinestomThread.java @@ -1,16 +1,30 @@ package net.minestom.server.utils.thread; +import net.minestom.server.MinecraftServer; +import net.minestom.server.timer.SchedulerManager; +import net.minestom.server.timer.TaskRunnable; + +import java.util.LinkedList; +import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class MinestomThread extends ThreadPoolExecutor { + private static final List executors = new LinkedList<>(); + public MinestomThread(int nThreads, String name) { super(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(), r -> { Thread thread = new Thread(r); + thread.setDaemon(true); thread.setName(thread.getName().replace("Thread", name)); return thread; }); + executors.add(this); + } + + public static void shutdownAll() { + executors.forEach(MinestomThread::shutdownNow); } }