From a4ade2a8063091d4d4de53f90e649cc1613fcb38 Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Mon, 17 Feb 2020 17:33:53 +0100 Subject: [PATCH] Proper separation --- src/main/java/fr/themode/demo/Main.java | 22 +++ src/main/java/fr/themode/demo/PlayerInit.java | 144 ++++++++++++++++++ .../demo => demo/blocks}/StoneBlock.java | 2 +- .../blocks}/UpdatableBlockDemo.java | 2 +- .../demo => demo/entity}/ChickenCreature.java | 2 +- .../demo => demo/entity}/TestArrow.java | 2 +- .../generator}/ChunkGeneratorDemo.java | 2 +- .../{Main.java => MinecraftServer.java} | 108 ++++++------- .../java/fr/themode/minestom/data/Data.java | 6 +- .../fr/themode/minestom/entity/Entity.java | 12 +- .../minestom/entity/EntityManager.java | 8 +- .../fr/themode/minestom/entity/Player.java | 140 ++--------------- .../minestom/instance/BlockModifier.java | 4 +- .../fr/themode/minestom/instance/Chunk.java | 4 +- .../themode/minestom/instance/Instance.java | 6 +- .../minestom/instance/InstanceManager.java | 4 +- .../minestom/instance/batch/IBatch.java | 4 +- .../themode/minestom/inventory/Inventory.java | 6 +- .../minestom/inventory/PlayerInventory.java | 90 ++++++++--- .../fr/themode/minestom/io/DataReader.java | 7 +- .../fr/themode/minestom/io/IOManager.java | 4 +- .../fr/themode/minestom/item/ItemStack.java | 16 +- .../item/rule/VanillaStackingRule.java | 2 +- .../listener/BlockPlacementListener.java | 8 +- .../listener/ChatMessageListener.java | 4 +- .../minestom/net/ConnectionManager.java | 11 ++ .../themode/minestom/net/PacketProcessor.java | 4 +- .../minestom/net/PacketWriterUtils.java | 4 +- .../net/packet/client/ClientPlayPacket.java | 4 +- .../packet/client/login/LoginStartPacket.java | 11 +- .../minestom/timer/SchedulerManager.java | 4 +- .../themode/minestom/utils/EntityUtils.java | 4 +- .../themode/minestom/utils/time/TimeUnit.java | 4 +- 33 files changed, 391 insertions(+), 264 deletions(-) create mode 100644 src/main/java/fr/themode/demo/Main.java create mode 100644 src/main/java/fr/themode/demo/PlayerInit.java rename src/main/java/fr/themode/{minestom/instance/demo => demo/blocks}/StoneBlock.java (91%) rename src/main/java/fr/themode/{minestom/instance/demo => demo/blocks}/UpdatableBlockDemo.java (95%) rename src/main/java/fr/themode/{minestom/entity/demo => demo/entity}/ChickenCreature.java (99%) rename src/main/java/fr/themode/{minestom/entity/demo => demo/entity}/TestArrow.java (93%) rename src/main/java/fr/themode/{minestom/instance/demo => demo/generator}/ChunkGeneratorDemo.java (95%) rename src/main/java/fr/themode/minestom/{Main.java => MinecraftServer.java} (93%) diff --git a/src/main/java/fr/themode/demo/Main.java b/src/main/java/fr/themode/demo/Main.java new file mode 100644 index 000000000..7adbd20e9 --- /dev/null +++ b/src/main/java/fr/themode/demo/Main.java @@ -0,0 +1,22 @@ +package fr.themode.demo; + +import fr.themode.demo.blocks.StoneBlock; +import fr.themode.demo.blocks.UpdatableBlockDemo; +import fr.themode.minestom.MinecraftServer; +import fr.themode.minestom.instance.block.BlockManager; + +public class Main { + + public static void main(String[] args) { + MinecraftServer minecraftServer = MinecraftServer.init(); + + PlayerInit.init(); + + BlockManager blockManager = MinecraftServer.getBlockManager(); + blockManager.registerBlock(new StoneBlock()); + blockManager.registerBlock(new UpdatableBlockDemo()); + + minecraftServer.start("localhost", 55555); + } + +} diff --git a/src/main/java/fr/themode/demo/PlayerInit.java b/src/main/java/fr/themode/demo/PlayerInit.java new file mode 100644 index 000000000..b80cc3966 --- /dev/null +++ b/src/main/java/fr/themode/demo/PlayerInit.java @@ -0,0 +1,144 @@ +package fr.themode.demo; + +import fr.themode.demo.entity.ChickenCreature; +import fr.themode.demo.generator.ChunkGeneratorDemo; +import fr.themode.minestom.MinecraftServer; +import fr.themode.minestom.entity.Entity; +import fr.themode.minestom.entity.EntityCreature; +import fr.themode.minestom.entity.GameMode; +import fr.themode.minestom.entity.Player; +import fr.themode.minestom.event.*; +import fr.themode.minestom.instance.InstanceContainer; +import fr.themode.minestom.inventory.Inventory; +import fr.themode.minestom.inventory.InventoryType; +import fr.themode.minestom.inventory.rule.InventoryConditionResult; +import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.utils.Position; +import fr.themode.minestom.utils.Vector; + +public class PlayerInit { + + private static InstanceContainer instanceContainer; + + static { + ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); + //instanceContainer = Main.getInstanceManager().createInstanceContainer(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); + instanceContainer = MinecraftServer.getInstanceManager().createInstanceContainer(); + instanceContainer.enableAutoChunkLoad(true); + instanceContainer.setChunkGenerator(chunkGeneratorDemo); + int loopStart = -2; + int loopEnd = 2; + long time = System.currentTimeMillis(); + for (int x = loopStart; x < loopEnd; x++) + for (int z = loopStart; z < loopEnd; z++) { + instanceContainer.loadChunk(x, z); + } + System.out.println("Time to load all chunks: " + (System.currentTimeMillis() - time) + " ms"); + } + + public static void init() { + MinecraftServer.getConnectionManager().setPlayerInitialization(player -> { + player.setEventCallback(AttackEvent.class, event -> { + Entity entity = event.getTarget(); + if (entity instanceof EntityCreature) { + ((EntityCreature) entity).damage(-1); + Vector velocity = player.getPosition().clone().getDirection().multiply(6); + velocity.setY(4f); + entity.setVelocity(velocity, 150); + player.sendMessage("You attacked an entity!"); + } else if (entity instanceof Player) { + Player target = (Player) entity; + Vector velocity = player.getPosition().clone().getDirection().multiply(4); + velocity.setY(3.5f); + target.setVelocity(velocity, 150); + target.damage(2); + player.sendMessage("ATTACK"); + } + }); + + player.setEventCallback(PlayerBlockPlaceEvent.class, event -> { + if (event.getHand() != Player.Hand.MAIN) + return; + + for (Player p : player.getInstance().getPlayers()) { + if (p != player) + p.teleport(player.getPosition()); + } + + ChickenCreature chickenCreature = new ChickenCreature(); + chickenCreature.refreshPosition(player.getPosition()); + chickenCreature.setInstance(player.getInstance()); + + }); + + player.setEventCallback(PickupItemEvent.class, event -> { + event.setCancelled(!player.getInventory().addItemStack(event.getItemStack())); // Cancel event if player does not have enough inventory space + }); + + player.setEventCallback(PlayerLoginEvent.class, event -> { + event.setSpawningInstance(instanceContainer); + }); + + player.setEventCallback(PlayerSpawnEvent.class, event -> { + player.setGameMode(GameMode.SURVIVAL); + player.teleport(new Position(0, 66, 0)); + + /*Random random = new Random(); + for (int i = 0; i < 50; i++) { + ChickenCreature chickenCreature = new ChickenCreature(); + chickenCreature.refreshPosition(random.nextInt(100), 65, random.nextInt(100)); + chickenCreature.setInstance(getInstance()); + }*/ + //chickenCreature.addPassenger(this); + + /*for (int ix = 0; ix < 4; ix++) + for (int iz = 0; iz < 4; iz++) { + ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32)); + itemEntity.refreshPosition(ix, 68, iz); + //itemEntity.setNoGravity(true); + itemEntity.setInstance(getInstance()); + //itemEntity.remove(); + }*/ + + ItemStack item = new ItemStack(1, (byte) 4); + item.setDisplayName("LE NOM PUTAIN"); + //item.getLore().add("lol le lore"); + player.getInventory().addItemStack(item); + + Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "Test inventory"); + inventory.setInventoryCondition((slot, inventory1, clickedItem, cursorItem) -> { + InventoryConditionResult result = new InventoryConditionResult(clickedItem, cursorItem); + result.setCancel(false); + return result; + }); + inventory.setItemStack(0, item.clone()); + + player.openInventory(inventory); + + //getInventory().addItemStack(new ItemStack(1, (byte) 100)); + + /*TeamManager teamManager = Main.getTeamManager(); + Team team = teamManager.createTeam(getUsername()); + team.setTeamDisplayName("display"); + team.setPrefix("[Test] "); + team.setTeamColor(ChatColor.RED); + setTeam(team); + + setAttribute(Attribute.MAX_HEALTH, 10); + heal(); + + Sidebar scoreboard = new Sidebar("Scoreboard Title"); + for (int i = 0; i < 15; i++) { + scoreboard.createLine(new Sidebar.ScoreboardLine("id" + i, "Hey guys " + i, i)); + } + scoreboard.addViewer(this); + scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED"); + + BelowNameScoreboard belowNameScoreboard = new BelowNameScoreboard(); + setBelowNameScoreboard(belowNameScoreboard); + belowNameScoreboard.updateScore(this, 50);*/ + }); + }); + } + +} diff --git a/src/main/java/fr/themode/minestom/instance/demo/StoneBlock.java b/src/main/java/fr/themode/demo/blocks/StoneBlock.java similarity index 91% rename from src/main/java/fr/themode/minestom/instance/demo/StoneBlock.java rename to src/main/java/fr/themode/demo/blocks/StoneBlock.java index 37353fc34..add7acfcd 100644 --- a/src/main/java/fr/themode/minestom/instance/demo/StoneBlock.java +++ b/src/main/java/fr/themode/demo/blocks/StoneBlock.java @@ -1,4 +1,4 @@ -package fr.themode.minestom.instance.demo; +package fr.themode.demo.blocks; import fr.themode.minestom.entity.Player; import fr.themode.minestom.instance.block.CustomBlock; diff --git a/src/main/java/fr/themode/minestom/instance/demo/UpdatableBlockDemo.java b/src/main/java/fr/themode/demo/blocks/UpdatableBlockDemo.java similarity index 95% rename from src/main/java/fr/themode/minestom/instance/demo/UpdatableBlockDemo.java rename to src/main/java/fr/themode/demo/blocks/UpdatableBlockDemo.java index d56b63d59..533511f9f 100644 --- a/src/main/java/fr/themode/minestom/instance/demo/UpdatableBlockDemo.java +++ b/src/main/java/fr/themode/demo/blocks/UpdatableBlockDemo.java @@ -1,4 +1,4 @@ -package fr.themode.minestom.instance.demo; +package fr.themode.demo.blocks; import fr.themode.minestom.data.Data; import fr.themode.minestom.entity.Player; diff --git a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java b/src/main/java/fr/themode/demo/entity/ChickenCreature.java similarity index 99% rename from src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java rename to src/main/java/fr/themode/demo/entity/ChickenCreature.java index 7f36e57cc..24bc21b36 100644 --- a/src/main/java/fr/themode/minestom/entity/demo/ChickenCreature.java +++ b/src/main/java/fr/themode/demo/entity/ChickenCreature.java @@ -1,4 +1,4 @@ -package fr.themode.minestom.entity.demo; +package fr.themode.demo.entity; import fr.themode.minestom.entity.Entity; import fr.themode.minestom.entity.EntityCreature; diff --git a/src/main/java/fr/themode/minestom/entity/demo/TestArrow.java b/src/main/java/fr/themode/demo/entity/TestArrow.java similarity index 93% rename from src/main/java/fr/themode/minestom/entity/demo/TestArrow.java rename to src/main/java/fr/themode/demo/entity/TestArrow.java index 6c47d0c94..9501a84f0 100644 --- a/src/main/java/fr/themode/minestom/entity/demo/TestArrow.java +++ b/src/main/java/fr/themode/demo/entity/TestArrow.java @@ -1,4 +1,4 @@ -package fr.themode.minestom.entity.demo; +package fr.themode.demo.entity; import fr.themode.minestom.entity.LivingEntity; import fr.themode.minestom.entity.ObjectEntity; diff --git a/src/main/java/fr/themode/minestom/instance/demo/ChunkGeneratorDemo.java b/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java similarity index 95% rename from src/main/java/fr/themode/minestom/instance/demo/ChunkGeneratorDemo.java rename to src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java index dffd3b4a0..45b4ac0d7 100644 --- a/src/main/java/fr/themode/minestom/instance/demo/ChunkGeneratorDemo.java +++ b/src/main/java/fr/themode/demo/generator/ChunkGeneratorDemo.java @@ -1,4 +1,4 @@ -package fr.themode.minestom.instance.demo; +package fr.themode.demo.generator; import fr.themode.minestom.instance.Biome; import fr.themode.minestom.instance.ChunkGenerator; diff --git a/src/main/java/fr/themode/minestom/Main.java b/src/main/java/fr/themode/minestom/MinecraftServer.java similarity index 93% rename from src/main/java/fr/themode/minestom/Main.java rename to src/main/java/fr/themode/minestom/MinecraftServer.java index b4676686d..363817fd8 100644 --- a/src/main/java/fr/themode/minestom/Main.java +++ b/src/main/java/fr/themode/minestom/MinecraftServer.java @@ -6,8 +6,6 @@ import fr.themode.minestom.entity.EntityManager; import fr.themode.minestom.entity.Player; import fr.themode.minestom.instance.InstanceManager; import fr.themode.minestom.instance.block.BlockManager; -import fr.themode.minestom.instance.demo.StoneBlock; -import fr.themode.minestom.instance.demo.UpdatableBlockDemo; import fr.themode.minestom.listener.PacketListenerManager; import fr.themode.minestom.net.ConnectionManager; import fr.themode.minestom.net.ConnectionUtils; @@ -20,7 +18,7 @@ import fr.themode.minestom.scoreboard.TeamManager; import fr.themode.minestom.timer.SchedulerManager; import fr.themode.minestom.utils.Utils; -public class Main { +public class MinecraftServer { // Thread pools public static final int THREAD_COUNT_PACKET_WRITER = 2; @@ -30,16 +28,13 @@ public class Main { public static final int THREAD_COUNT_ENTITIES = 2; public static final int THREAD_COUNT_PLAYERS_ENTITIES = 2; public static final int THREAD_COUNT_SCHEDULER = 2; - + // Config + public static final int CHUNK_VIEW_DISTANCE = 5; + public static final int ENTITY_VIEW_DISTANCE = 2; // Can be modified at performance cost when decreased private static final int MS_TO_SEC = 1000; public static final int TICK_MS = MS_TO_SEC / 20; public static final int TICK_PER_SECOND = MS_TO_SEC / TICK_MS; - - // Config - public static final int CHUNK_VIEW_DISTANCE = 5; - public static final int ENTITY_VIEW_DISTANCE = 2; - // Networking private static ConnectionManager connectionManager; private static PacketProcessor packetProcessor; @@ -54,7 +49,9 @@ public class Main { private static TeamManager teamManager; private static SchedulerManager schedulerManager; - public static void main(String[] args) { + private static MinecraftServer minecraftServer; + + public static MinecraftServer init() { connectionManager = new ConnectionManager(); packetProcessor = new PacketProcessor(); packetListenerManager = new PacketListenerManager(); @@ -66,11 +63,56 @@ public class Main { teamManager = new TeamManager(); schedulerManager = new SchedulerManager(); - blockManager.registerBlock(new StoneBlock()); - blockManager.registerBlock(new UpdatableBlockDemo()); - server = new Server(); + minecraftServer = new MinecraftServer(); + + return minecraftServer; + } + + public static PacketListenerManager getPacketListenerManager() { + return packetListenerManager; + } + + public static Server getServer() { + return server; + } + + public static InstanceManager getInstanceManager() { + return instanceManager; + } + + public static BlockManager getBlockManager() { + return blockManager; + } + + public static EntityManager getEntityManager() { + return entityManager; + } + + public static DataManager getDataManager() { + return dataManager; + } + + public static TeamManager getTeamManager() { + return teamManager; + } + + public static SchedulerManager getSchedulerManager() { + return schedulerManager; + } + + public static ConnectionManager getConnectionManager() { + return connectionManager; + } + + public void start(String address, int port) { + initClients(); + server.bind(address, port); + initUpdates(); + } + + private void initClients() { server.onConnect(client -> { System.out.println("CONNECTION"); @@ -104,10 +146,9 @@ public class Main { } }); }); + } - server.bind("localhost", 55555); - System.out.println("Server started"); - + private void initUpdates() { final long tickDistance = TICK_MS * 1000000; long currentTime; while (true) { @@ -149,39 +190,4 @@ public class Main { } } - public static PacketListenerManager getPacketListenerManager() { - return packetListenerManager; - } - - public static Server getServer() { - return server; - } - - public static InstanceManager getInstanceManager() { - return instanceManager; - } - - public static BlockManager getBlockManager() { - return blockManager; - } - - public static EntityManager getEntityManager() { - return entityManager; - } - - public static DataManager getDataManager() { - return dataManager; - } - - public static TeamManager getTeamManager() { - return teamManager; - } - - public static SchedulerManager getSchedulerManager() { - return schedulerManager; - } - - public static ConnectionManager getConnectionManager() { - return connectionManager; - } } diff --git a/src/main/java/fr/themode/minestom/data/Data.java b/src/main/java/fr/themode/minestom/data/Data.java index 40d33ec09..1f0924e4c 100644 --- a/src/main/java/fr/themode/minestom/data/Data.java +++ b/src/main/java/fr/themode/minestom/data/Data.java @@ -1,6 +1,6 @@ package fr.themode.minestom.data; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.utils.PrimitiveConversion; import java.io.ByteArrayOutputStream; @@ -11,7 +11,7 @@ import java.util.concurrent.ConcurrentHashMap; public class Data { - private static final DataManager DATA_MANAGER = Main.getDataManager(); + private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager(); // TODO replace maps to something more memory-friendly private ConcurrentHashMap data = new ConcurrentHashMap(); @@ -48,7 +48,7 @@ public class Data { String key = entry.getKey(); Class type = dataType.get(key); Object value = entry.getValue(); - DataType dataType = Main.getDataManager().getDataType(type); + DataType dataType = DATA_MANAGER.getDataType(type); byte[] encodedType = PrimitiveConversion.getObjectClassString(type.getName()).getBytes(); // Data type (fix for primitives) dos.writeShort(encodedType.length); diff --git a/src/main/java/fr/themode/minestom/entity/Entity.java b/src/main/java/fr/themode/minestom/entity/Entity.java index dba24e875..e79d746a0 100644 --- a/src/main/java/fr/themode/minestom/entity/Entity.java +++ b/src/main/java/fr/themode/minestom/entity/Entity.java @@ -1,7 +1,7 @@ package fr.themode.minestom.entity; import com.github.simplenet.packet.Packet; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.Viewable; import fr.themode.minestom.collision.BoundingBox; import fr.themode.minestom.data.Data; @@ -206,7 +206,7 @@ public abstract class Entity implements Viewable, DataContainer { if (this instanceof Player) { sendPacketToViewersAndSelf(getVelocityPacket()); } else { - final float tps = Main.TICK_PER_SECOND; + final float tps = MinecraftServer.TICK_PER_SECOND; refreshPosition(position.getX() + velocity.getX() / tps, position.getY() + velocity.getY() / tps, position.getZ() + velocity.getZ() / tps); if (this instanceof ObjectEntity) { sendPacketToViewers(getVelocityPacket()); @@ -468,8 +468,8 @@ public abstract class Entity implements Viewable, DataContainer { ((Player) entity).onChunkChange(lastChunk, newChunk); // Refresh loaded chunk // Refresh entity viewable list - long[] lastVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), Main.ENTITY_VIEW_DISTANCE); - long[] updatedVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), Main.ENTITY_VIEW_DISTANCE); + long[] lastVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE); + long[] updatedVisibleChunksEntity = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), MinecraftServer.ENTITY_VIEW_DISTANCE); boolean isPlayer = entity instanceof Player; @@ -570,7 +570,7 @@ public abstract class Entity implements Viewable, DataContainer { } protected EntityVelocityPacket getVelocityPacket() { - final float strength = 8000f / Main.TICK_PER_SECOND; + final float strength = 8000f / MinecraftServer.TICK_PER_SECOND; EntityVelocityPacket velocityPacket = new EntityVelocityPacket(); velocityPacket.entityId = getEntityId(); velocityPacket.velocityX = (short) (velocity.getX() * strength); @@ -684,7 +684,7 @@ public abstract class Entity implements Viewable, DataContainer { } private boolean shouldUpdate(long time) { - return (float) (time - lastUpdate) >= Main.TICK_MS * 0.9f; // Margin of error + return (float) (time - lastUpdate) >= MinecraftServer.TICK_MS * 0.9f; // Margin of error } public enum Pose { diff --git a/src/main/java/fr/themode/minestom/entity/EntityManager.java b/src/main/java/fr/themode/minestom/entity/EntityManager.java index 82edbd2e4..e8dc7ecc9 100644 --- a/src/main/java/fr/themode/minestom/entity/EntityManager.java +++ b/src/main/java/fr/themode/minestom/entity/EntityManager.java @@ -1,6 +1,6 @@ package fr.themode.minestom.entity; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.event.PlayerLoginEvent; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Instance; @@ -13,13 +13,13 @@ import java.util.concurrent.ExecutorService; public class EntityManager { - private static InstanceManager instanceManager = Main.getInstanceManager(); + private static InstanceManager instanceManager = MinecraftServer.getInstanceManager(); private UpdateType updateType = UpdateType.PER_CHUNK; private Set instances = instanceManager.getInstances(); - private ExecutorService entitiesPool = new MinestomThread(Main.THREAD_COUNT_ENTITIES, "Ms-EntitiesPool"); - private ExecutorService playersPool = new MinestomThread(Main.THREAD_COUNT_PLAYERS_ENTITIES, "Ms-PlayersPool"); + private ExecutorService entitiesPool = new MinestomThread(MinecraftServer.THREAD_COUNT_ENTITIES, "Ms-EntitiesPool"); + private ExecutorService playersPool = new MinestomThread(MinecraftServer.THREAD_COUNT_PLAYERS_ENTITIES, "Ms-PlayersPool"); private ConcurrentLinkedQueue waitingPlayers = new ConcurrentLinkedQueue<>(); diff --git a/src/main/java/fr/themode/minestom/entity/Player.java b/src/main/java/fr/themode/minestom/entity/Player.java index a61ea166f..bc92340ef 100644 --- a/src/main/java/fr/themode/minestom/entity/Player.java +++ b/src/main/java/fr/themode/minestom/entity/Player.java @@ -2,30 +2,27 @@ package fr.themode.minestom.entity; import club.thectm.minecraft.text.TextObject; import com.google.gson.JsonObject; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.bossbar.BossBar; import fr.themode.minestom.chat.Chat; import fr.themode.minestom.collision.BoundingBox; -import fr.themode.minestom.entity.demo.ChickenCreature; import fr.themode.minestom.entity.property.Attribute; import fr.themode.minestom.event.*; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Instance; -import fr.themode.minestom.instance.InstanceContainer; import fr.themode.minestom.instance.block.CustomBlock; -import fr.themode.minestom.instance.demo.ChunkGeneratorDemo; import fr.themode.minestom.inventory.Inventory; -import fr.themode.minestom.inventory.InventoryType; import fr.themode.minestom.inventory.PlayerInventory; -import fr.themode.minestom.inventory.rule.InventoryConditionResult; -import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.net.packet.client.ClientPlayPacket; import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.play.*; import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.scoreboard.BelowNameScoreboard; import fr.themode.minestom.scoreboard.Team; -import fr.themode.minestom.utils.*; +import fr.themode.minestom.utils.ArrayUtils; +import fr.themode.minestom.utils.BlockPosition; +import fr.themode.minestom.utils.ChunkUtils; +import fr.themode.minestom.utils.Position; import fr.themode.minestom.world.Dimension; import fr.themode.minestom.world.LevelType; @@ -51,24 +48,6 @@ public class Player extends LivingEntity { protected boolean onGround; - private static InstanceContainer instanceContainer; - - static { - ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); - //instanceContainer = Main.getInstanceManager().createInstanceContainer(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); - instanceContainer = Main.getInstanceManager().createInstanceContainer(); - instanceContainer.enableAutoChunkLoad(true); - instanceContainer.setChunkGenerator(chunkGeneratorDemo); - int loopStart = -2; - int loopEnd = 2; - long time = System.currentTimeMillis(); - for (int x = loopStart; x < loopEnd; x++) - for (int z = loopStart; z < loopEnd; z++) { - instanceContainer.loadChunk(x, z); - } - System.out.println("Time to load all chunks: " + (System.currentTimeMillis() - time) + " ms"); - } - protected Set viewableEntities = new CopyOnWriteArraySet<>(); protected Set viewableChunks = new CopyOnWriteArraySet<>(); @@ -120,107 +99,6 @@ public class Player extends LivingEntity { this.inventory = new PlayerInventory(this); setCanPickupItem(true); // By default - - setEventCallback(AttackEvent.class, event -> { - Entity entity = event.getTarget(); - if (entity instanceof EntityCreature) { - ((EntityCreature) entity).damage(-1); - Vector velocity = getPosition().clone().getDirection().multiply(6); - velocity.setY(4f); - entity.setVelocity(velocity, 150); - sendMessage("You attacked an entity!"); - } else if (entity instanceof Player) { - Player player = (Player) entity; - Vector velocity = getPosition().clone().getDirection().multiply(4); - velocity.setY(3.5f); - player.setVelocity(velocity, 150); - player.damage(2); - sendMessage("ATTACK"); - } - }); - - setEventCallback(PlayerBlockPlaceEvent.class, event -> { - if (event.getHand() != Hand.MAIN) - return; - - for (Player player : instance.getPlayers()) { - if (player != this) - player.teleport(getPosition()); - } - - ChickenCreature chickenCreature = new ChickenCreature(); - chickenCreature.refreshPosition(getPosition()); - chickenCreature.setInstance(getInstance()); - - }); - - setEventCallback(PickupItemEvent.class, event -> { - event.setCancelled(!getInventory().addItemStack(event.getItemStack())); // Cancel event if player does not have enough inventory space - }); - - setEventCallback(PlayerLoginEvent.class, event -> { - event.setSpawningInstance(instanceContainer); - }); - - setEventCallback(PlayerSpawnEvent.class, event -> { - setGameMode(GameMode.SURVIVAL); - teleport(new Position(0, 66, 0)); - - /*Random random = new Random(); - for (int i = 0; i < 50; i++) { - ChickenCreature chickenCreature = new ChickenCreature(); - chickenCreature.refreshPosition(random.nextInt(100), 65, random.nextInt(100)); - chickenCreature.setInstance(getInstance()); - }*/ - //chickenCreature.addPassenger(this); - - /*for (int ix = 0; ix < 4; ix++) - for (int iz = 0; iz < 4; iz++) { - ItemEntity itemEntity = new ItemEntity(new ItemStack(1, (byte) 32)); - itemEntity.refreshPosition(ix, 68, iz); - //itemEntity.setNoGravity(true); - itemEntity.setInstance(getInstance()); - //itemEntity.remove(); - }*/ - - ItemStack item = new ItemStack(1, (byte) 4); - item.setDisplayName("LE NOM PUTAIN"); - //item.getLore().add("lol le lore"); - getInventory().addItemStack(item); - - Inventory inventory = new Inventory(InventoryType.CHEST_1_ROW, "Test inventory"); - inventory.setInventoryCondition((slot, inventory1, clickedItem, cursorItem) -> { - InventoryConditionResult result = new InventoryConditionResult(clickedItem, cursorItem); - result.setCancel(false); - return result; - }); - inventory.setItemStack(0, item.clone()); - - openInventory(inventory); - - //getInventory().addItemStack(new ItemStack(1, (byte) 100)); - - /*TeamManager teamManager = Main.getTeamManager(); - Team team = teamManager.createTeam(getUsername()); - team.setTeamDisplayName("display"); - team.setPrefix("[Test] "); - team.setTeamColor(ChatColor.RED); - setTeam(team); - - setAttribute(Attribute.MAX_HEALTH, 10); - heal(); - - Sidebar scoreboard = new Sidebar("Scoreboard Title"); - for (int i = 0; i < 15; i++) { - scoreboard.createLine(new Sidebar.ScoreboardLine("id" + i, "Hey guys " + i, i)); - } - scoreboard.addViewer(this); - scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED"); - - BelowNameScoreboard belowNameScoreboard = new BelowNameScoreboard(); - setBelowNameScoreboard(belowNameScoreboard); - belowNameScoreboard.updateScore(this, 50);*/ - }); } @Override @@ -610,10 +488,10 @@ public class Player extends LivingEntity { float dx = newChunk.getChunkX() - lastChunk.getChunkX(); float dz = newChunk.getChunkZ() - lastChunk.getChunkZ(); double distance = Math.sqrt(dx * dx + dz * dz); - boolean isFar = distance >= Main.CHUNK_VIEW_DISTANCE / 2; + boolean isFar = distance >= MinecraftServer.CHUNK_VIEW_DISTANCE / 2; - long[] lastVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), Main.CHUNK_VIEW_DISTANCE); - long[] updatedVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), Main.CHUNK_VIEW_DISTANCE); + long[] lastVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * lastChunk.getChunkX(), 0, 16 * lastChunk.getChunkZ()), MinecraftServer.CHUNK_VIEW_DISTANCE); + long[] updatedVisibleChunks = ChunkUtils.getChunksInRange(new Position(16 * newChunk.getChunkX(), 0, 16 * newChunk.getChunkZ()), MinecraftServer.CHUNK_VIEW_DISTANCE); int[] oldChunks = ArrayUtils.getDifferencesBetweenArray(lastVisibleChunks, updatedVisibleChunks); int[] newChunks = ArrayUtils.getDifferencesBetweenArray(updatedVisibleChunks, lastVisibleChunks); @@ -995,7 +873,7 @@ public class Player extends LivingEntity { } public int getChunkRange() { - int serverRange = Main.CHUNK_VIEW_DISTANCE; + int serverRange = MinecraftServer.CHUNK_VIEW_DISTANCE; int playerRange = getSettings().viewDistance; if (playerRange == 0) { return serverRange; // Didn't receive settings packet yet diff --git a/src/main/java/fr/themode/minestom/instance/BlockModifier.java b/src/main/java/fr/themode/minestom/instance/BlockModifier.java index 4a6126b9d..6da6f76f7 100644 --- a/src/main/java/fr/themode/minestom/instance/BlockModifier.java +++ b/src/main/java/fr/themode/minestom/instance/BlockModifier.java @@ -1,6 +1,6 @@ package fr.themode.minestom.instance; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.data.Data; import fr.themode.minestom.instance.block.BlockManager; import fr.themode.minestom.instance.block.CustomBlock; @@ -9,7 +9,7 @@ import fr.themode.minestom.utils.Position; public interface BlockModifier { - BlockManager BLOCK_MANAGER = Main.getBlockManager(); + BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); void setBlock(int x, int y, int z, short blockId, Data data); diff --git a/src/main/java/fr/themode/minestom/instance/Chunk.java b/src/main/java/fr/themode/minestom/instance/Chunk.java index 6c050e020..c846c85cd 100644 --- a/src/main/java/fr/themode/minestom/instance/Chunk.java +++ b/src/main/java/fr/themode/minestom/instance/Chunk.java @@ -1,7 +1,7 @@ package fr.themode.minestom.instance; import com.github.simplenet.packet.Packet; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.Viewable; import fr.themode.minestom.data.Data; import fr.themode.minestom.entity.Player; @@ -26,7 +26,7 @@ import java.util.concurrent.CopyOnWriteArraySet; // TODO light data & API public class Chunk implements Viewable { - private static final BlockManager BLOCK_MANAGER = Main.getBlockManager(); + private static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); public static final int CHUNK_SIZE_X = 16; public static final int CHUNK_SIZE_Y = 256; diff --git a/src/main/java/fr/themode/minestom/instance/Instance.java b/src/main/java/fr/themode/minestom/instance/Instance.java index 97856a98c..97b96935c 100644 --- a/src/main/java/fr/themode/minestom/instance/Instance.java +++ b/src/main/java/fr/themode/minestom/instance/Instance.java @@ -1,7 +1,7 @@ package fr.themode.minestom.instance; import com.github.simplenet.packet.Packet; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.data.Data; import fr.themode.minestom.data.DataContainer; import fr.themode.minestom.entity.*; @@ -24,7 +24,7 @@ import java.util.function.Consumer; public abstract class Instance implements BlockModifier, DataContainer { protected static final ChunkLoaderIO CHUNK_LOADER_IO = new ChunkLoaderIO(); - protected static final BlockManager BLOCK_MANAGER = Main.getBlockManager(); + protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); // Entities present in this instance protected Set players = new CopyOnWriteArraySet<>(); @@ -206,7 +206,7 @@ public abstract class Instance implements BlockModifier, DataContainer { lastInstance.removeEntity(entity); // If entity is in another instance, remove it from there and add it to this } - long[] visibleChunksEntity = ChunkUtils.getChunksInRange(entity.getPosition(), Main.ENTITY_VIEW_DISTANCE); + long[] visibleChunksEntity = ChunkUtils.getChunksInRange(entity.getPosition(), MinecraftServer.ENTITY_VIEW_DISTANCE); boolean isPlayer = entity instanceof Player; if (isPlayer) { diff --git a/src/main/java/fr/themode/minestom/instance/InstanceManager.java b/src/main/java/fr/themode/minestom/instance/InstanceManager.java index 2d3ffb513..51d45a263 100644 --- a/src/main/java/fr/themode/minestom/instance/InstanceManager.java +++ b/src/main/java/fr/themode/minestom/instance/InstanceManager.java @@ -1,6 +1,6 @@ package fr.themode.minestom.instance; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.utils.thread.MinestomThread; import java.io.File; @@ -12,7 +12,7 @@ import java.util.concurrent.ExecutorService; public class InstanceManager { - private ExecutorService blocksPool = new MinestomThread(Main.THREAD_COUNT_BLOCK_UPDATE, "Ms-BlockUpdatePool"); + private ExecutorService blocksPool = new MinestomThread(MinecraftServer.THREAD_COUNT_BLOCK_UPDATE, "Ms-BlockUpdatePool"); private Set instances = Collections.synchronizedSet(new HashSet<>()); diff --git a/src/main/java/fr/themode/minestom/instance/batch/IBatch.java b/src/main/java/fr/themode/minestom/instance/batch/IBatch.java index 39e30708a..dad9a7196 100644 --- a/src/main/java/fr/themode/minestom/instance/batch/IBatch.java +++ b/src/main/java/fr/themode/minestom/instance/batch/IBatch.java @@ -1,6 +1,6 @@ package fr.themode.minestom.instance.batch; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.instance.BlockModifier; import fr.themode.minestom.utils.thread.MinestomThread; @@ -8,6 +8,6 @@ import java.util.concurrent.ExecutorService; public interface IBatch extends BlockModifier { - ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_BLOCK_BATCH, "Ms-BlockBatchPool"); + ExecutorService batchesPool = new MinestomThread(MinecraftServer.THREAD_COUNT_BLOCK_BATCH, "Ms-BlockBatchPool"); } diff --git a/src/main/java/fr/themode/minestom/inventory/Inventory.java b/src/main/java/fr/themode/minestom/inventory/Inventory.java index baf8962a3..b7b87bb2c 100644 --- a/src/main/java/fr/themode/minestom/inventory/Inventory.java +++ b/src/main/java/fr/themode/minestom/inventory/Inventory.java @@ -542,7 +542,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View item = cursorRule.apply(item, totalAmount - maxSize); setItemStack(i, item); } else { - cursorItem.setAmount((byte) totalAmount); + cursorItem = cursorRule.apply(cursorItem, totalAmount); setItemStack(i, ItemStack.AIR_ITEM); } amount = cursorItem.getAmount(); @@ -563,7 +563,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View item = cursorRule.apply(item, totalAmount - maxSize); playerInventory.setItemStack(i, offset, item); } else { - cursorItem.setAmount((byte) totalAmount); + cursorItem = cursorRule.apply(cursorItem, totalAmount); playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM); } amount = cursorItem.getAmount(); @@ -583,7 +583,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View item = cursorRule.apply(item, totalAmount - maxSize); playerInventory.setItemStack(i, offset, item); } else { - cursorItem.setAmount((byte) totalAmount); + cursorItem = cursorRule.apply(cursorItem, totalAmount); playerInventory.setItemStack(i, offset, ItemStack.AIR_ITEM); } amount = cursorItem.getAmount(); diff --git a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java index b2b5c1843..ac1244bb3 100644 --- a/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java +++ b/src/main/java/fr/themode/minestom/inventory/PlayerInventory.java @@ -2,7 +2,9 @@ package fr.themode.minestom.inventory; import fr.themode.minestom.entity.Player; import fr.themode.minestom.inventory.rule.InventoryCondition; +import fr.themode.minestom.inventory.rule.InventoryConditionResult; import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.item.StackingRule; import fr.themode.minestom.net.packet.server.play.EntityEquipmentPacket; import fr.themode.minestom.net.packet.server.play.SetSlotPacket; import fr.themode.minestom.net.packet.server.play.WindowItemsPacket; @@ -14,8 +16,6 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler public static final int INVENTORY_SIZE = 46; - private static final byte ITEM_MAX_SIZE = 127; - private static final int OFFSET = 9; private static final int CRAFT_SLOT_1 = 36; @@ -74,20 +74,23 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler @Override public boolean addItemStack(ItemStack itemStack) { synchronized (this) { + StackingRule stackingRule = itemStack.getStackingRule(); for (int i = 0; i < items.length - 10; i++) { ItemStack item = items[i]; + StackingRule itemStackingRule = item.getStackingRule(); if (item.isAir()) { setItemStack(i, itemStack); return true; } else if (itemStack.isSimilar(item)) { int itemAmount = item.getAmount(); - if (itemAmount == ITEM_MAX_SIZE) + if (itemAmount == stackingRule.getMaxSize()) continue; int totalAmount = itemStack.getAmount() + itemAmount; - if (totalAmount > ITEM_MAX_SIZE) { - item.setAmount((byte) ITEM_MAX_SIZE); + if (!stackingRule.canApply(itemStack, totalAmount)) { + item = itemStackingRule.apply(item, itemStackingRule.getMaxSize()); + sendSlotRefresh((short) convertToPacketSlot(i), item); - itemStack.setAmount((byte) (totalAmount - ITEM_MAX_SIZE)); + itemStack = stackingRule.apply(itemStack, totalAmount - stackingRule.getMaxSize()); } else { item.setAmount((byte) totalAmount); sendSlotRefresh((short) convertToPacketSlot(i), item); @@ -288,11 +291,28 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack cursorItem = getCursorItem(); ItemStack clicked = getItemStack(convertSlot(slot, OFFSET)); - if (!cursorItem.isAir()) { + // Start condition + InventoryCondition inventoryCondition = getInventoryCondition(); + if (inventoryCondition != null) { + InventoryConditionResult result = inventoryCondition.accept(slot, null, clicked, cursorItem); + cursorItem = result.getCursorItem(); + clicked = result.getClickedItem(); + + if (result.isCancel()) { + setItemStack(slot, OFFSET, clicked); + setCursorItem(cursorItem); + // Refresh client slot + sendSlotRefresh((short) slot, clicked); + return; + } + } + // End condition + + /*if (!cursorItem.isAir()) { if (slot == 0 || slot == 6 || slot == 7 || slot == 8) { return; // Disable putting item on CRAFTING_RESULT and chestplate/leggings/boots slots } - } + }*/ if (cursorItem.isAir() && clicked.isAir()) return; @@ -300,16 +320,19 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack resultCursor; ItemStack resultClicked; + StackingRule cursorRule = cursorItem.getStackingRule(); + StackingRule clickedRule = clicked.getStackingRule(); + if (cursorItem.isSimilar(clicked)) { resultCursor = cursorItem.clone(); resultClicked = clicked.clone(); int totalAmount = cursorItem.getAmount() + clicked.getAmount(); - if (totalAmount > ITEM_MAX_SIZE) { - resultCursor.setAmount((byte) (totalAmount - ITEM_MAX_SIZE)); - resultClicked.setAmount((byte) ITEM_MAX_SIZE); + if (!clickedRule.canApply(resultClicked, totalAmount)) { + resultCursor = cursorRule.apply(resultCursor, totalAmount - cursorRule.getMaxSize()); + resultClicked = clickedRule.apply(resultClicked, clickedRule.getMaxSize()); } else { - resultCursor = ItemStack.AIR_ITEM; - resultClicked.setAmount((byte) totalAmount); + resultCursor = cursorRule.apply(resultCursor, 0); + resultClicked = clickedRule.apply(resultClicked, totalAmount); } } else { resultCursor = clicked.clone(); @@ -325,11 +348,28 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack cursorItem = getCursorItem(); ItemStack clicked = getItemStack(slot, OFFSET); - if (!cursorItem.isAir()) { + // Start condition + InventoryCondition inventoryCondition = getInventoryCondition(); + if (inventoryCondition != null) { + InventoryConditionResult result = inventoryCondition.accept(slot, null, clicked, cursorItem); + cursorItem = result.getCursorItem(); + clicked = result.getClickedItem(); + + if (result.isCancel()) { + setItemStack(slot, OFFSET, clicked); + setCursorItem(cursorItem); + // Refresh client slot + sendSlotRefresh((short) slot, clicked); + return; + } + } + // End condition + + /*if (!cursorItem.isAir()) { if (slot == 0 || slot == 6 || slot == 7 || slot == 8) { return; // Disable putting item on CRAFTING_RESULT and on helmet/chestplate/leggings/boots slots } - } + }*/ if (cursorItem.isAir() && clicked.isAir()) return; @@ -337,19 +377,21 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler ItemStack resultCursor; ItemStack resultClicked; + StackingRule cursorRule = cursorItem.getStackingRule(); + StackingRule clickedRule = clicked.getStackingRule(); + if (cursorItem.isSimilar(clicked)) { resultClicked = clicked.clone(); int amount = clicked.getAmount() + 1; - if (amount > ITEM_MAX_SIZE) { + if (!clickedRule.canApply(resultClicked, amount)) { return; } else { resultCursor = cursorItem.clone(); - resultCursor.setAmount((byte) (resultCursor.getAmount() - 1)); - if (resultCursor.getAmount() < 1) - resultCursor = ItemStack.AIR_ITEM; - resultClicked.setAmount((byte) amount); + resultCursor = cursorRule.apply(resultCursor, cursorRule.getAmount(resultCursor) - 1); + resultClicked = clickedRule.apply(resultClicked, amount); } } else { + // TODO complete replace setAmount for StackingRule if (cursorItem.isAir()) { int amount = (int) Math.ceil((double) clicked.getAmount() / 2d); resultCursor = clicked.clone(); @@ -378,7 +420,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler @Override public void shiftClick(Player player, int slot) { - ItemStack clicked = getItemStack(slot, OFFSET); + /*ItemStack clicked = getItemStack(slot, OFFSET); if (clicked.isAir()) return; @@ -416,7 +458,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler } if (!filled) { setItemStack(slot, OFFSET, resultClicked); - } + }*/ } @Override @@ -467,7 +509,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler @Override public void doubleClick(Player player, int slot) { - ItemStack cursorItem = getCursorItem().clone(); + /*ItemStack cursorItem = getCursorItem().clone(); if (cursorItem.isAir()) return; @@ -497,6 +539,6 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler } } - setCursorItem(cursorItem); + setCursorItem(cursorItem);*/ } } diff --git a/src/main/java/fr/themode/minestom/io/DataReader.java b/src/main/java/fr/themode/minestom/io/DataReader.java index ac2b03cf1..d2bb6163c 100644 --- a/src/main/java/fr/themode/minestom/io/DataReader.java +++ b/src/main/java/fr/themode/minestom/io/DataReader.java @@ -1,7 +1,8 @@ package fr.themode.minestom.io; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.data.Data; +import fr.themode.minestom.data.DataManager; import fr.themode.minestom.utils.CompressionUtils; import java.io.ByteArrayInputStream; @@ -10,6 +11,8 @@ import java.io.IOException; public class DataReader { + private static final DataManager DATA_MANAGER = MinecraftServer.getDataManager(); + public static Data readData(byte[] b, boolean shouldDecompress) { b = shouldDecompress ? CompressionUtils.getDecompressedData(b) : b; @@ -42,7 +45,7 @@ public class DataReader { Class type = Class.forName(new String(typeCache)); String name = new String(nameCache); - Object value = Main.getDataManager().getDataType(type).decode(valueCache); + Object value = DATA_MANAGER.getDataType(type).decode(valueCache); data.set(name, value, type); } diff --git a/src/main/java/fr/themode/minestom/io/IOManager.java b/src/main/java/fr/themode/minestom/io/IOManager.java index 7d468625f..fcec3fe1f 100644 --- a/src/main/java/fr/themode/minestom/io/IOManager.java +++ b/src/main/java/fr/themode/minestom/io/IOManager.java @@ -1,13 +1,13 @@ package fr.themode.minestom.io; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.utils.thread.MinestomThread; import java.util.concurrent.ExecutorService; public class IOManager { - private static final ExecutorService IO_POOL = new MinestomThread(Main.THREAD_COUNT_IO, "Ms-IOPool"); + private static final ExecutorService IO_POOL = new MinestomThread(MinecraftServer.THREAD_COUNT_IO, "Ms-IOPool"); public static void submit(Runnable runnable) { IO_POOL.execute(runnable); diff --git a/src/main/java/fr/themode/minestom/item/ItemStack.java b/src/main/java/fr/themode/minestom/item/ItemStack.java index e0fc1edd1..aec538d85 100644 --- a/src/main/java/fr/themode/minestom/item/ItemStack.java +++ b/src/main/java/fr/themode/minestom/item/ItemStack.java @@ -9,6 +9,7 @@ import java.util.ArrayList; public class ItemStack implements DataContainer { public static final ItemStack AIR_ITEM = new ItemStack(0, (byte) 1); + private static StackingRule defaultStackingRule = new VanillaStackingRule(64); private Material material; private byte amount; @@ -18,7 +19,7 @@ public class ItemStack implements DataContainer { private boolean unbreakable; private ArrayList lore; - private StackingRule stackingRule = new VanillaStackingRule((byte) 64); + private StackingRule stackingRule; private Data data; public ItemStack(Material material, byte amount, short damage) { @@ -26,6 +27,8 @@ public class ItemStack implements DataContainer { this.amount = amount; this.damage = damage; this.lore = new ArrayList<>(); + + this.stackingRule = defaultStackingRule; } public ItemStack(int id, byte amount) { @@ -139,4 +142,15 @@ public class ItemStack implements DataContainer { public void setData(Data data) { this.data = data; } + + public static StackingRule getDefaultStackingRule() { + return defaultStackingRule; + } + + public static void setDefaultStackingRule(StackingRule defaultStackingRule) { + if (defaultStackingRule == null) + throw new NullPointerException("StackingRule cannot be null!"); + + ItemStack.defaultStackingRule = defaultStackingRule; + } } diff --git a/src/main/java/fr/themode/minestom/item/rule/VanillaStackingRule.java b/src/main/java/fr/themode/minestom/item/rule/VanillaStackingRule.java index 43fdd8311..dd0eee4fe 100644 --- a/src/main/java/fr/themode/minestom/item/rule/VanillaStackingRule.java +++ b/src/main/java/fr/themode/minestom/item/rule/VanillaStackingRule.java @@ -11,7 +11,7 @@ public class VanillaStackingRule extends StackingRule { @Override public boolean canApply(ItemStack item, int newAmount) { - return newAmount >= 1 && newAmount <= getMaxSize(); + return newAmount > 0 && newAmount <= getMaxSize(); } @Override diff --git a/src/main/java/fr/themode/minestom/listener/BlockPlacementListener.java b/src/main/java/fr/themode/minestom/listener/BlockPlacementListener.java index 90bf7446e..8f66a11a5 100644 --- a/src/main/java/fr/themode/minestom/listener/BlockPlacementListener.java +++ b/src/main/java/fr/themode/minestom/listener/BlockPlacementListener.java @@ -7,6 +7,7 @@ import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Instance; import fr.themode.minestom.inventory.PlayerInventory; import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.item.StackingRule; import fr.themode.minestom.net.packet.client.play.ClientPlayerBlockPlacementPacket; import fr.themode.minestom.net.packet.client.play.ClientPlayerDiggingPacket; import fr.themode.minestom.utils.BlockPosition; @@ -44,9 +45,10 @@ public class BlockPlacementListener { if (!playerBlockPlaceEvent.isCancelled()) { instance.setCustomBlock(blockPosition, "updatable"); // TODO set useItem's block instead if (playerBlockPlaceEvent.doesConsumeBlock()) { - usedItem.setAmount((byte) (usedItem.getAmount() - 1)); - if (usedItem.getAmount() <= 0) - usedItem = ItemStack.AIR_ITEM; + + StackingRule stackingRule = usedItem.getStackingRule(); + stackingRule.apply(usedItem, stackingRule.getAmount(usedItem) - 1); + if (hand == Player.Hand.OFF) { playerInventory.setItemInOffHand(usedItem); } else { // Main diff --git a/src/main/java/fr/themode/minestom/listener/ChatMessageListener.java b/src/main/java/fr/themode/minestom/listener/ChatMessageListener.java index f922d2c37..ba371ae8d 100644 --- a/src/main/java/fr/themode/minestom/listener/ChatMessageListener.java +++ b/src/main/java/fr/themode/minestom/listener/ChatMessageListener.java @@ -1,7 +1,7 @@ package fr.themode.minestom.listener; import club.thectm.minecraft.text.*; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.chat.Chat; import fr.themode.minestom.entity.Player; import fr.themode.minestom.event.PlayerChatEvent; @@ -14,7 +14,7 @@ public class ChatMessageListener { public static void listener(ClientChatMessagePacket packet, Player player) { String message = Chat.uncoloredLegacyText(packet.message); - PlayerChatEvent playerChatEvent = new PlayerChatEvent(player, Main.getConnectionManager().getOnlinePlayers(), message); + PlayerChatEvent playerChatEvent = new PlayerChatEvent(player, MinecraftServer.getConnectionManager().getOnlinePlayers(), message); // Default format playerChatEvent.setChatFormat((event) -> { diff --git a/src/main/java/fr/themode/minestom/net/ConnectionManager.java b/src/main/java/fr/themode/minestom/net/ConnectionManager.java index 8e179df61..a4f7fab86 100644 --- a/src/main/java/fr/themode/minestom/net/ConnectionManager.java +++ b/src/main/java/fr/themode/minestom/net/ConnectionManager.java @@ -5,12 +5,15 @@ import fr.themode.minestom.net.player.PlayerConnection; import java.util.*; import java.util.concurrent.CopyOnWriteArraySet; +import java.util.function.Consumer; public class ConnectionManager { private Set players = new CopyOnWriteArraySet<>(); private Map connectionPlayerMap = Collections.synchronizedMap(new HashMap<>()); + private Consumer playerInitialization; + public Player getPlayer(PlayerConnection connection) { return connectionPlayerMap.get(connection); } @@ -27,6 +30,14 @@ public class ConnectionManager { return null; } + public Consumer getPlayerInitialization() { + return playerInitialization; + } + + public void setPlayerInitialization(Consumer playerInitialization) { + this.playerInitialization = playerInitialization; + } + // Is only used at LoginStartPacket#process public void createPlayer(UUID uuid, String username, PlayerConnection connection) { Player player = new Player(uuid, username, connection); diff --git a/src/main/java/fr/themode/minestom/net/PacketProcessor.java b/src/main/java/fr/themode/minestom/net/PacketProcessor.java index 9c517b6b0..bc407a2ec 100644 --- a/src/main/java/fr/themode/minestom/net/PacketProcessor.java +++ b/src/main/java/fr/themode/minestom/net/PacketProcessor.java @@ -1,7 +1,7 @@ package fr.themode.minestom.net; import com.github.simplenet.Client; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.packet.PacketReader; import fr.themode.minestom.net.packet.client.ClientPlayPacket; @@ -29,7 +29,7 @@ public class PacketProcessor { private ClientPlayPacketsHandler playPacketsHandler; public PacketProcessor() { - this.connectionManager = Main.getConnectionManager(); + this.connectionManager = MinecraftServer.getConnectionManager(); this.statusPacketsHandler = new ClientStatusPacketsHandler(); this.loginPacketsHandler = new ClientLoginPacketsHandler(); diff --git a/src/main/java/fr/themode/minestom/net/PacketWriterUtils.java b/src/main/java/fr/themode/minestom/net/PacketWriterUtils.java index 5d185a5e5..e3ce4793e 100644 --- a/src/main/java/fr/themode/minestom/net/PacketWriterUtils.java +++ b/src/main/java/fr/themode/minestom/net/PacketWriterUtils.java @@ -1,7 +1,7 @@ package fr.themode.minestom.net; import com.github.simplenet.packet.Packet; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.player.PlayerConnection; @@ -14,7 +14,7 @@ import java.util.function.Consumer; public class PacketWriterUtils { - private static ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_PACKET_WRITER, "Ms-PacketWriterPool"); + private static ExecutorService batchesPool = new MinestomThread(MinecraftServer.THREAD_COUNT_PACKET_WRITER, "Ms-PacketWriterPool"); public static void writeCallbackPacket(ServerPacket serverPacket, Consumer consumer) { batchesPool.execute(() -> { diff --git a/src/main/java/fr/themode/minestom/net/packet/client/ClientPlayPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/ClientPlayPacket.java index 1220c63c8..dfe99476b 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/ClientPlayPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/ClientPlayPacket.java @@ -1,12 +1,12 @@ package fr.themode.minestom.net.packet.client; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.Player; public abstract class ClientPlayPacket implements ClientPacket { public void process(Player player) { - Main.getPacketListenerManager().process(this, player); + MinecraftServer.getPacketListenerManager().process(this, player); } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java index 617c3301d..a928be73b 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java @@ -1,6 +1,6 @@ package fr.themode.minestom.net.packet.client.login; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.GameMode; import fr.themode.minestom.entity.Player; import fr.themode.minestom.net.ConnectionManager; @@ -17,6 +17,7 @@ import fr.themode.minestom.world.Dimension; import fr.themode.minestom.world.LevelType; import java.util.UUID; +import java.util.function.Consumer; public class LoginStartPacket implements ClientPreplayPacket { @@ -59,7 +60,7 @@ public class LoginStartPacket implements ClientPreplayPacket { joinGamePacket.dimension = dimension; joinGamePacket.maxPlayers = 0; // Unused joinGamePacket.levelType = levelType; - joinGamePacket.viewDistance = Main.CHUNK_VIEW_DISTANCE; + joinGamePacket.viewDistance = MinecraftServer.CHUNK_VIEW_DISTANCE; joinGamePacket.reducedDebugInfo = false; connection.sendPacket(joinGamePacket); @@ -83,7 +84,11 @@ public class LoginStartPacket implements ClientPreplayPacket { playerInfoPacket.playerInfos.add(addPlayer); connection.sendPacket(playerInfoPacket); - Main.getEntityManager().addWaitingPlayer(player); + Consumer playerInitialization = MinecraftServer.getConnectionManager().getPlayerInitialization(); + if (playerInitialization != null) + playerInitialization.accept(player); + + MinecraftServer.getEntityManager().addWaitingPlayer(player); DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket(); DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); diff --git a/src/main/java/fr/themode/minestom/timer/SchedulerManager.java b/src/main/java/fr/themode/minestom/timer/SchedulerManager.java index 6c004ac8f..48f88503a 100644 --- a/src/main/java/fr/themode/minestom/timer/SchedulerManager.java +++ b/src/main/java/fr/themode/minestom/timer/SchedulerManager.java @@ -1,6 +1,6 @@ package fr.themode.minestom.timer; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.utils.thread.MinestomThread; import fr.themode.minestom.utils.time.CooldownUtils; import fr.themode.minestom.utils.time.UpdateOption; @@ -14,7 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class SchedulerManager { private static final AtomicInteger COUNTER = new AtomicInteger(); - private static ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_SCHEDULER, "Ms-SchedulerPool"); + private static ExecutorService batchesPool = new MinestomThread(MinecraftServer.THREAD_COUNT_SCHEDULER, "Ms-SchedulerPool"); private List tasks = new CopyOnWriteArrayList<>(); public int addTask(TaskRunnable runnable, UpdateOption updateOption, int maxCallCount) { diff --git a/src/main/java/fr/themode/minestom/utils/EntityUtils.java b/src/main/java/fr/themode/minestom/utils/EntityUtils.java index 4f945c4c7..fc3eddb93 100644 --- a/src/main/java/fr/themode/minestom/utils/EntityUtils.java +++ b/src/main/java/fr/themode/minestom/utils/EntityUtils.java @@ -1,6 +1,6 @@ package fr.themode.minestom.utils; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; import fr.themode.minestom.entity.Entity; import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Instance; @@ -15,7 +15,7 @@ public class EntityUtils { Chunk chunk = ent1.getInstance().getChunkAt(ent1.getPosition()); - long[] visibleChunksEntity = ChunkUtils.getChunksInRange(ent2.getPosition(), Main.ENTITY_VIEW_DISTANCE); + long[] visibleChunksEntity = ChunkUtils.getChunksInRange(ent2.getPosition(), MinecraftServer.ENTITY_VIEW_DISTANCE); for (long visibleChunk : visibleChunksEntity) { int[] chunkPos = ChunkUtils.getChunkCoord(visibleChunk); int chunkX = chunkPos[0]; diff --git a/src/main/java/fr/themode/minestom/utils/time/TimeUnit.java b/src/main/java/fr/themode/minestom/utils/time/TimeUnit.java index ec23d20e3..7f2ce62c1 100644 --- a/src/main/java/fr/themode/minestom/utils/time/TimeUnit.java +++ b/src/main/java/fr/themode/minestom/utils/time/TimeUnit.java @@ -1,6 +1,6 @@ package fr.themode.minestom.utils.time; -import fr.themode.minestom.Main; +import fr.themode.minestom.MinecraftServer; public enum TimeUnit { @@ -9,7 +9,7 @@ public enum TimeUnit { public long toMilliseconds(int value) { switch (this) { case TICK: - return Main.TICK_MS * value; + return MinecraftServer.TICK_MS * value; case SECOND: return value * 1000; case MILLISECOND: