mirror of
https://github.com/Minestom/Minestom.git
synced 2025-02-04 06:21:52 +01:00
Bugs fixes & scheduled task API
This commit is contained in:
parent
5c0056e183
commit
c66020a196
@ -17,19 +17,23 @@ import fr.themode.minestom.net.packet.client.status.LegacyServerListPingPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.KeepAlivePacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.scoreboard.TeamManager;
|
||||
import fr.themode.minestom.timer.SchedulerManager;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class Main {
|
||||
|
||||
// Thread number
|
||||
// Thread pools
|
||||
public static final int THREAD_COUNT_PACKET_WRITER = 2;
|
||||
public static final int THREAD_COUNT_IO = 2;
|
||||
public static final int THREAD_COUNT_BLOCK_BATCH = 2;
|
||||
public static final int THREAD_COUNT_BLOCK_UPDATE = 2;
|
||||
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;
|
||||
|
||||
// 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;
|
||||
|
||||
// Config
|
||||
@ -48,6 +52,7 @@ public class Main {
|
||||
private static EntityManager entityManager;
|
||||
private static DataManager dataManager;
|
||||
private static TeamManager teamManager;
|
||||
private static SchedulerManager schedulerManager;
|
||||
|
||||
public static void main(String[] args) {
|
||||
connectionManager = new ConnectionManager();
|
||||
@ -59,6 +64,7 @@ public class Main {
|
||||
entityManager = new EntityManager();
|
||||
dataManager = new DataManager();
|
||||
teamManager = new TeamManager();
|
||||
schedulerManager = new SchedulerManager();
|
||||
|
||||
blockManager.registerBlock(new StoneBlock());
|
||||
blockManager.registerBlock(new UpdatableBlockDemo());
|
||||
@ -123,6 +129,9 @@ public class Main {
|
||||
// Blocks update
|
||||
instanceManager.updateBlocks();
|
||||
|
||||
// Scheduler
|
||||
schedulerManager.update();
|
||||
|
||||
// TODO miscellaneous update (scoreboard)
|
||||
|
||||
// Sleep until next tick
|
||||
@ -168,6 +177,10 @@ public class Main {
|
||||
return teamManager;
|
||||
}
|
||||
|
||||
public static SchedulerManager getSchedulerManager() {
|
||||
return schedulerManager;
|
||||
}
|
||||
|
||||
public static ConnectionManager getConnectionManager() {
|
||||
return connectionManager;
|
||||
}
|
||||
|
@ -90,6 +90,14 @@ public class Player extends LivingEntity {
|
||||
private Team team;
|
||||
private BelowNameScoreboard belowNameScoreboard;
|
||||
|
||||
// Abilities
|
||||
private boolean invulnerable;
|
||||
private boolean flying;
|
||||
private boolean allowFlying;
|
||||
private boolean instantBreak;
|
||||
private float flyingSpeed = 0.05f;
|
||||
private float fieldViewModifier = 0.1f;
|
||||
|
||||
// Vehicle
|
||||
private float sideways;
|
||||
private float forward;
|
||||
@ -189,7 +197,9 @@ public class Player extends LivingEntity {
|
||||
scoreboard.addViewer(this);
|
||||
scoreboard.updateLineContent("id3", "I HAVE BEEN UPDATED &2TEST");*/
|
||||
|
||||
setBelowNameScoreboard(new BelowNameScoreboard());
|
||||
BelowNameScoreboard belowNameScoreboard = new BelowNameScoreboard();
|
||||
setBelowNameScoreboard(belowNameScoreboard);
|
||||
belowNameScoreboard.updateScore(this, 50);
|
||||
});
|
||||
}
|
||||
|
||||
@ -718,6 +728,7 @@ public class Player extends LivingEntity {
|
||||
this.belowNameScoreboard = belowNameScoreboard;
|
||||
if (belowNameScoreboard != null) {
|
||||
belowNameScoreboard.addViewer(this);
|
||||
belowNameScoreboard.displayScoreboard(this);
|
||||
getViewers().forEach(player -> belowNameScoreboard.addViewer(player));
|
||||
}
|
||||
}
|
||||
@ -824,6 +835,72 @@ public class Player extends LivingEntity {
|
||||
playerConnection.sendPacket(positionAndLookPacket);
|
||||
}
|
||||
|
||||
public boolean isInvulnerable() {
|
||||
return invulnerable;
|
||||
}
|
||||
|
||||
public void setInvulnerable(boolean invulnerable) {
|
||||
this.invulnerable = invulnerable;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
public boolean isFlying() {
|
||||
return flying;
|
||||
}
|
||||
|
||||
public void setFlying(boolean flying) {
|
||||
this.flying = flying;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
public boolean isAllowFlying() {
|
||||
return allowFlying;
|
||||
}
|
||||
|
||||
public void setAllowFlying(boolean allowFlying) {
|
||||
this.allowFlying = allowFlying;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
public boolean isInstantBreak() {
|
||||
return instantBreak;
|
||||
}
|
||||
|
||||
public void setInstantBreak(boolean instantBreak) {
|
||||
this.instantBreak = instantBreak;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
public float getFlyingSpeed() {
|
||||
return flyingSpeed;
|
||||
}
|
||||
|
||||
public void setFlyingSpeed(float flyingSpeed) {
|
||||
this.flyingSpeed = flyingSpeed;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
public float getFieldViewModifier() {
|
||||
return fieldViewModifier;
|
||||
}
|
||||
|
||||
public void setFieldViewModifier(float fieldViewModifier) {
|
||||
this.fieldViewModifier = fieldViewModifier;
|
||||
refreshAbilities();
|
||||
}
|
||||
|
||||
private void refreshAbilities() {
|
||||
PlayerAbilitiesPacket playerAbilitiesPacket = new PlayerAbilitiesPacket();
|
||||
playerAbilitiesPacket.invulnerable = invulnerable;
|
||||
playerAbilitiesPacket.flying = flying;
|
||||
playerAbilitiesPacket.allowFlying = allowFlying;
|
||||
playerAbilitiesPacket.instantBreak = instantBreak;
|
||||
playerAbilitiesPacket.flyingSpeed = flyingSpeed;
|
||||
playerAbilitiesPacket.fieldViewModifier = fieldViewModifier;
|
||||
|
||||
playerConnection.sendPacket(playerAbilitiesPacket);
|
||||
}
|
||||
|
||||
public void addPacketToQueue(ClientPlayPacket packet) {
|
||||
this.packets.add(packet);
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.block.BlockManager;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.UpdateConsumer;
|
||||
import fr.themode.minestom.instance.block.UpdateOption;
|
||||
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
import fr.themode.minestom.utils.PacketUtils;
|
||||
import fr.themode.minestom.utils.SerializerUtils;
|
||||
import fr.themode.minestom.utils.time.CooldownUtils;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
// TODO light data & API
|
||||
public class Chunk implements Viewable {
|
||||
|
||||
private static final BlockManager BLOCK_MANAGER = Main.getBlockManager();
|
||||
@ -40,7 +41,7 @@ public class Chunk implements Viewable {
|
||||
|
||||
// Used to get all blocks with data (no null)
|
||||
// Key is still chunk coord
|
||||
// TODO shouldn't take Data object (too much memory overhead)
|
||||
// FIXME: shouldn't take Data object (too much memory overhead)
|
||||
private Int2ObjectMap<Data> blocksData = new Int2ObjectOpenHashMap<>(16 * 16); // Start with the size of a single row
|
||||
|
||||
// Contains CustomBlocks' index which are updatable
|
||||
@ -53,8 +54,6 @@ 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;
|
||||
@ -92,12 +91,24 @@ public class Chunk implements Viewable {
|
||||
|
||||
private void setBlock(byte x, byte y, byte z, short blockType, short customId, Data data, UpdateConsumer updateConsumer) {
|
||||
int index = SerializerUtils.chunkCoordToIndex(x, y, z);
|
||||
if (blockType != 0 || customId != 0) {
|
||||
int value = (blockType << 16 | customId & 0xFFFF); // Merge blockType and customId to one unique Integer (16/16)
|
||||
if (blockType != 0
|
||||
|| (blockType == 0 && customId != 0 && updateConsumer != null)) { // Allow custom air block for update purpose, refused if no update consumer has been found
|
||||
int value = (blockType << 16 | customId & 0xFFFF); // Merge blockType and customId to one unique Integer (16/16 bits)
|
||||
this.blocks.put(index, value);
|
||||
} else {
|
||||
// Block has been deleted
|
||||
// Block has been deleted, clear cache and return
|
||||
|
||||
this.blocks.remove(index);
|
||||
|
||||
this.blocksData.remove(index);
|
||||
|
||||
this.updatableBlocks.remove(index);
|
||||
this.updatableBlocksLastUpdate.remove(index);
|
||||
|
||||
this.blockEntities.remove(index);
|
||||
|
||||
this.packetUpdated = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the new data (or remove from the map if is null)
|
||||
@ -173,11 +184,7 @@ public class Chunk implements Viewable {
|
||||
IntIterator iterator = new IntOpenHashSet(updatableBlocks).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
int index = iterator.nextInt();
|
||||
byte[] blockPos = SerializerUtils.indexToChunkPosition(index);
|
||||
byte x = blockPos[0];
|
||||
byte y = blockPos[1];
|
||||
byte z = blockPos[2];
|
||||
CustomBlock customBlock = getCustomBlock(x, y, z);
|
||||
CustomBlock customBlock = getCustomBlock(index);
|
||||
|
||||
// Update cooldown
|
||||
UpdateOption updateOption = customBlock.getUpdateOption();
|
||||
@ -187,6 +194,12 @@ public class Chunk implements Viewable {
|
||||
continue;
|
||||
|
||||
this.updatableBlocksLastUpdate.put(index, time); // Refresh last update time
|
||||
|
||||
byte[] blockPos = SerializerUtils.indexToChunkPosition(index);
|
||||
byte x = blockPos[0];
|
||||
byte y = blockPos[1];
|
||||
byte z = blockPos[2];
|
||||
|
||||
BlockPosition blockPosition = new BlockPosition(x + 16 * chunkX, y, z + 16 * chunkZ);
|
||||
Data data = getData(index);
|
||||
customBlock.update(instance, blockPosition, data);
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.instance.BlockModifier;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.instance.InstanceContainer;
|
||||
|
||||
@ -10,7 +9,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BlockBatch implements IBatch, BlockModifier {
|
||||
public class BlockBatch implements IBatch {
|
||||
|
||||
private InstanceContainer instance;
|
||||
|
||||
@ -21,38 +20,42 @@ public class BlockBatch implements IBatch, BlockModifier {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void setBlock(int x, int y, int z, short blockId, Data data) {
|
||||
Chunk chunk = this.instance.getChunkAt(x, z);
|
||||
List<BlockData> blocksData = this.data.getOrDefault(chunk, new ArrayList<>());
|
||||
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;
|
||||
BlockData blockData = new BlockData();
|
||||
blockData.x = x % 16;
|
||||
blockData.y = y;
|
||||
blockData.z = z % 16;
|
||||
blockData.blockId = blockId;
|
||||
blockData.data = data;
|
||||
|
||||
blocksData.add(blockData);
|
||||
blocksData.add(blockData);
|
||||
|
||||
this.data.put(chunk, blocksData);
|
||||
this.data.put(chunk, blocksData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomBlock(int x, int y, int z, short blockId, Data data) {
|
||||
Chunk chunk = this.instance.getChunkAt(x, z);
|
||||
List<BlockData> blocksData = this.data.getOrDefault(chunk, new ArrayList<>());
|
||||
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;
|
||||
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);
|
||||
blocksData.add(blockData);
|
||||
|
||||
this.data.put(chunk, blocksData);
|
||||
this.data.put(chunk, blocksData);
|
||||
}
|
||||
}
|
||||
|
||||
public void flush(Runnable callback) {
|
||||
|
@ -1,24 +1,24 @@
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.data.Data;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Use chunk coordinate (0-16) instead of world's
|
||||
*/
|
||||
public class ChunkBatch implements IBatch, BlockModifier {
|
||||
public class ChunkBatch implements IBatch {
|
||||
|
||||
private InstanceContainer instance;
|
||||
private Chunk chunk;
|
||||
|
||||
private List<BlockData> dataList = new ArrayList<>();
|
||||
private List<BlockData> dataList = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
public ChunkBatch(InstanceContainer instance, Chunk chunk) {
|
||||
this.instance = instance;
|
||||
|
@ -1,11 +1,12 @@
|
||||
package fr.themode.minestom.instance.batch;
|
||||
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.instance.BlockModifier;
|
||||
import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
||||
public interface IBatch {
|
||||
public interface IBatch extends BlockModifier {
|
||||
|
||||
ExecutorService batchesPool = new MinestomThread(Main.THREAD_COUNT_BLOCK_BATCH, "Ms-BlockBatchPool");
|
||||
|
||||
|
@ -4,6 +4,7 @@ import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
|
@ -2,7 +2,7 @@ package fr.themode.minestom.instance.demo;
|
||||
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.UpdateOption;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
public class StoneBlock extends CustomBlock {
|
||||
|
||||
|
@ -4,9 +4,9 @@ import fr.themode.minestom.data.Data;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.instance.block.CustomBlock;
|
||||
import fr.themode.minestom.instance.block.UpdateOption;
|
||||
import fr.themode.minestom.utils.BlockPosition;
|
||||
import fr.themode.minestom.utils.time.TimeUnit;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
public class UpdatableBlockDemo extends CustomBlock {
|
||||
|
||||
|
@ -19,7 +19,8 @@ public class ClientPacketsHandler {
|
||||
|
||||
ConstructorAccess<? extends ClientPacket> constructorAccess = constructorAccesses[id];
|
||||
if (constructorAccess == null)
|
||||
System.err.println("Packet id 0x" + Integer.toHexString(id) + " isn't registered!");
|
||||
throw new IllegalStateException("Packet id 0x" + Integer.toHexString(id) + " isn't registered!");
|
||||
|
||||
ClientPacket packet = constructorAccess.newInstance();
|
||||
return packet;
|
||||
}
|
||||
|
@ -18,22 +18,32 @@ public class ClientUseEntityPacket extends ClientPlayPacket {
|
||||
reader.readVarInt(value -> targetId = value);
|
||||
reader.readVarInt(value -> {
|
||||
type = Type.values()[value];
|
||||
if (type == Type.ATTACK)
|
||||
callback.run();
|
||||
});
|
||||
|
||||
if (this.type == Type.INTERACT_AT) {
|
||||
reader.readFloat(value -> x = value);
|
||||
reader.readFloat(value -> y = value);
|
||||
reader.readFloat(value -> {
|
||||
z = value;
|
||||
});
|
||||
}
|
||||
if (type == Type.INTERACT || type == Type.INTERACT_AT)
|
||||
reader.readVarInt(value -> {
|
||||
hand = Player.Hand.values()[value];
|
||||
callback.run();
|
||||
});
|
||||
switch (type) {
|
||||
|
||||
case ATTACK:
|
||||
callback.run();
|
||||
break;
|
||||
|
||||
case INTERACT:
|
||||
reader.readVarInt(v2 -> {
|
||||
hand = Player.Hand.values()[v2];
|
||||
callback.run();
|
||||
});
|
||||
break;
|
||||
|
||||
case INTERACT_AT:
|
||||
reader.readFloat(vX -> x = vX);
|
||||
reader.readFloat(vY -> y = vY);
|
||||
reader.readFloat(vZ -> z = vZ);
|
||||
reader.readVarInt(v2 -> {
|
||||
hand = Player.Hand.values()[v2];
|
||||
callback.run();
|
||||
});
|
||||
break;
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
|
@ -0,0 +1,39 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.themode.minestom.net.packet.PacketWriter;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
|
||||
public class PlayerAbilitiesPacket implements ServerPacket {
|
||||
|
||||
// Flags
|
||||
public boolean invulnerable;
|
||||
public boolean flying;
|
||||
public boolean allowFlying;
|
||||
public boolean instantBreak;
|
||||
|
||||
// Options
|
||||
public float flyingSpeed;
|
||||
public float fieldViewModifier;
|
||||
|
||||
@Override
|
||||
public void write(PacketWriter writer) {
|
||||
byte flags = 0;
|
||||
if (invulnerable)
|
||||
flags += 1;
|
||||
if (flying)
|
||||
flags += 2;
|
||||
if (allowFlying)
|
||||
flags += 4;
|
||||
if (instantBreak)
|
||||
flags += 8;
|
||||
|
||||
writer.writeByte(flags);
|
||||
writer.writeFloat(flyingSpeed);
|
||||
writer.writeFloat(fieldViewModifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x31;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ import fr.themode.minestom.Viewable;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.server.play.DisplayScoreboardPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ScoreboardObjectivePacket;
|
||||
import fr.themode.minestom.net.packet.server.play.UpdateScorePacket;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -11,6 +12,7 @@ import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
// TODO fix score and objective refresh
|
||||
public class BelowNameScoreboard implements Viewable {
|
||||
|
||||
private static final AtomicInteger counter = new AtomicInteger();
|
||||
@ -28,7 +30,7 @@ public class BelowNameScoreboard implements Viewable {
|
||||
|
||||
public BelowNameScoreboard() {
|
||||
this.objectiveName = SCOREBOARD_PREFIX + counter.incrementAndGet();
|
||||
System.out.println("DEBUG: " + objectiveName);
|
||||
|
||||
scoreboardObjectivePacket = new ScoreboardObjectivePacket();
|
||||
scoreboardObjectivePacket.objectiveName = objectiveName;
|
||||
scoreboardObjectivePacket.mode = 0;
|
||||
@ -36,17 +38,25 @@ public class BelowNameScoreboard implements Viewable {
|
||||
scoreboardObjectivePacket.type = 0;
|
||||
|
||||
displayScoreboardPacket = new DisplayScoreboardPacket();
|
||||
displayScoreboardPacket.position = 2;
|
||||
displayScoreboardPacket.position = 2; // Below name
|
||||
displayScoreboardPacket.scoreName = objectiveName;
|
||||
}
|
||||
|
||||
public void updateScore(Player player, int score) {
|
||||
UpdateScorePacket updateScorePacket = new UpdateScorePacket();
|
||||
updateScorePacket.entityName = player.getUsername();
|
||||
updateScorePacket.action = 0; // Create/update
|
||||
updateScorePacket.objectiveName = objectiveName;
|
||||
updateScorePacket.value = score;
|
||||
|
||||
sendPacketToViewers(updateScorePacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewer(Player player) {
|
||||
this.viewers.add(player);
|
||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
playerConnection.sendPacket(scoreboardObjectivePacket);
|
||||
// TODO score
|
||||
playerConnection.sendPacket(displayScoreboardPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -58,4 +68,9 @@ public class BelowNameScoreboard implements Viewable {
|
||||
public Set<Player> getViewers() {
|
||||
return Collections.unmodifiableSet(viewers);
|
||||
}
|
||||
|
||||
public void displayScoreboard(Player player) {
|
||||
PlayerConnection playerConnection = player.getPlayerConnection();
|
||||
playerConnection.sendPacket(displayScoreboardPacket);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,43 @@
|
||||
package fr.themode.minestom.timer;
|
||||
|
||||
import fr.themode.minestom.utils.time.TimeUnit;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.utils.thread.MinestomThread;
|
||||
import fr.themode.minestom.utils.time.CooldownUtils;
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class SchedulerManager {
|
||||
|
||||
public void addRepeatingTask(Runnable runnable, TimeUnit timeUnit, int time) {
|
||||
private static final AtomicInteger COUNTER = new AtomicInteger();
|
||||
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());
|
||||
|
||||
Task task = new Task(runnable, updateOption);
|
||||
this.tasks.add(task);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
32
src/main/java/fr/themode/minestom/timer/Task.java
Normal file
32
src/main/java/fr/themode/minestom/timer/Task.java
Normal file
@ -0,0 +1,32 @@
|
||||
package fr.themode.minestom.timer;
|
||||
|
||||
import fr.themode.minestom.utils.time.UpdateOption;
|
||||
|
||||
public class Task {
|
||||
|
||||
private TaskRunnable runnable;
|
||||
private UpdateOption updateOption;
|
||||
|
||||
private long lastUpdateTime;
|
||||
|
||||
public Task(TaskRunnable runnable, UpdateOption updateOption) {
|
||||
this.runnable = runnable;
|
||||
this.updateOption = updateOption;
|
||||
}
|
||||
|
||||
protected void refreshLastUpdateTime(long lastUpdateTime) {
|
||||
this.lastUpdateTime = lastUpdateTime;
|
||||
}
|
||||
|
||||
protected long getLastUpdateTime() {
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
public TaskRunnable getRunnable() {
|
||||
return runnable;
|
||||
}
|
||||
|
||||
public UpdateOption getUpdateOption() {
|
||||
return updateOption;
|
||||
}
|
||||
}
|
16
src/main/java/fr/themode/minestom/timer/TaskRunnable.java
Normal file
16
src/main/java/fr/themode/minestom/timer/TaskRunnable.java
Normal file
@ -0,0 +1,16 @@
|
||||
package fr.themode.minestom.timer;
|
||||
|
||||
public abstract class TaskRunnable {
|
||||
|
||||
private int id;
|
||||
|
||||
public abstract void run();
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
protected void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
package fr.themode.minestom.instance.block;
|
||||
|
||||
import fr.themode.minestom.utils.time.TimeUnit;
|
||||
package fr.themode.minestom.utils.time;
|
||||
|
||||
public class UpdateOption {
|
||||
|
Loading…
Reference in New Issue
Block a user