mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 11:07:53 +01:00
1.15.2 update
This commit is contained in:
parent
c66020a196
commit
b1b41afebb
@ -24,7 +24,7 @@ dependencies {
|
||||
apt lombokDependency
|
||||
|
||||
// https://mvnrepository.com/artifact/com.github.jhg023/SimpleNet
|
||||
compile group: 'com.github.jhg023', name: 'SimpleNet', version: '1.5.1'
|
||||
compile group: 'com.github.jhg023', name: 'SimpleNet', version: '1.6.2'
|
||||
// https://mvnrepository.com/artifact/it.unimi.dsi/fastutil
|
||||
compile group: 'it.unimi.dsi', name: 'fastutil', version: '8.3.0'
|
||||
|
||||
|
@ -32,9 +32,9 @@ public class Main {
|
||||
public static final int THREAD_COUNT_SCHEDULER = 2;
|
||||
|
||||
// Can be modified at performance cost when decreased
|
||||
public static final int TICK_MS = 50;
|
||||
|
||||
public static final int TICK_PER_SECOND = 1000 / TICK_MS;
|
||||
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;
|
||||
@ -69,7 +69,8 @@ public class Main {
|
||||
blockManager.registerBlock(new StoneBlock());
|
||||
blockManager.registerBlock(new UpdatableBlockDemo());
|
||||
|
||||
server = new Server(136434);
|
||||
server = new Server();
|
||||
//server = new Server(136434);
|
||||
|
||||
server.onConnect(client -> {
|
||||
System.out.println("CONNECTION");
|
||||
@ -105,17 +106,17 @@ public class Main {
|
||||
});
|
||||
});
|
||||
|
||||
server.bind("localhost", 25565);
|
||||
server.bind("localhost", 55555);
|
||||
System.out.println("Server started");
|
||||
|
||||
long tickDistance = TICK_MS * 1000000;
|
||||
final long tickDistance = TICK_MS * 1000000;
|
||||
long currentTime;
|
||||
while (true) {
|
||||
currentTime = System.nanoTime();
|
||||
|
||||
// Keep Alive Handling
|
||||
for (Player player : getConnectionManager().getOnlinePlayers()) {
|
||||
long time = System.currentTimeMillis();
|
||||
long time = currentTime / 1_000_000;
|
||||
if (time - player.getLastKeepAlive() > 20000) {
|
||||
player.refreshKeepAlive(time);
|
||||
KeepAlivePacket keepAlivePacket = new KeepAlivePacket(time);
|
||||
|
@ -33,6 +33,13 @@ public class Data {
|
||||
return (T) data.getOrDefault(key, defaultValue);
|
||||
}
|
||||
|
||||
public Data clone() {
|
||||
Data data = new Data();
|
||||
data.data = new ConcurrentHashMap<>(this.data);
|
||||
data.dataType = new ConcurrentHashMap<>(dataType);
|
||||
return data;
|
||||
}
|
||||
|
||||
public byte[] getSerializedData() throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
DataOutputStream dos = new DataOutputStream(output);
|
||||
|
@ -183,12 +183,12 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
public void tick(long time) {
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
if (scheduledRemoveTime != 0) { // Any entity with scheduled remove does not update
|
||||
boolean finished = System.currentTimeMillis() >= scheduledRemoveTime;
|
||||
boolean finished = time >= scheduledRemoveTime;
|
||||
if (finished) {
|
||||
remove();
|
||||
}
|
||||
@ -198,8 +198,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
if (shouldRemove()) {
|
||||
remove();
|
||||
return;
|
||||
} else if (shouldUpdate()) {
|
||||
long time = System.currentTimeMillis();
|
||||
} else if (shouldUpdate(time)) {
|
||||
this.lastUpdate = time;
|
||||
|
||||
// Velocity
|
||||
@ -207,7 +206,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
if (this instanceof Player) {
|
||||
sendPacketToViewersAndSelf(getVelocityPacket());
|
||||
} else {
|
||||
float tps = Main.TICK_PER_SECOND;
|
||||
final 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());
|
||||
@ -256,7 +255,7 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
|
||||
// Scheduled synchronization
|
||||
if (time - lastSynchronizationTime >= synchronizationDelay) {
|
||||
lastSynchronizationTime = System.currentTimeMillis();
|
||||
lastSynchronizationTime = time;
|
||||
sendSynchronization();
|
||||
}
|
||||
}
|
||||
@ -669,8 +668,8 @@ public abstract class Entity implements Viewable, DataContainer {
|
||||
sendPacketToViewers(getPassengersPacket());
|
||||
}
|
||||
|
||||
private boolean shouldUpdate() {
|
||||
return (float) (System.currentTimeMillis() - lastUpdate) >= Main.TICK_MS * 0.9f; // Margin of error
|
||||
private boolean shouldUpdate(long time) {
|
||||
return (float) (time - lastUpdate) >= Main.TICK_MS * 0.9f; // Margin of error
|
||||
}
|
||||
|
||||
public enum Pose {
|
||||
|
@ -88,15 +88,21 @@ public abstract class EntityCreature extends LivingEntity {
|
||||
|
||||
EntityPacket entityPacket = new EntityPacket();
|
||||
entityPacket.entityId = getEntityId();
|
||||
|
||||
SpawnMobPacket spawnMobPacket = new SpawnMobPacket();
|
||||
spawnMobPacket.entityId = getEntityId();
|
||||
spawnMobPacket.entityUuid = getUuid();
|
||||
spawnMobPacket.entityType = getEntityType();
|
||||
spawnMobPacket.position = getPosition();
|
||||
spawnMobPacket.headPitch = 0;
|
||||
spawnMobPacket.consumer = getMetadataConsumer();
|
||||
|
||||
EntityMetaDataPacket entityMetaDataPacket = new EntityMetaDataPacket();
|
||||
entityMetaDataPacket.entityId = getEntityId();
|
||||
entityMetaDataPacket.consumer = getMetadataConsumer();
|
||||
|
||||
playerConnection.sendPacket(entityPacket);
|
||||
playerConnection.sendPacket(spawnMobPacket);
|
||||
playerConnection.sendPacket(entityMetaDataPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,9 +21,11 @@ public class EntityManager {
|
||||
private ConcurrentLinkedQueue<Player> waitingPlayers = new ConcurrentLinkedQueue<>();
|
||||
|
||||
public void update() {
|
||||
final long time = System.currentTimeMillis();
|
||||
|
||||
waitingPlayersTick();
|
||||
for (Instance instance : instanceManager.getInstances()) {
|
||||
testTick2(instance);
|
||||
testTick2(instance, time);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,21 +44,21 @@ public class EntityManager {
|
||||
}
|
||||
|
||||
// TODO optimize for when there are too many entities on one chunk
|
||||
private void testTick2(Instance instance) {
|
||||
private void testTick2(Instance instance, long time) {
|
||||
for (Chunk chunk : instance.getChunks()) {
|
||||
Set<Entity> entities = instance.getChunkEntities(chunk);
|
||||
|
||||
if (!entities.isEmpty()) {
|
||||
entitiesPool.execute(() -> {
|
||||
for (Entity entity : entities) {
|
||||
entity.tick();
|
||||
entity.tick(time);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void testTick1(Instance instance) {
|
||||
private void testTick1(Instance instance, long time) {
|
||||
Set<ObjectEntity> objects = instance.getObjectEntities();
|
||||
Set<EntityCreature> creatures = instance.getCreatures();
|
||||
Set<Player> players = instance.getPlayers();
|
||||
@ -64,10 +66,10 @@ public class EntityManager {
|
||||
if (!creatures.isEmpty() || !objects.isEmpty()) {
|
||||
entitiesPool.execute(() -> {
|
||||
for (EntityCreature creature : creatures) {
|
||||
creature.tick();
|
||||
creature.tick(time);
|
||||
}
|
||||
for (ObjectEntity objectEntity : objects) {
|
||||
objectEntity.tick();
|
||||
objectEntity.tick(time);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -75,7 +77,7 @@ public class EntityManager {
|
||||
if (!players.isEmpty()) {
|
||||
playersPool.execute(() -> {
|
||||
for (Player player : players) {
|
||||
player.tick();
|
||||
player.tick(time);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -82,6 +82,8 @@ public abstract class LivingEntity extends Entity {
|
||||
activeHandValue += 4;
|
||||
}
|
||||
packet.putByte(activeHandValue);
|
||||
|
||||
// TODO all remaining metadata
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import com.google.gson.JsonObject;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.bossbar.BossBar;
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.chat.ChatColor;
|
||||
import fr.themode.minestom.collision.BoundingBox;
|
||||
import fr.themode.minestom.entity.property.Attribute;
|
||||
import fr.themode.minestom.event.*;
|
||||
@ -23,7 +22,6 @@ 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.scoreboard.TeamManager;
|
||||
import fr.themode.minestom.utils.*;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
import fr.themode.minestom.world.LevelType;
|
||||
@ -180,7 +178,7 @@ public class Player extends LivingEntity {
|
||||
getInventory().addItemStack(new ItemStack(1, (byte) 75));
|
||||
//getInventory().addItemStack(new ItemStack(1, (byte) 100));
|
||||
|
||||
TeamManager teamManager = Main.getTeamManager();
|
||||
/*TeamManager teamManager = Main.getTeamManager();
|
||||
Team team = teamManager.createTeam(getUsername());
|
||||
team.setTeamDisplayName("display");
|
||||
team.setPrefix("[Test] ");
|
||||
@ -190,16 +188,16 @@ public class Player extends LivingEntity {
|
||||
setAttribute(Attribute.MAX_HEALTH, 10);
|
||||
heal();
|
||||
|
||||
/*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");
|
||||
|
||||
BelowNameScoreboard belowNameScoreboard = new BelowNameScoreboard();
|
||||
setBelowNameScoreboard(belowNameScoreboard);
|
||||
belowNameScoreboard.updateScore(this, 50);
|
||||
belowNameScoreboard.updateScore(this, 50);*/
|
||||
});
|
||||
}
|
||||
|
||||
@ -209,7 +207,7 @@ public class Player extends LivingEntity {
|
||||
// Flush all pending packets
|
||||
playerConnection.flush();
|
||||
|
||||
// Process sent packets
|
||||
// Process received packets
|
||||
ClientPlayPacket packet;
|
||||
while ((packet = packets.poll()) != null) {
|
||||
packet.process(this);
|
||||
@ -358,7 +356,7 @@ public class Player extends LivingEntity {
|
||||
spawnPlayerPacket.position = getPosition();
|
||||
|
||||
PlayerInfoPacket pInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||
PlayerInfoPacket.AddPlayer addP = new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer addP = new PlayerInfoPacket.AddPlayer(getUuid(), getUsername(), getGameMode(), 10);
|
||||
PlayerInfoPacket.AddPlayer.Property p = new PlayerInfoPacket.AddPlayer.Property("textures", property);//new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(onlinePlayer.getUsername()));
|
||||
addP.properties.add(p);
|
||||
pInfoPacket.playerInfos.add(addP);
|
||||
|
@ -189,8 +189,8 @@ public class Chunk implements Viewable {
|
||||
// Update cooldown
|
||||
UpdateOption updateOption = customBlock.getUpdateOption();
|
||||
long lastUpdate = updatableBlocksLastUpdate.get(index);
|
||||
boolean shouldUpdate = !CooldownUtils.hasCooldown(time, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
if (!shouldUpdate)
|
||||
boolean hasCooldown = CooldownUtils.hasCooldown(time, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
if (hasCooldown)
|
||||
continue;
|
||||
|
||||
this.updatableBlocksLastUpdate.put(index, time); // Refresh last update time
|
||||
@ -242,9 +242,6 @@ public class Chunk implements Viewable {
|
||||
DataOutputStream dos = new DataOutputStream(output);
|
||||
dos.writeByte(biome.getId());
|
||||
|
||||
// TODO customblock id map (StringId -> short id)
|
||||
// TODO List of (sectionId;blockcount;blocktype;blockarray)
|
||||
// TODO block data
|
||||
for (Int2IntMap.Entry entry : blocks.int2IntEntrySet()) {
|
||||
int index = entry.getIntKey();
|
||||
int value = entry.getIntValue();
|
||||
|
@ -3,6 +3,7 @@ package fr.themode.minestom.instance;
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.data.DataContainer;
|
||||
import fr.themode.minestom.entity.*;
|
||||
import fr.themode.minestom.instance.batch.BlockBatch;
|
||||
import fr.themode.minestom.instance.batch.ChunkBatch;
|
||||
@ -20,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class Instance implements BlockModifier {
|
||||
public abstract class Instance implements BlockModifier, DataContainer {
|
||||
|
||||
protected static final ChunkLoaderIO CHUNK_LOADER_IO = new ChunkLoaderIO();
|
||||
protected static final BlockManager BLOCK_MANAGER = Main.getBlockManager();
|
||||
@ -34,6 +35,8 @@ public abstract class Instance implements BlockModifier {
|
||||
protected Map<Long, Set<Entity>> chunkEntities = new ConcurrentHashMap<>();
|
||||
private UUID uniqueId;
|
||||
|
||||
private Data data;
|
||||
|
||||
protected Instance(UUID uniqueId) {
|
||||
this.uniqueId = uniqueId;
|
||||
}
|
||||
@ -49,7 +52,9 @@ public abstract class Instance implements BlockModifier {
|
||||
|
||||
public abstract Chunk getChunk(int chunkX, int chunkZ);
|
||||
|
||||
public abstract void saveToFolder(Runnable callback);
|
||||
public abstract void saveChunkToFolder(Chunk chunk, Runnable callback);
|
||||
|
||||
public abstract void saveChunksToFolder(Runnable callback);
|
||||
|
||||
public abstract BlockBatch createBlockBatch();
|
||||
|
||||
@ -171,14 +176,28 @@ public abstract class Instance implements BlockModifier {
|
||||
return getChunkAt(position.getX(), position.getZ());
|
||||
}
|
||||
|
||||
public void saveToFolder() {
|
||||
saveToFolder(null);
|
||||
public void saveChunkToFolder(Chunk chunk) {
|
||||
saveChunkToFolder(chunk, null);
|
||||
}
|
||||
|
||||
public void saveChunksToFolder() {
|
||||
saveChunksToFolder(null);
|
||||
}
|
||||
|
||||
public UUID getUniqueId() {
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
// UNSAFE METHODS (need most of time to be synchronized)
|
||||
|
||||
public void addEntity(Entity entity) {
|
||||
|
@ -89,11 +89,11 @@ public class InstanceContainer extends Instance {
|
||||
particlePacket.x = x + 0.5f;
|
||||
particlePacket.y = y;
|
||||
particlePacket.z = z + 0.5f;
|
||||
particlePacket.offsetX = 0.45f;
|
||||
particlePacket.offsetY = 0.55f;
|
||||
particlePacket.offsetZ = 0.45f;
|
||||
particlePacket.offsetX = 0.4f;
|
||||
particlePacket.offsetY = 0.5f;
|
||||
particlePacket.offsetZ = 0.4f;
|
||||
particlePacket.particleData = 0.3f;
|
||||
particlePacket.particleCount = 100;
|
||||
particlePacket.particleCount = 125;
|
||||
particlePacket.blockId = blockId;
|
||||
chunk.sendPacketToViewers(particlePacket);
|
||||
} else {
|
||||
@ -133,7 +133,12 @@ public class InstanceContainer extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToFolder(Runnable callback) {
|
||||
public void saveChunkToFolder(Chunk chunk, Runnable callback) {
|
||||
CHUNK_LOADER_IO.saveChunk(chunk, getFolder(), callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunksToFolder(Runnable callback) {
|
||||
if (folder == null)
|
||||
throw new UnsupportedOperationException("You cannot save an instance without setting a folder.");
|
||||
|
||||
@ -141,7 +146,7 @@ public class InstanceContainer extends Instance {
|
||||
while (chunks.hasNext()) {
|
||||
Chunk chunk = chunks.next();
|
||||
boolean isLast = !chunks.hasNext();
|
||||
CHUNK_LOADER_IO.saveChunk(chunk, getFolder(), isLast ? callback : null);
|
||||
saveChunkToFolder(chunk, isLast ? callback : null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,8 +209,8 @@ public class InstanceContainer extends Instance {
|
||||
public void sendChunk(Player player, Chunk chunk) {
|
||||
Packet data = chunk.getFullDataPacket();
|
||||
if (data == null || !chunk.packetUpdated) {
|
||||
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
|
||||
chunk.setFullDataPacket(buffer);
|
||||
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), packet -> {
|
||||
chunk.setFullDataPacket(packet);
|
||||
sendChunkUpdate(player, chunk);
|
||||
});
|
||||
} else {
|
||||
|
@ -44,8 +44,13 @@ public class SharedInstance extends Instance {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveToFolder(Runnable callback) {
|
||||
instanceContainer.saveToFolder(callback);
|
||||
public void saveChunkToFolder(Chunk chunk, Runnable callback) {
|
||||
instanceContainer.saveChunkToFolder(chunk, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveChunksToFolder(Runnable callback) {
|
||||
instanceContainer.saveChunksToFolder(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -23,18 +23,7 @@ public class BlockBatch implements IBatch {
|
||||
public void setBlock(int x, int y, int z, short blockId, Data data) {
|
||||
synchronized (this) {
|
||||
Chunk chunk = this.instance.getChunkAt(x, z);
|
||||
List<BlockData> blocksData = this.data.getOrDefault(chunk, new ArrayList<>());
|
||||
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = x % 16;
|
||||
blockData.y = y;
|
||||
blockData.z = z % 16;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
blocksData.add(blockData);
|
||||
|
||||
this.data.put(chunk, blocksData);
|
||||
addBlockData(chunk, x, y, z, false, blockId, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,22 +31,28 @@ public class BlockBatch implements IBatch {
|
||||
public void setCustomBlock(int x, int y, int z, short blockId, Data data) {
|
||||
synchronized (this) {
|
||||
Chunk chunk = this.instance.getChunkAt(x, z);
|
||||
List<BlockData> blocksData = this.data.getOrDefault(chunk, new ArrayList<>());
|
||||
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = x % 16;
|
||||
blockData.y = y;
|
||||
blockData.z = z % 16;
|
||||
blockData.isCustomBlock = true;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
blocksData.add(blockData);
|
||||
|
||||
this.data.put(chunk, blocksData);
|
||||
addBlockData(chunk, x, y, z, true, blockId, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void addBlockData(Chunk chunk, int x, int y, int z, boolean customBlock, short blockId, Data data) {
|
||||
List<BlockData> blocksData = this.data.get(chunk);
|
||||
if (blocksData == null)
|
||||
blocksData = new ArrayList<>();
|
||||
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = x % 16;
|
||||
blockData.y = y;
|
||||
blockData.z = z % 16;
|
||||
blockData.isCustomBlock = customBlock;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
blocksData.add(blockData);
|
||||
|
||||
this.data.put(chunk, blocksData);
|
||||
}
|
||||
|
||||
public void flush(Runnable callback) {
|
||||
int counter = 0;
|
||||
for (Map.Entry<Chunk, List<BlockData>> entry : data.entrySet()) {
|
||||
|
@ -27,24 +27,20 @@ public class ChunkBatch implements IBatch {
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, short blockId, Data data) {
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = (byte) x;
|
||||
blockData.y = (byte) y;
|
||||
blockData.z = (byte) z;
|
||||
blockData.isCustomBlock = false;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
this.dataList.add(blockData);
|
||||
addBlockData((byte) x, (byte) y, (byte) z, false, blockId, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomBlock(int x, int y, int z, short blockId, Data data) {
|
||||
addBlockData((byte) x, (byte) y, (byte) z, true, blockId, data);
|
||||
}
|
||||
|
||||
private void addBlockData(byte x, byte y, byte z, boolean customBlock, short blockId, Data data) {
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = (byte) x;
|
||||
blockData.y = (byte) y;
|
||||
blockData.z = (byte) z;
|
||||
blockData.isCustomBlock = true;
|
||||
blockData.x = x;
|
||||
blockData.y = y;
|
||||
blockData.z = z;
|
||||
blockData.isCustomBlock = customBlock;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
|
@ -309,7 +309,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler
|
||||
|
||||
if (!cursorItem.isAir()) {
|
||||
if (slot == 0 || slot == 6 || slot == 7 || slot == 8) {
|
||||
return; // Disable putting item on CRAFTING_RESULT and chestplate/leggings/boots slots
|
||||
return; // Disable putting item on CRAFTING_RESULT and on helmet/chestplate/leggings/boots slots
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,9 @@ public class ItemStack implements DataContainer {
|
||||
ItemStack itemStack = new ItemStack(material, amount, damage);
|
||||
itemStack.setDisplayName(displayName);
|
||||
itemStack.setUnbreakable(unbreakable);
|
||||
itemStack.setData(getData());
|
||||
Data data = getData();
|
||||
if (data != null)
|
||||
itemStack.setData(data.clone());
|
||||
return itemStack;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import com.github.simplenet.utility.exposed.consumer.BooleanConsumer;
|
||||
import com.github.simplenet.utility.exposed.consumer.ByteConsumer;
|
||||
import com.github.simplenet.utility.exposed.consumer.FloatConsumer;
|
||||
import com.github.simplenet.utility.exposed.consumer.ShortConsumer;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.ConnectionUtils;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
@ -85,4 +86,8 @@ public class PacketReader {
|
||||
Utils.readPosition(client, consumer);
|
||||
}
|
||||
|
||||
public void readSlot(Consumer<ItemStack> consumer) {
|
||||
Utils.readItemStack(this, consumer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,9 +23,10 @@ public class ClientPlayPacketsHandler extends ClientPacketsHandler {
|
||||
register(0x23, ClientHeldItemChangePacket.class);
|
||||
register(0x09, ClientClickWindowPacket.class);
|
||||
register(0x0A, ClientCloseWindow.class);
|
||||
register(0x07, ClientConfirmTransactionPacket.class);
|
||||
register(0x07, ClientClickWindowButtonPacket.class);
|
||||
register(0x1C, ClientSteerVehiclePacket.class);
|
||||
register(0x2D, ClientUseItemPacket.class);
|
||||
register(0x04, ClientStatusPacket.class);
|
||||
register(0x26, ClientCreativeInventoryActionPacket.class);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||
import fr.themode.minestom.net.packet.server.login.JoinGamePacket;
|
||||
import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.DeclareCommandsPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
@ -76,7 +77,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
connection.sendPacket(spawnPositionPacket);
|
||||
|
||||
PlayerInfoPacket playerInfoPacket = new PlayerInfoPacket(PlayerInfoPacket.Action.ADD_PLAYER);
|
||||
PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(player.getUuid(), username, GameMode.CREATIVE, 10);
|
||||
PlayerInfoPacket.AddPlayer addPlayer = new PlayerInfoPacket.AddPlayer(player.getUuid(), username, player.getGameMode(), 10);
|
||||
PlayerInfoPacket.AddPlayer.Property prop = new PlayerInfoPacket.AddPlayer.Property("textures", property); //new PlayerInfoPacket.AddPlayer.Property("textures", properties.get(username));
|
||||
addPlayer.properties.add(prop);
|
||||
playerInfoPacket.playerInfos.add(addPlayer);
|
||||
@ -84,7 +85,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
|
||||
Main.getEntityManager().addWaitingPlayer(player);
|
||||
|
||||
/*DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
||||
DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket();
|
||||
DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node();
|
||||
argumentNode.flags = 0b1010;
|
||||
argumentNode.children = new int[0];
|
||||
@ -102,7 +103,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
declareCommandsPacket.rootIndex = 0;
|
||||
|
||||
|
||||
connection.sendPacket(declareCommandsPacket);*/
|
||||
connection.sendPacket(declareCommandsPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,20 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
|
||||
public class ClientClickWindowButtonPacket extends ClientPlayPacket {
|
||||
|
||||
public byte windowId;
|
||||
public byte buttonId;
|
||||
|
||||
@Override
|
||||
public void read(PacketReader reader, Runnable callback) {
|
||||
// FIXME: 2 packets have the same id (Confirm Transaction / Click window button)
|
||||
reader.readByte(value -> windowId = value);
|
||||
reader.readByte(value -> {
|
||||
buttonId = value;
|
||||
callback.run();
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
|
||||
@ -10,6 +11,7 @@ public class ClientClickWindowPacket extends ClientPlayPacket {
|
||||
public byte button;
|
||||
public short actionNumber;
|
||||
public int mode;
|
||||
public ItemStack item;
|
||||
// TODO clicked item
|
||||
|
||||
@Override
|
||||
@ -18,10 +20,10 @@ public class ClientClickWindowPacket extends ClientPlayPacket {
|
||||
reader.readShort(value -> slot = value);
|
||||
reader.readByte(value -> button = value);
|
||||
reader.readShort(value -> actionNumber = value);
|
||||
reader.readVarInt(value -> {
|
||||
mode = value;
|
||||
reader.readVarInt(value -> mode = value);
|
||||
reader.readSlot(itemStack -> {
|
||||
item = itemStack;
|
||||
callback.run();
|
||||
});
|
||||
// TODO read clicked item
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
|
||||
public class ClientConfirmTransactionPacket extends ClientPlayPacket {
|
||||
|
||||
public int windowId;
|
||||
public short actionNumber;
|
||||
public boolean accepted;
|
||||
|
||||
@Override
|
||||
public void read(PacketReader reader, Runnable callback) {
|
||||
callback.run();
|
||||
// TODO
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
|
||||
public class ClientCreativeInventoryActionPacket extends ClientPlayPacket {
|
||||
|
||||
public short slot;
|
||||
public ItemStack item;
|
||||
|
||||
@Override
|
||||
public void read(PacketReader reader, Runnable callback) {
|
||||
reader.readShort(value -> slot = value);
|
||||
reader.readSlot(itemStack -> {
|
||||
item = itemStack;
|
||||
callback.run();
|
||||
});
|
||||
}
|
||||
}
|
@ -7,8 +7,8 @@ public class ResponsePacket implements ServerPacket {
|
||||
|
||||
private static final String JSON_EXAMPLE = "{\n" +
|
||||
" \"version\": {\n" +
|
||||
" \"name\": \"1.14.4\",\n" +
|
||||
" \"protocol\": 498\n" +
|
||||
" \"name\": \"1.15.2\",\n" +
|
||||
" \"protocol\": 578\n" +
|
||||
" },\n" +
|
||||
" \"players\": {\n" +
|
||||
" \"max\": 100,\n" +
|
||||
|
@ -11,10 +11,12 @@ public class JoinGamePacket implements ServerPacket {
|
||||
public int entityId;
|
||||
public GameMode gameMode = GameMode.SURVIVAL;
|
||||
public Dimension dimension = Dimension.OVERWORLD;
|
||||
public long hashedSeed;
|
||||
public byte maxPlayers = 0; // Unused
|
||||
public LevelType levelType;
|
||||
public int viewDistance;
|
||||
public boolean reducedDebugInfo = false;
|
||||
public boolean enableRespawnScreen = true;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
@ -25,14 +27,16 @@ public class JoinGamePacket implements ServerPacket {
|
||||
writer.writeInt(entityId);
|
||||
writer.writeByte((byte) gameModeId);
|
||||
writer.writeInt(dimension.getId());
|
||||
writer.writeLong(hashedSeed);
|
||||
writer.writeByte(maxPlayers);
|
||||
writer.writeSizedString(levelType.getType());
|
||||
writer.writeVarInt(viewDistance);
|
||||
writer.writeBoolean(reducedDebugInfo);
|
||||
writer.writeBoolean(enableRespawnScreen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x25;
|
||||
return 0x26;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ public class AcknowledgePlayerDiggingPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x5c;
|
||||
return 0x8;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class AdvancementsPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x57;
|
||||
return 0x58;
|
||||
}
|
||||
|
||||
public enum FrameType {
|
||||
|
@ -21,6 +21,6 @@ public class BlockActionPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0A;
|
||||
return 0x0B;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ public class BlockBreakAnimationPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x08;
|
||||
return 0x09;
|
||||
}
|
||||
}
|
@ -17,6 +17,6 @@ public class BlockChangePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0B;
|
||||
return 0x0C;
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ public class BossBarPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0C;
|
||||
return 0x0D;
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
|
@ -16,7 +16,7 @@ public class ChangeGameStatePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x1E;
|
||||
return 0x1F;
|
||||
}
|
||||
|
||||
public enum Reason {
|
||||
@ -30,7 +30,8 @@ public class ChangeGameStatePacket implements ServerPacket {
|
||||
FADE_VALUE,
|
||||
FADE_TIME,
|
||||
PLAY_PUFFERFISH_STING_SOUND,
|
||||
PLAYER_ELDER_GUARDIAN_MOB_APPEARANCE;
|
||||
PLAYER_ELDER_GUARDIAN_MOB_APPEARANCE,
|
||||
ENABLE_RESPAWN_SCREEN;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class ChatMessagePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0E;
|
||||
return 0x0F;
|
||||
}
|
||||
|
||||
public enum Position {
|
||||
|
@ -49,15 +49,6 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
}
|
||||
}
|
||||
|
||||
// Biome data
|
||||
if (fullChunk) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
blocks.putInt(chunk.getBiome().getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.writeVarInt(mask);
|
||||
|
||||
// Heightmap
|
||||
@ -84,6 +75,15 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
writer.writeBytes(data);
|
||||
}
|
||||
|
||||
// Biome data
|
||||
if (fullChunk) {
|
||||
for (int z = 0; z < 1024; z++) {
|
||||
writer.writeInt(chunk.getBiome().getId());
|
||||
//blocks.putInt(chunk.getBiome().getId()); // FIXME
|
||||
}
|
||||
}
|
||||
|
||||
// Data
|
||||
writer.writeVarInt(blocks.getSize());
|
||||
writer.writeBufferAndFree(blocks);
|
||||
|
||||
@ -129,6 +129,6 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x21;
|
||||
return 0x22;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ public class CloseWindowPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x13;
|
||||
return 0x14;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class CollectItemPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x55;
|
||||
return 0x56;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class ConfirmTransactionPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x12;
|
||||
return 0x13;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class DeclareCommandsPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x11;
|
||||
return 0x12;
|
||||
}
|
||||
|
||||
public static class Node {
|
||||
|
@ -14,6 +14,6 @@ public class DestroyEntitiesPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x37;
|
||||
return 0x38;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,6 @@ public class DisconnectPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x1A;
|
||||
return 0x1B;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ public class DisplayScoreboardPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x42;
|
||||
return 0x43;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ public class EntityEffectPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x59;
|
||||
return 0x5A;
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class EntityEquipmentPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x46;
|
||||
return 0x47;
|
||||
}
|
||||
|
||||
public enum Slot {
|
||||
|
@ -16,6 +16,6 @@ public class EntityHeadLookPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x3B;
|
||||
return 0x3C;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,6 @@ public class EntityLookAndRelativeMovePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x29;
|
||||
return 0x2A;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ public class EntityLookPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x2A;
|
||||
return 0x2B;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,6 @@ public class EntityMetaDataPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x43;
|
||||
return 0x44;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ public class EntityPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x2B;
|
||||
return 0x2C;
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class EntityPropertiesPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x58;
|
||||
return 0x59;
|
||||
}
|
||||
|
||||
public static class Property {
|
||||
|
@ -20,6 +20,6 @@ public class EntityRelativeMovePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x28;
|
||||
return 0x29;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ public class EntityStatusPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x1B;
|
||||
return 0x1C;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,6 @@ public class EntityTeleportPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x56;
|
||||
return 0x57;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class EntityVelocityPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x45;
|
||||
return 0x46;
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,6 @@ public class ExplosionPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x1C;
|
||||
return 0x1D;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,6 @@ public class HeldItemChangePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x3F;
|
||||
return 0x40;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class KeepAlivePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x20;
|
||||
return 0x21;
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ public class MultiBlockChangePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x0F;
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
public static class BlockChange {
|
||||
|
@ -18,6 +18,6 @@ public class OpenWindowPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x2E;
|
||||
return 0x2F;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ public class ParticlePacket implements ServerPacket {
|
||||
|
||||
public int particleId;
|
||||
public boolean longDistance;
|
||||
public float x, y, z;
|
||||
public double x, y, z;
|
||||
public float offsetX, offsetY, offsetZ;
|
||||
public float particleData;
|
||||
public int particleCount;
|
||||
@ -18,9 +18,9 @@ public class ParticlePacket implements ServerPacket {
|
||||
public void write(PacketWriter writer) {
|
||||
writer.writeInt(particleId);
|
||||
writer.writeBoolean(longDistance);
|
||||
writer.writeFloat(x);
|
||||
writer.writeFloat(y);
|
||||
writer.writeFloat(z);
|
||||
writer.writeDouble(x);
|
||||
writer.writeDouble(y);
|
||||
writer.writeDouble(z);
|
||||
writer.writeFloat(offsetX);
|
||||
writer.writeFloat(offsetY);
|
||||
writer.writeFloat(offsetZ);
|
||||
@ -32,6 +32,6 @@ public class ParticlePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x23;
|
||||
return 0x24;
|
||||
}
|
||||
}
|
||||
|
@ -34,6 +34,6 @@ public class PlayerAbilitiesPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x31;
|
||||
return 0x32;
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class PlayerInfoPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x33;
|
||||
return 0x34;
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
|
@ -24,6 +24,6 @@ public class PlayerPositionAndLookPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x35;
|
||||
return 0x36;
|
||||
}
|
||||
}
|
@ -16,6 +16,6 @@ public class RemoveEntityEffectPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x38;
|
||||
return 0x39;
|
||||
}
|
||||
}
|
||||
|
@ -9,18 +9,20 @@ import fr.themode.minestom.world.LevelType;
|
||||
public class RespawnPacket implements ServerPacket {
|
||||
|
||||
public Dimension dimension;
|
||||
public long hashedSeed;
|
||||
public GameMode gameMode;
|
||||
public LevelType levelType;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
writer.writeByte((byte) gameMode.getId()); // Hardcore flag not included
|
||||
writer.writeInt(dimension.getId());
|
||||
writer.writeLong(hashedSeed);
|
||||
writer.writeByte((byte) gameMode.getId()); // Hardcore flag not included
|
||||
writer.writeSizedString(levelType.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x3A;
|
||||
return 0x3B;
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,6 @@ public class ScoreboardObjectivePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x49;
|
||||
return 0x4A;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class SetExperiencePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x47;
|
||||
return 0x48;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,6 @@ public class SetPassengersPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x4A;
|
||||
return 0x4B;
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ public class SetSlotPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x16;
|
||||
return 0x17;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,10 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.net.packet.PacketWriter;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SpawnMobPacket implements ServerPacket {
|
||||
|
||||
@ -16,7 +14,6 @@ public class SpawnMobPacket implements ServerPacket {
|
||||
public Position position;
|
||||
public float headPitch;
|
||||
public short velocityX, velocityY, velocityZ;
|
||||
public Consumer<Packet> consumer;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
@ -32,10 +29,6 @@ public class SpawnMobPacket implements ServerPacket {
|
||||
writer.writeShort(velocityX);
|
||||
writer.writeShort(velocityY);
|
||||
writer.writeShort(velocityZ);
|
||||
if (consumer != null) {
|
||||
writer.write(consumer);
|
||||
}
|
||||
writer.writeByte((byte) 0xff);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,19 +1,16 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.net.packet.PacketWriter;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SpawnPlayerPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public UUID playerUuid;
|
||||
public Position position;
|
||||
public Consumer<Packet> metadataConsumer;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
@ -24,12 +21,6 @@ public class SpawnPlayerPacket implements ServerPacket {
|
||||
writer.writeDouble(position.getZ());
|
||||
writer.writeByte((byte) (position.getYaw() * 256f / 360f));
|
||||
writer.writeByte((byte) (position.getPitch() * 256f / 360f));
|
||||
|
||||
if (metadataConsumer != null) {
|
||||
writer.write(metadataConsumer);
|
||||
} else {
|
||||
writer.writeByte((byte) 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -14,6 +14,6 @@ public class SpawnPositionPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x4D;
|
||||
return 0x4E;
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ public class TeamsPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x4B;
|
||||
return 0x4C;
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
|
@ -28,7 +28,7 @@ public class TradeListPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x27;
|
||||
return 0x28;
|
||||
}
|
||||
|
||||
public static class Trade {
|
||||
|
@ -15,6 +15,6 @@ public class UnloadChunkPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x1D;
|
||||
return 0x1E;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class UpdateHealthPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x48;
|
||||
return 0x49;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ public class UpdateScorePacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x4C;
|
||||
return 0x4D;
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,6 @@ public class UpdateViewPositionPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x40;
|
||||
return 0x41;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ public class WindowItemsPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x14;
|
||||
return 0x15;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,6 @@ public class WindowPropertyPacket implements ServerPacket {
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x15;
|
||||
return 0x16;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
import fr.themode.minestom.utils.time.CooldownUtils;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
@ -16,25 +17,56 @@ public class SchedulerManager {
|
||||
private static ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_SCHEDULER, "Ms-SchedulerPool");
|
||||
private List<Task> tasks = new CopyOnWriteArrayList<>();
|
||||
|
||||
public void addRepeatingTask(TaskRunnable runnable, UpdateOption updateOption) {
|
||||
runnable.setId(COUNTER.incrementAndGet());
|
||||
public int addTask(TaskRunnable runnable, UpdateOption updateOption, int maxCallCount) {
|
||||
int id = COUNTER.incrementAndGet();
|
||||
runnable.setId(id);
|
||||
|
||||
Task task = new Task(runnable, updateOption);
|
||||
Task task = new Task(runnable, updateOption, maxCallCount);
|
||||
this.tasks.add(task);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public int addRepeatingTask(TaskRunnable runnable, UpdateOption updateOption) {
|
||||
return addTask(runnable, updateOption, 0);
|
||||
}
|
||||
|
||||
public int addDelayedTask(TaskRunnable runnable, UpdateOption updateOption) {
|
||||
return addTask(runnable, updateOption, 1);
|
||||
}
|
||||
|
||||
public void removeTask(int taskId) {
|
||||
synchronized (tasks) {
|
||||
this.tasks.removeIf(task -> task.getId() == taskId);
|
||||
}
|
||||
}
|
||||
|
||||
public void update() {
|
||||
long time = System.currentTimeMillis();
|
||||
batchesPool.execute(() -> {
|
||||
for (Task task : tasks) {
|
||||
UpdateOption updateOption = task.getUpdateOption();
|
||||
long lastUpdate = task.getLastUpdateTime();
|
||||
boolean hasCooldown = CooldownUtils.hasCooldown(time, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
if (!hasCooldown) {
|
||||
TaskRunnable runnable = task.getRunnable();
|
||||
|
||||
runnable.run();
|
||||
task.refreshLastUpdateTime(time);
|
||||
synchronized (tasks) {
|
||||
Iterator<Task> iterator = tasks.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Task task = iterator.next();
|
||||
|
||||
UpdateOption updateOption = task.getUpdateOption();
|
||||
long lastUpdate = task.getLastUpdateTime();
|
||||
boolean hasCooldown = CooldownUtils.hasCooldown(time, lastUpdate, updateOption.getTimeUnit(), updateOption.getValue());
|
||||
if (!hasCooldown) {
|
||||
TaskRunnable runnable = task.getRunnable();
|
||||
int maxCallCount = task.getMaxCallCount();
|
||||
int callCount = runnable.getCallCount() + 1;
|
||||
runnable.setCallCount(callCount);
|
||||
|
||||
runnable.run();
|
||||
|
||||
task.refreshLastUpdateTime(time);
|
||||
|
||||
if (callCount == maxCallCount) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -4,14 +4,21 @@ import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
public class Task {
|
||||
|
||||
private int id;
|
||||
|
||||
private TaskRunnable runnable;
|
||||
private UpdateOption updateOption;
|
||||
|
||||
private int maxCallCount;
|
||||
|
||||
private long lastUpdateTime;
|
||||
|
||||
public Task(TaskRunnable runnable, UpdateOption updateOption) {
|
||||
public Task(TaskRunnable runnable, UpdateOption updateOption, int maxCallCount) {
|
||||
this.id = runnable.getId();
|
||||
|
||||
this.runnable = runnable;
|
||||
this.updateOption = updateOption;
|
||||
this.maxCallCount = maxCallCount;
|
||||
}
|
||||
|
||||
protected void refreshLastUpdateTime(long lastUpdateTime) {
|
||||
@ -22,6 +29,10 @@ public class Task {
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public TaskRunnable getRunnable() {
|
||||
return runnable;
|
||||
}
|
||||
@ -29,4 +40,8 @@ public class Task {
|
||||
public UpdateOption getUpdateOption() {
|
||||
return updateOption;
|
||||
}
|
||||
|
||||
public int getMaxCallCount() {
|
||||
return maxCallCount;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package fr.themode.minestom.timer;
|
||||
public abstract class TaskRunnable {
|
||||
|
||||
private int id;
|
||||
private int callCount;
|
||||
|
||||
public abstract void run();
|
||||
|
||||
@ -10,7 +11,15 @@ public abstract class TaskRunnable {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getCallCount() {
|
||||
return callCount;
|
||||
}
|
||||
|
||||
protected void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
protected void setCallCount(int callCount) {
|
||||
this.callCount = callCount;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ public class PacketUtils {
|
||||
PacketWriter packetWriter = new PacketWriter(packet);
|
||||
serverPacket.write(packetWriter);
|
||||
|
||||
System.out.println("WRITE PACKET: " + id + " " + serverPacket.getClass().getSimpleName());
|
||||
|
||||
callback.accept(packet.prepend(p -> {
|
||||
Utils.writeVarInt(packet, packet.getSize());
|
||||
}));
|
||||
|
@ -5,6 +5,7 @@ import com.github.simplenet.packet.Packet;
|
||||
import fr.themode.minestom.chat.Chat;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.ConnectionUtils;
|
||||
import fr.themode.minestom.net.packet.PacketReader;
|
||||
import fr.themode.minestom.utils.buffer.BufferWrapper;
|
||||
import fr.themode.minestom.utils.consumer.StringConsumer;
|
||||
|
||||
@ -136,6 +137,30 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void readItemStack(PacketReader reader, Consumer<ItemStack> consumer) {
|
||||
// FIXME: need finishing
|
||||
reader.readBoolean(present -> {
|
||||
if (!present) {
|
||||
consumer.accept(ItemStack.AIR_ITEM); // Consume air item if empty
|
||||
return;
|
||||
}
|
||||
|
||||
reader.readVarInt(id -> {
|
||||
|
||||
reader.readByte(count -> {
|
||||
|
||||
reader.readByte(nbt -> { // FIXME: assume that there is no NBT data
|
||||
consumer.accept(new ItemStack(id, count));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public static void writeBlocks(BufferWrapper buffer, short[] blocksId, int bitsPerEntry) {
|
||||
short count = 0;
|
||||
for (short id : blocksId)
|
||||
|
Loading…
Reference in New Issue
Block a user