mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 11:07:53 +01:00
General optimization
This commit is contained in:
parent
ce83ea05a3
commit
e8aa4bfe9e
19
build.gradle
19
build.gradle
@ -1,5 +1,6 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'net.ltgt.apt' version '0.10'
|
||||
}
|
||||
|
||||
group 'fr.themode.minestom'
|
||||
@ -12,12 +13,26 @@ repositories {
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
|
||||
def lombokDependency = 'org.projectlombok:lombok:1.18.2'
|
||||
|
||||
|
||||
dependencies {
|
||||
testCompile group: 'junit', name: 'junit', version: '4.12'
|
||||
|
||||
compileOnly lombokDependency
|
||||
|
||||
apt lombokDependency
|
||||
|
||||
// https://mvnrepository.com/artifact/com.github.jhg023/SimpleNet
|
||||
compile group: 'com.github.jhg023', name: 'SimpleNet', version: '1.5.1'
|
||||
// https://mvnrepository.com/artifact/it.unimi.dsi/fastutil
|
||||
compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.3.0'
|
||||
|
||||
compile 'com.github.Querz:NBT:4.1'
|
||||
implementation 'com.github.luben:zstd-jni:1.4.3-1'
|
||||
implementation 'com.esotericsoftware:reflectasm:1.11.9'
|
||||
implementation 'com.github.LynnOwens:starlite:9971b899f7'
|
||||
//implementation 'com.github.jhg023:SimpleNet:1.5.0'
|
||||
implementation 'com.github.jhg023:SimpleNet:97dbc4951e'
|
||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ import com.github.simplenet.Server;
|
||||
import fr.themode.minestom.data.DataManager;
|
||||
import fr.themode.minestom.entity.EntityManager;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.BlockManager;
|
||||
import fr.themode.minestom.instance.InstanceManager;
|
||||
import fr.themode.minestom.instance.block.BlockManager;
|
||||
import fr.themode.minestom.instance.demo.StoneBlock;
|
||||
import fr.themode.minestom.listener.PacketListenerManager;
|
||||
import fr.themode.minestom.net.ConnectionManager;
|
||||
@ -22,7 +22,6 @@ public class Main {
|
||||
// Thread number
|
||||
public static final int THREAD_COUNT_PACKET_WRITER = 2;
|
||||
public static final int THREAD_COUNT_IO = 2;
|
||||
public static final int THREAD_COUNT_CHUNK_BATCH = 2;
|
||||
public static final int THREAD_COUNT_BLOCK_BATCH = 2;
|
||||
public static final int THREAD_COUNT_ENTITIES = 2;
|
||||
public static final int THREAD_COUNT_PLAYERS_ENTITIES = 2;
|
||||
@ -64,7 +63,7 @@ public class Main {
|
||||
System.out.println("CONNECTION");
|
||||
|
||||
client.preDisconnect(() -> {
|
||||
System.out.println("A Disconnection");
|
||||
System.out.println("DISCONNECTION");
|
||||
PlayerConnection playerConnection = packetProcessor.getPlayerConnection(client);
|
||||
if (playerConnection != null) {
|
||||
playerConnection.refreshOnline(false);
|
||||
@ -115,6 +114,11 @@ public class Main {
|
||||
// Entities update
|
||||
entityManager.update();
|
||||
|
||||
// Blocks update
|
||||
blockManager.update();
|
||||
|
||||
// TODO miscellaneous update (scoreboard)
|
||||
|
||||
// Sleep until next tick
|
||||
long sleepTime = (tickDistance - (System.nanoTime() - currentTime)) / 1000000;
|
||||
sleepTime = Math.max(1, sleepTime);
|
||||
|
35
src/main/java/fr/themode/minestom/chat/ChatColor.java
Normal file
35
src/main/java/fr/themode/minestom/chat/ChatColor.java
Normal file
@ -0,0 +1,35 @@
|
||||
package fr.themode.minestom.chat;
|
||||
|
||||
import fr.themode.minestom.utils.HexUtils;
|
||||
|
||||
public enum ChatColor {
|
||||
|
||||
BLACK((byte) 0),
|
||||
DARK_BLUE((byte) 1),
|
||||
DARK_GREEN((byte) 2),
|
||||
DARK_AQUA((byte) 3),
|
||||
DARK_RED((byte) 4),
|
||||
DARK_PURPLE((byte) 5),
|
||||
GOLD((byte) 6),
|
||||
GRAY((byte) 7),
|
||||
DARK_GRAY((byte) 8),
|
||||
BLUE((byte) 9),
|
||||
GREEN((byte) 0xa),
|
||||
AQUA((byte) 0xb),
|
||||
RED((byte) 0xc),
|
||||
LIGHT_PURPLE((byte) 0xd),
|
||||
YELLOW((byte) 0xe),
|
||||
WHITE((byte) 0xf);
|
||||
|
||||
|
||||
private byte id;
|
||||
|
||||
ChatColor(byte id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Chat.COLOR_CHAR + String.valueOf(HexUtils.byteToHex(id));
|
||||
}
|
||||
}
|
@ -204,21 +204,20 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
|
||||
// Velocity
|
||||
if (velocityTime != 0) {
|
||||
if (this instanceof Player) {
|
||||
sendPacketToViewersAndSelf(getVelocityPacket());
|
||||
} else {
|
||||
float tps = Main.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());
|
||||
} else if (this instanceof EntityCreature) {
|
||||
teleport(getPosition());
|
||||
}
|
||||
}
|
||||
if (time >= velocityTime) {
|
||||
sendSynchronization(); // Send synchronization after velocity ended
|
||||
resetVelocity();
|
||||
} else {
|
||||
if (this instanceof Player) {
|
||||
sendPacketToViewersAndSelf(getVelocityPacket());
|
||||
} else {
|
||||
float tps = Main.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());
|
||||
} else if (this instanceof EntityCreature) {
|
||||
teleport(getPosition());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class ItemEntity extends ObjectEntity {
|
||||
super(34);
|
||||
this.itemStack = itemStack;
|
||||
setBoundingBox(0.25f, 0.25f, 0.25f);
|
||||
setGravity(0.02f);
|
||||
setGravity(0.025f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -153,8 +153,12 @@ public abstract class LivingEntity extends Entity {
|
||||
for (int i = 0; i < length; i++) {
|
||||
Attribute attribute = Attribute.values()[i];
|
||||
EntityPropertiesPacket.Property property = new EntityPropertiesPacket.Property();
|
||||
float maxValue = attribute.getMaxVanillaValue();
|
||||
float value = getAttributeValue(attribute);
|
||||
value = value > maxValue ? maxValue : value; // Bypass vanilla limit client-side if needed (by sending the max value allowed)
|
||||
|
||||
property.key = attribute.getKey();
|
||||
property.value = getAttributeValue(attribute);
|
||||
property.value = value;
|
||||
properties[i] = property;
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ import fr.themode.minestom.collision.BoundingBox;
|
||||
import fr.themode.minestom.entity.property.Attribute;
|
||||
import fr.themode.minestom.event.*;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.CustomBlock;
|
||||
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.PlayerInventory;
|
||||
@ -20,7 +20,6 @@ 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.Scoreboard;
|
||||
import fr.themode.minestom.utils.*;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
import fr.themode.minestom.world.LevelType;
|
||||
@ -145,7 +144,7 @@ public class Player extends LivingEntity {
|
||||
});
|
||||
|
||||
setEventCallback(PlayerSpawnEvent.class, event -> {
|
||||
setGameMode(GameMode.CREATIVE);
|
||||
setGameMode(GameMode.SURVIVAL);
|
||||
teleport(new Position(0, 66, 0));
|
||||
|
||||
/*Random random = new Random();
|
||||
@ -183,14 +182,12 @@ public class Player extends LivingEntity {
|
||||
setAttribute(Attribute.MAX_HEALTH, 10);
|
||||
heal();
|
||||
|
||||
setExp(0.9f);
|
||||
|
||||
Scoreboard scoreboard = new Scoreboard("Scoreboard Title");
|
||||
/*Scoreboard scoreboard = new Scoreboard("Scoreboard Title");
|
||||
for (int i = 0; i < 15; i++) {
|
||||
scoreboard.createLine(new Scoreboard.ScoreboardLine("id" + i, "Hey guys " + i, i));
|
||||
}
|
||||
scoreboard.addViewer(this);
|
||||
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED &2TEST");
|
||||
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED &2TEST");*/
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -2,22 +2,24 @@ package fr.themode.minestom.entity.property;
|
||||
|
||||
public enum Attribute {
|
||||
|
||||
MAX_HEALTH("generic.maxHealth", 20),
|
||||
FOLLOW_RANGE("generic.followRange", 32),
|
||||
KNOCKBACK_RESISTANCE("generic.knockbackResistance", 0),
|
||||
MOVEMENT_SPEED("generic.movementSpeed", 0.7f),
|
||||
ATTACK_DAMAGE("generic.attackDamage", 2),
|
||||
ATTACK_SPEED("generic.attackSpeed", 4),
|
||||
FLYING_SPEED("generic.flyingSpeed", 0.4f),
|
||||
HORSE_JUMP_STRENGTH("horse.jumpStrength", 0.7f),
|
||||
ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawnReinforcements", 0);
|
||||
MAX_HEALTH("generic.maxHealth", 20, 1024),
|
||||
FOLLOW_RANGE("generic.followRange", 32, 2048),
|
||||
KNOCKBACK_RESISTANCE("generic.knockbackResistance", 0, 1),
|
||||
MOVEMENT_SPEED("generic.movementSpeed", 0.7f, 1024),
|
||||
ATTACK_DAMAGE("generic.attackDamage", 2, 2048),
|
||||
ATTACK_SPEED("generic.attackSpeed", 4, 1024),
|
||||
FLYING_SPEED("generic.flyingSpeed", 0.4f, 1024),
|
||||
HORSE_JUMP_STRENGTH("horse.jumpStrength", 0.7f, 2),
|
||||
ZOMBIE_SPAWN_REINFORCEMENTS("zombie.spawnReinforcements", 0, 1);
|
||||
|
||||
private String key;
|
||||
private float defaultValue;
|
||||
private float maxVanillaValue;
|
||||
|
||||
Attribute(String key, float defaultValue) {
|
||||
Attribute(String key, float defaultValue, float maxVanillaValue) {
|
||||
this.key = key;
|
||||
this.defaultValue = defaultValue;
|
||||
this.maxVanillaValue = maxVanillaValue;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
@ -27,4 +29,8 @@ public enum Attribute {
|
||||
public float getDefaultValue() {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public float getMaxVanillaValue() {
|
||||
return maxVanillaValue;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package fr.themode.minestom.event;
|
||||
|
||||
import fr.themode.minestom.instance.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
|
||||
public class PlayerStartDiggingEvent extends CancellableEvent {
|
||||
|
||||
|
@ -3,7 +3,9 @@ package fr.themode.minestom.instance;
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.Viewable;
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
|
||||
import fr.themode.minestom.utils.PacketUtils;
|
||||
import fr.themode.minestom.utils.SerializerUtils;
|
||||
@ -14,7 +16,9 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
// TODO air management to free memory
|
||||
public class Chunk implements Viewable {
|
||||
|
||||
public static final int CHUNK_SIZE_X = 16;
|
||||
@ -30,6 +34,8 @@ public class Chunk implements Viewable {
|
||||
// Block entities
|
||||
private Set<Integer> blockEntities = new CopyOnWriteArraySet<>();
|
||||
|
||||
// TODO blocks update
|
||||
|
||||
// Cache
|
||||
private Set<Player> viewers = new CopyOnWriteArraySet<>();
|
||||
private Packet fullDataPacket;
|
||||
@ -42,16 +48,16 @@ public class Chunk implements Viewable {
|
||||
this.chunkZ = chunkZ;
|
||||
}
|
||||
|
||||
protected void setBlock(byte x, byte y, byte z, short blockId) {
|
||||
public void UNSAFE_setBlock(byte x, byte y, byte z, short blockId) {
|
||||
setBlock(x, y, z, blockId, (short) 0);
|
||||
}
|
||||
|
||||
protected void setCustomBlock(byte x, byte y, byte z, String blockId) {
|
||||
public void UNSAFE_setCustomBlock(byte x, byte y, byte z, String blockId) {
|
||||
CustomBlock customBlock = Main.getBlockManager().getBlock(blockId);
|
||||
if (customBlock == null)
|
||||
throw new IllegalArgumentException("The block " + blockId + " does not exist or isn't registered");
|
||||
|
||||
setBlock(x, y, z, customBlock.getType(), customBlock.getId());
|
||||
setCustomBlock(x, y, z, customBlock);
|
||||
}
|
||||
|
||||
protected void setCustomBlock(byte x, byte y, byte z, short customBlockId) {
|
||||
@ -59,7 +65,7 @@ public class Chunk implements Viewable {
|
||||
if (customBlock == null)
|
||||
throw new IllegalArgumentException("The custom block " + customBlockId + " does not exist or isn't registered");
|
||||
|
||||
setBlock(x, y, z, customBlock.getType(), customBlockId);
|
||||
setCustomBlock(x, y, z, customBlock);
|
||||
}
|
||||
|
||||
private void setBlock(byte x, byte y, byte z, short blockType, short customId) {
|
||||
@ -74,6 +80,14 @@ public class Chunk implements Viewable {
|
||||
this.packetUpdated = false;
|
||||
}
|
||||
|
||||
private void setCustomBlock(byte x, byte y, byte z, CustomBlock customBlock) {
|
||||
if (customBlock.hasUpdate()) {
|
||||
Consumer<Data> test = customBlock::update;
|
||||
// TODO add update callback
|
||||
}
|
||||
setBlock(x, y, z, customBlock.getType(), customBlock.getId());
|
||||
}
|
||||
|
||||
public short getBlockId(byte x, byte y, byte z) {
|
||||
return this.blocksId[SerializerUtils.chunkCoordToIndex(x, y, z)];
|
||||
}
|
||||
@ -83,6 +97,17 @@ public class Chunk implements Viewable {
|
||||
return id != 0 ? Main.getBlockManager().getBlock(id) : null;
|
||||
}
|
||||
|
||||
public void updateBlocks() {
|
||||
/**
|
||||
* TODO blocks' update:
|
||||
* - get all custom blocks
|
||||
* - check if they have an update method
|
||||
* - check if they should be updated
|
||||
* - get custom block's data
|
||||
* - call update method
|
||||
*/
|
||||
}
|
||||
|
||||
public Biome getBiome() {
|
||||
return biome;
|
||||
}
|
||||
@ -110,6 +135,7 @@ public class Chunk implements Viewable {
|
||||
|
||||
public void setFullDataPacket(Packet fullDataPacket) {
|
||||
this.fullDataPacket = fullDataPacket;
|
||||
this.packetUpdated = true;
|
||||
}
|
||||
|
||||
protected byte[] getSerializedData() throws IOException {
|
||||
@ -153,10 +179,9 @@ public class Chunk implements Viewable {
|
||||
}
|
||||
|
||||
// Write the packet in the current thread
|
||||
protected void refreshDataPacket() {
|
||||
public void refreshDataPacket() {
|
||||
PacketUtils.writePacket(getFreshFullDataPacket(), packet -> {
|
||||
fullDataPacket = packet;
|
||||
packetUpdated = true;
|
||||
setFullDataPacket(packet);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.themode.minestom.instance;
|
||||
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
|
||||
public abstract class ChunkGenerator {
|
||||
|
||||
public abstract void generateChunkData(ChunkBatch batch, int chunkX, int chunkZ);
|
||||
|
@ -69,7 +69,7 @@ public class ChunkLoaderIO {
|
||||
if (isCustomBlock) {
|
||||
chunk.setCustomBlock(chunkPos[0], chunkPos[1], chunkPos[2], blockId);
|
||||
} else {
|
||||
chunk.setBlock(chunkPos[0], chunkPos[1], chunkPos[2], blockId);
|
||||
chunk.UNSAFE_setBlock(chunkPos[0], chunkPos[1], chunkPos[2], blockId);
|
||||
}
|
||||
}
|
||||
} catch (EOFException e) {
|
||||
|
@ -3,6 +3,9 @@ package fr.themode.minestom.instance;
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.entity.*;
|
||||
import fr.themode.minestom.instance.batch.BlockBatch;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.net.PacketWriterUtils;
|
||||
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
|
@ -3,6 +3,8 @@ package fr.themode.minestom.instance;
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.event.PlayerBlockBreakEvent;
|
||||
import fr.themode.minestom.instance.batch.BlockBatch;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
import fr.themode.minestom.net.PacketWriterUtils;
|
||||
import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ParticlePacket;
|
||||
@ -41,7 +43,7 @@ public class InstanceContainer extends Instance {
|
||||
byte chunkX = (byte) (x % 16);
|
||||
byte chunkY = (byte) y;
|
||||
byte chunkZ = (byte) (z % 16);
|
||||
chunk.setBlock(chunkX, chunkY, chunkZ, blockId);
|
||||
chunk.UNSAFE_setBlock(chunkX, chunkY, chunkZ, blockId);
|
||||
sendBlockChange(chunk, x, y, z, blockId);
|
||||
}
|
||||
}
|
||||
@ -53,7 +55,7 @@ public class InstanceContainer extends Instance {
|
||||
byte chunkX = (byte) (x % 16);
|
||||
byte chunkY = (byte) y;
|
||||
byte chunkZ = (byte) (z % 16);
|
||||
chunk.setCustomBlock(chunkX, chunkY, chunkZ, blockId);
|
||||
chunk.UNSAFE_setCustomBlock(chunkX, chunkY, chunkZ, blockId);
|
||||
short id = chunk.getBlockId(chunkX, chunkY, chunkZ);
|
||||
sendBlockChange(chunk, x, y, z, id);
|
||||
}
|
||||
@ -199,7 +201,6 @@ public class InstanceContainer extends Instance {
|
||||
if (data == null || !chunk.packetUpdated) {
|
||||
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
|
||||
chunk.setFullDataPacket(buffer);
|
||||
chunk.packetUpdated = true;
|
||||
sendChunkUpdate(player, chunk);
|
||||
});
|
||||
} else {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package fr.themode.minestom.instance;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.batch.BlockBatch;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -1,17 +1,15 @@
|
||||
package fr.themode.minestom.instance;
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
import fr.themode.minestom.instance.BlockModifier;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.InstanceContainer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public class BlockBatch implements BlockModifier {
|
||||
|
||||
private static final ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_BLOCK_BATCH, "Ms-BlockBatchPool");
|
||||
public class BlockBatch implements IBatch, BlockModifier {
|
||||
|
||||
private InstanceContainer instance;
|
||||
|
||||
@ -85,9 +83,9 @@ public class BlockBatch implements BlockModifier {
|
||||
|
||||
public void apply(Chunk chunk) {
|
||||
if (blockIdentifier == null) {
|
||||
chunk.setBlock((byte) x, (byte) y, (byte) z, blockId);
|
||||
chunk.UNSAFE_setBlock((byte) x, (byte) y, (byte) z, blockId);
|
||||
} else {
|
||||
chunk.setCustomBlock((byte) x, (byte) y, (byte) z, blockIdentifier);
|
||||
chunk.UNSAFE_setCustomBlock((byte) x, (byte) y, (byte) z, blockIdentifier);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,18 @@
|
||||
package fr.themode.minestom.instance;
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
import fr.themode.minestom.instance.BlockModifier;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.ChunkGenerator;
|
||||
import fr.themode.minestom.instance.InstanceContainer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Use chunk coordinate (0-16) instead of world's
|
||||
*/
|
||||
public class ChunkBatch implements BlockModifier {
|
||||
|
||||
private static final ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_CHUNK_BATCH, "Ms-ChunkBatchPool");
|
||||
public class ChunkBatch implements IBatch, BlockModifier {
|
||||
|
||||
private InstanceContainer instance;
|
||||
private Chunk chunk;
|
||||
@ -82,9 +81,9 @@ public class ChunkBatch implements BlockModifier {
|
||||
|
||||
public void apply(Chunk chunk) {
|
||||
if (blockIdentifier == null) {
|
||||
chunk.setBlock(x, y, z, blockId);
|
||||
chunk.UNSAFE_setBlock(x, y, z, blockId);
|
||||
} else {
|
||||
chunk.setCustomBlock(x, y, z, blockIdentifier);
|
||||
chunk.UNSAFE_setCustomBlock(x, y, z, blockIdentifier);
|
||||
}
|
||||
}
|
||||
|
12
src/main/java/fr/themode/minestom/instance/batch/IBatch.java
Normal file
12
src/main/java/fr/themode/minestom/instance/batch/IBatch.java
Normal file
@ -0,0 +1,12 @@
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public interface IBatch {
|
||||
|
||||
ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_BLOCK_BATCH, "Ms-BlockBatchPool");
|
||||
|
||||
}
|
@ -1,4 +1,9 @@
|
||||
package fr.themode.minestom.instance;
|
||||
package fr.themode.minestom.instance.block;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.InstanceManager;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@ -6,6 +11,8 @@ import java.util.function.Supplier;
|
||||
|
||||
public class BlockManager {
|
||||
|
||||
private static InstanceManager instanceManager = Main.getInstanceManager();
|
||||
|
||||
private Map<Short, CustomBlock> blocksInternalId = new HashMap<>();
|
||||
private Map<String, CustomBlock> blocksId = new HashMap<>();
|
||||
|
||||
@ -17,6 +24,15 @@ public class BlockManager {
|
||||
this.blocksId.put(identifier, customBlock);
|
||||
}
|
||||
|
||||
public void update() {
|
||||
for (Instance instance : instanceManager.getInstances()) {
|
||||
// TODO only InstanceContainer?
|
||||
for (Chunk chunk : instance.getChunks()) {
|
||||
chunk.updateBlocks();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CustomBlock getBlock(String identifier) {
|
||||
return blocksId.get(identifier);
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package fr.themode.minestom.instance;
|
||||
package fr.themode.minestom.instance.block;
|
||||
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
@ -18,6 +19,12 @@ public abstract class CustomBlock {
|
||||
this.id = (short) idCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
public void update(Data data) {
|
||||
throw new UnsupportedOperationException("Update method not overriden");
|
||||
}
|
||||
|
||||
public abstract UpdateOption getUpdateOption();
|
||||
|
||||
public abstract short getType();
|
||||
|
||||
public abstract String getIdentifier();
|
||||
@ -27,6 +34,10 @@ public abstract class CustomBlock {
|
||||
*/
|
||||
public abstract int getBreakDelay(Player player);
|
||||
|
||||
public boolean hasUpdate() {
|
||||
return getUpdateOption().getValue() > 0;
|
||||
}
|
||||
|
||||
public short getId() {
|
||||
return id;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package fr.themode.minestom.instance.block;
|
||||
|
||||
import fr.themode.minestom.timer.TimeUnit;
|
||||
|
||||
public class UpdateOption {
|
||||
|
||||
private int value;
|
||||
private TimeUnit timeUnit;
|
||||
|
||||
public UpdateOption(int value, TimeUnit timeUnit) {
|
||||
this.value = value;
|
||||
this.timeUnit = timeUnit;
|
||||
}
|
||||
|
||||
public UpdateOption() {
|
||||
this(0, null);
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public TimeUnit getTimeUnit() {
|
||||
return timeUnit;
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package fr.themode.minestom.instance.demo;
|
||||
|
||||
import fr.themode.minestom.instance.Biome;
|
||||
import fr.themode.minestom.instance.ChunkBatch;
|
||||
import fr.themode.minestom.instance.ChunkGenerator;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
@ -1,10 +1,25 @@
|
||||
package fr.themode.minestom.instance.demo;
|
||||
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.UpdateOption;
|
||||
import fr.themode.minestom.timer.TimeUnit;
|
||||
|
||||
public class StoneBlock extends CustomBlock {
|
||||
|
||||
private static final UpdateOption UPDATE_OPTION = new UpdateOption(1, TimeUnit.TICK);
|
||||
|
||||
@Override
|
||||
public UpdateOption getUpdateOption() {
|
||||
return UPDATE_OPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Data data) {
|
||||
System.out.println("BLOCK HAS BEEN UPDATED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public short getType() {
|
||||
return 1;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.themode.minestom.listener;
|
||||
|
||||
import fr.themode.minestom.entity.GameMode;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.event.PlayerBlockPlaceEvent;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
@ -37,6 +38,8 @@ public class BlockPlacementListener {
|
||||
boolean intersectPlayer = player.getBoundingBox().intersect(blockPosition); // TODO check if collide with nearby players
|
||||
if (!intersectPlayer) {
|
||||
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent((short) 10, blockPosition, packet.hand);
|
||||
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
|
||||
|
||||
player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
|
||||
if (!playerBlockPlaceEvent.isCancelled()) {
|
||||
instance.setBlock(blockPosition, "custom_block"); // TODO set useItem's block instead
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.themode.minestom.listener;
|
||||
|
||||
import fr.themode.minestom.chat.ChatColor;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientKeepAlivePacket;
|
||||
|
||||
@ -7,7 +8,7 @@ public class KeepAliveListener {
|
||||
|
||||
public static void listener(ClientKeepAlivePacket packet, Player player) {
|
||||
if (packet.id != player.getLastKeepAlive()) {
|
||||
player.kick("Bad Keep Alive packet");
|
||||
player.kick(ChatColor.RED + "Bad Keep Alive packet");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,8 @@ import fr.themode.minestom.entity.ItemEntity;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.event.ItemDropEvent;
|
||||
import fr.themode.minestom.event.PlayerStartDiggingEvent;
|
||||
import fr.themode.minestom.instance.CustomBlock;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPlayerDiggingPacket;
|
||||
|
21
src/main/java/fr/themode/minestom/timer/TimeUnit.java
Normal file
21
src/main/java/fr/themode/minestom/timer/TimeUnit.java
Normal file
@ -0,0 +1,21 @@
|
||||
package fr.themode.minestom.timer;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
|
||||
public enum TimeUnit {
|
||||
|
||||
TICK, MILLISECOND, SECOND;
|
||||
|
||||
public long toMilliseconds(int value) {
|
||||
switch (this) {
|
||||
case TICK:
|
||||
return Main.TICK_MS * value;
|
||||
case SECOND:
|
||||
return value * 1000;
|
||||
case MILLISECOND:
|
||||
return value;
|
||||
}
|
||||
return -1; // Unexpected
|
||||
}
|
||||
|
||||
}
|
13
src/main/java/fr/themode/minestom/utils/HexUtils.java
Normal file
13
src/main/java/fr/themode/minestom/utils/HexUtils.java
Normal file
@ -0,0 +1,13 @@
|
||||
package fr.themode.minestom.utils;
|
||||
|
||||
public class HexUtils {
|
||||
|
||||
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
|
||||
|
||||
public static char byteToHex(byte b) {
|
||||
int v = b & 0xFF;
|
||||
char hexChar = HEX_ARRAY[v >>> 4];
|
||||
return hexChar;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user