mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-28 14:37:31 +02:00
Comments
This commit is contained in:
parent
12ccbfc80e
commit
45fd0dc22a
@ -4,7 +4,6 @@ import fr.themode.demo.entity.ChickenCreature;
|
||||
import fr.themode.demo.generator.ChunkGeneratorDemo;
|
||||
import fr.themode.demo.generator.NoiseTestGenerator;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.advancements.*;
|
||||
import net.minestom.server.benchmark.BenchmarkManager;
|
||||
import net.minestom.server.benchmark.ThreadResult;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
@ -69,7 +68,6 @@ public class PlayerInit {
|
||||
end.loadChunk(x, z);
|
||||
}
|
||||
|
||||
|
||||
inventory = new Inventory(InventoryType.CHEST_1_ROW, "Test inventory");
|
||||
inventory.addInventoryCondition((p, slot, clickType, inventoryConditionResult) -> {
|
||||
p.sendMessage("click type inventory: " + clickType);
|
||||
@ -149,10 +147,8 @@ public class PlayerInit {
|
||||
p.teleport(player.getPosition());
|
||||
}*/
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
ChickenCreature chickenCreature = new ChickenCreature(player.getPosition());
|
||||
chickenCreature.setInstance(player.getInstance());
|
||||
}
|
||||
|
||||
/*EntityZombie zombie = new EntityZombie(player.getPosition());
|
||||
zombie.setAttribute(Attribute.MOVEMENT_SPEED, 0.25f);
|
||||
@ -228,7 +224,7 @@ public class PlayerInit {
|
||||
scoreboard.setTitle("test");*/
|
||||
|
||||
{
|
||||
AdvancementManager advancementManager = MinecraftServer.getAdvancementManager();
|
||||
/*AdvancementManager advancementManager = MinecraftServer.getAdvancementManager();
|
||||
AdvancementRoot root = new AdvancementRoot(ColoredText.of("title"), ColoredText.of(ChatColor.BLUE + "description"),
|
||||
Material.APPLE, FrameType.TASK, 0, 0,
|
||||
"minecraft:textures/block/red_wool.png");
|
||||
@ -247,9 +243,7 @@ public class PlayerInit {
|
||||
ColoredText.of("description of the advancement"),
|
||||
Material.GOLD_BLOCK, FrameType.CHALLENGE, 3, 0)
|
||||
.showToast(true).setHidden(false);
|
||||
tab.createAdvancement("second2", advancement2, root);
|
||||
|
||||
//player.getPlayerConnection().sendPacket(tab.removePacket());
|
||||
tab.createAdvancement("second2", advancement2, root);*/
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -192,7 +192,7 @@ public class MinecraftServer {
|
||||
/**
|
||||
* Change the server brand name, update the name to all connected players
|
||||
*
|
||||
* @param brandName
|
||||
* @param brandName the server brand name
|
||||
*/
|
||||
public static void setBrandName(String brandName) {
|
||||
Check.notNull(brandName, "The brand name cannot be null");
|
||||
|
@ -5,7 +5,6 @@ import net.minestom.server.chat.ColoredText;
|
||||
import net.minestom.server.entity.EntityManager;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.instance.Instance;
|
||||
import net.minestom.server.instance.InstanceManager;
|
||||
import net.minestom.server.network.ConnectionManager;
|
||||
import net.minestom.server.network.packet.server.play.KeepAlivePacket;
|
||||
import net.minestom.server.thread.PerGroupChunkProvider;
|
||||
@ -19,6 +18,7 @@ public final class UpdateManager {
|
||||
|
||||
private static final long KEEP_ALIVE_DELAY = 10_000;
|
||||
private static final long KEEP_ALIVE_KICK = 30_000;
|
||||
private static final ColoredText TIMEOUT_TEXT = ColoredText.of(ChatColor.RED + "Timeout");
|
||||
|
||||
private ExecutorService mainUpdate = new MinestomThread(1, MinecraftServer.THREAD_NAME_MAIN_UPDATE);
|
||||
private boolean stopRequested;
|
||||
@ -36,12 +36,14 @@ public final class UpdateManager {
|
||||
protected UpdateManager() {
|
||||
}
|
||||
|
||||
public void start() {
|
||||
/**
|
||||
* Start the server loop in the update thread
|
||||
*/
|
||||
protected void start() {
|
||||
mainUpdate.execute(() -> {
|
||||
|
||||
final ConnectionManager connectionManager = MinecraftServer.getConnectionManager();
|
||||
final EntityManager entityManager = MinecraftServer.getEntityManager();
|
||||
final InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||
|
||||
final long tickDistance = MinecraftServer.TICK_MS * 1000000;
|
||||
long currentTime;
|
||||
@ -49,10 +51,10 @@ public final class UpdateManager {
|
||||
currentTime = System.nanoTime();
|
||||
final long time = System.currentTimeMillis();
|
||||
|
||||
// Server tick
|
||||
// Server tick (instance/chunk/entity)
|
||||
threadProvider.update(time);
|
||||
|
||||
// Waiting players update
|
||||
// Waiting players update (newly connected waiting to get into the server)
|
||||
entityManager.updateWaitingPlayers();
|
||||
|
||||
// Keep Alive Handling
|
||||
@ -63,7 +65,7 @@ public final class UpdateManager {
|
||||
player.refreshKeepAlive(time);
|
||||
player.getPlayerConnection().sendPacket(keepAlivePacket);
|
||||
} else if (lastKeepAlive >= KEEP_ALIVE_KICK) {
|
||||
player.kick(ColoredText.of(ChatColor.RED + "Timeout"));
|
||||
player.kick(TIMEOUT_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -127,7 +129,9 @@ public final class UpdateManager {
|
||||
this.threadProvider.onChunkUnload(instance, chunkX, chunkZ);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop the server loop
|
||||
*/
|
||||
public void stop() {
|
||||
stopRequested = true;
|
||||
}
|
||||
|
@ -121,13 +121,13 @@ public class CollisionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Steps once (by a length of 1 block) on the given axis. Returns false if this method encountered a collision
|
||||
* Steps once (by a length of 1 block) on the given axis.
|
||||
*
|
||||
* @param instance instance to get blocks from
|
||||
* @param axis the axis to move along
|
||||
* @param cornersCopy the corners of the bounding box to consider (mutable)
|
||||
* @param cornerPositions the corners, converted to BlockPosition (mutable)
|
||||
* @return
|
||||
* @return false if this method encountered a collision
|
||||
*/
|
||||
private static boolean stepOnce(Instance instance, Vector axis, float amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
|
||||
final float sign = Math.signum(amount);
|
||||
|
@ -68,8 +68,8 @@ public class Data {
|
||||
/**
|
||||
* Get if the data has a key
|
||||
*
|
||||
* @param key
|
||||
* @return true if the data contains the key, false otherwise
|
||||
* @param key the key to check
|
||||
* @return true if the data contains the key
|
||||
*/
|
||||
public boolean hasKey(String key) {
|
||||
return data.containsKey(key);
|
||||
|
@ -1125,8 +1125,8 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
|
||||
/**
|
||||
* Trigger {@link #remove()} after the specified time
|
||||
*
|
||||
* @param delay
|
||||
* @param timeUnit to determine the delay unit
|
||||
* @param delay the time before removing the entity
|
||||
* @param timeUnit the unit of the delay
|
||||
*/
|
||||
public void scheduleRemove(long delay, TimeUnit timeUnit) {
|
||||
delay = timeUnit.toMilliseconds(delay);
|
||||
|
@ -234,8 +234,8 @@ public class ItemEntity extends ObjectEntity {
|
||||
/**
|
||||
* Set the pickup delay of the ItemEntity
|
||||
*
|
||||
* @param delay
|
||||
* @param timeUnit
|
||||
* @param delay the pickup delay
|
||||
* @param timeUnit the unit of the delay
|
||||
*/
|
||||
public void setPickupDelay(long delay, TimeUnit timeUnit) {
|
||||
this.pickupDelay = timeUnit.toMilliseconds(delay);
|
||||
|
@ -1669,7 +1669,7 @@ public class Player extends LivingEntity implements CommandSender {
|
||||
* <p>
|
||||
* WARNING: this has nothing to do with {@link CustomBlock#getBreakDelay(Player, BlockPosition)}
|
||||
*
|
||||
* @param instantBreak
|
||||
* @param instantBreak true to allow instant break
|
||||
*/
|
||||
public void setInstantBreak(boolean instantBreak) {
|
||||
this.instantBreak = instantBreak;
|
||||
|
@ -27,8 +27,10 @@ public interface EventHandler {
|
||||
<E extends Event> void removeEventCallback(Class<E> eventClass, EventCallback<E> eventCallback);
|
||||
|
||||
/**
|
||||
* @param eventClass
|
||||
* @param <E>
|
||||
* Get the event callbacks of a specific event type
|
||||
*
|
||||
* @param eventClass the event class
|
||||
* @param <E> the event type
|
||||
* @return all event callbacks for the specified type {@code eventClass}
|
||||
*/
|
||||
<E extends Event> List<EventCallback> getEventCallbacks(Class<E> eventClass);
|
||||
|
@ -76,7 +76,7 @@ public class PlayerBlockPlaceEvent extends CancellableEvent {
|
||||
* WARNING: this does not change the visual block id, see {@link #setBlockId(short)}
|
||||
* or {@link #setCustomBlock(short)}
|
||||
*
|
||||
* @param customBlockId
|
||||
* @param customBlockId the custom block id
|
||||
*/
|
||||
public void setCustomBlockId(short customBlockId) {
|
||||
this.customBlockId = customBlockId;
|
||||
|
@ -4,13 +4,14 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import net.minestom.server.network.packet.server.play.TagsPacket;
|
||||
import net.minestom.server.registry.ResourceGatherer;
|
||||
import net.minestom.server.utils.BlockPosition;
|
||||
import net.minestom.server.utils.NamespaceID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.HashMap;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.Reader;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -177,6 +178,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Loads a tag with the given name. This method attempts to read from "data/<name.domain>/tags/<tagType>/<name.path>.json" if the given name is not already present in cache
|
||||
*
|
||||
* @param name
|
||||
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||
* @return
|
||||
@ -188,6 +190,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache
|
||||
*
|
||||
* @param name
|
||||
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||
* @param reader
|
||||
@ -199,6 +202,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Loads a tag with the given name. This method reads from 'reader'. This will override the previous tag
|
||||
*
|
||||
* @param name
|
||||
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||
* @param readerSupplier
|
||||
@ -213,6 +217,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Loads a tag with the given name. This method attempts to read from 'reader' if the given name is not already present in cache
|
||||
*
|
||||
* @param name
|
||||
* @param tagType the type of the tag to load, used to resolve paths (blocks, items, entity_types, fluids, functions are the vanilla variants)
|
||||
* @param readerSupplier
|
||||
@ -240,6 +245,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Adds the required tags for the game to function correctly
|
||||
*
|
||||
* @param tags the packet to add the tags to
|
||||
*/
|
||||
public void addRequiredTagsToPacket(TagsPacket tags) {
|
||||
@ -267,6 +273,7 @@ public class TagManager {
|
||||
|
||||
/**
|
||||
* Adds a required tag to send to players when they connect
|
||||
*
|
||||
* @param type type of tag to send. Required so the client knows its use
|
||||
* @param name the name of the tag to load
|
||||
*/
|
||||
|
@ -30,7 +30,7 @@ public interface IChunkLoader {
|
||||
/**
|
||||
* Does this ChunkLoader allow for multi-threaded saving of chunks?
|
||||
*
|
||||
* @return
|
||||
* @return true if the chunk loader supports parallel saving
|
||||
*/
|
||||
default boolean supportsParallelSaving() {
|
||||
return false;
|
||||
@ -39,7 +39,7 @@ public interface IChunkLoader {
|
||||
/**
|
||||
* Does this ChunkLoader allow for multi-threaded loading of chunks?
|
||||
*
|
||||
* @return
|
||||
* @return true if the chunk loader supports parallel loading
|
||||
*/
|
||||
default boolean supportsParallelLoading() {
|
||||
return false;
|
||||
|
@ -919,10 +919,10 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
||||
* Creates an explosion at the given position with the given strength.
|
||||
* The algorithm used to compute damages is provided by {@link #getExplosionSupplier()}.
|
||||
*
|
||||
* @param centerX
|
||||
* @param centerY
|
||||
* @param centerZ
|
||||
* @param strength
|
||||
* @param centerX the center X
|
||||
* @param centerY the center Y
|
||||
* @param centerZ the center Z
|
||||
* @param strength the strength of the explosion
|
||||
* @throws IllegalStateException If no {@link ExplosionSupplier} was supplied
|
||||
*/
|
||||
public void explode(float centerX, float centerY, float centerZ, float strength) {
|
||||
|
@ -142,8 +142,8 @@ public class InstanceContainer extends Instance {
|
||||
/**
|
||||
* Has this block already changed since last update? Prevents StackOverflow with blocks trying to modify their position in onDestroy or onPlace
|
||||
*
|
||||
* @param blockPosition
|
||||
* @param blockId
|
||||
* @param blockPosition the block position
|
||||
* @param blockId the block id
|
||||
* @return
|
||||
*/
|
||||
private boolean isAlreadyChanged(BlockPosition blockPosition, short blockId) {
|
||||
|
@ -129,7 +129,7 @@ public abstract class CustomBlock {
|
||||
/**
|
||||
* Defines custom behaviour for entities touching this block.
|
||||
*
|
||||
* @param instance
|
||||
* @param instance the instance
|
||||
* @param position the position at which the block is
|
||||
* @param touching the entity currently touching the block
|
||||
*/
|
||||
@ -220,7 +220,7 @@ public abstract class CustomBlock {
|
||||
/**
|
||||
* Called when an explosion wants to destroy this block.
|
||||
*
|
||||
* @param instance
|
||||
* @param instance the instance
|
||||
* @param lootTableArguments arguments used in the loot table loot generation
|
||||
* @return 'true' if the explosion should happen on this block, 'false' to cancel the destruction.
|
||||
* Returning true does NOT block the explosion rays, ie it does not change the block explosion resistance
|
||||
@ -232,7 +232,7 @@ public abstract class CustomBlock {
|
||||
/**
|
||||
* Return the loot table associated to this block. Return null to use vanilla behavior
|
||||
*
|
||||
* @param tableManager
|
||||
* @param tableManager the loot table manager
|
||||
* @return the loot table associated to this block
|
||||
*/
|
||||
public LootTable getLootTable(LootTableManager tableManager) {
|
||||
|
@ -66,8 +66,8 @@ public class StorageManager {
|
||||
/**
|
||||
* Used to know if the specified folder already exist or not
|
||||
*
|
||||
* @param folderPath
|
||||
* @param storageSystem
|
||||
* @param folderPath the folder path
|
||||
* @param storageSystem the storage system to use
|
||||
* @return true if the folder exists, false otherwise
|
||||
*/
|
||||
public boolean folderExists(String folderPath, StorageSystem storageSystem) {
|
||||
@ -77,8 +77,8 @@ public class StorageManager {
|
||||
/**
|
||||
* Call {@link #folderExists(String, StorageSystem)} with the default StorageSystem
|
||||
*
|
||||
* @param folderPath
|
||||
* @return
|
||||
* @param folderPath the folder path
|
||||
* @return true if the folder exists
|
||||
*/
|
||||
public boolean folderExists(String folderPath) {
|
||||
return folderExists(folderPath, defaultStorageSystemSupplier.get());
|
||||
@ -93,6 +93,11 @@ public class StorageManager {
|
||||
return Collections.unmodifiableCollection(folderMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the default storage system used for {@link StorageFolder}
|
||||
*
|
||||
* @param storageSystemSupplier the supplier called to get the default {@link StorageSystem}
|
||||
*/
|
||||
public void defineDefaultStorageSystem(Supplier<StorageSystem> storageSystemSupplier) {
|
||||
if (this.defaultStorageSystemSupplier != null) {
|
||||
LOGGER.warn("The default storage-system has been changed. This could lead to issues!");
|
||||
@ -100,6 +105,11 @@ public class StorageManager {
|
||||
this.defaultStorageSystemSupplier = storageSystemSupplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if the default storage system is set
|
||||
*
|
||||
* @return true if a default storage system is set
|
||||
*/
|
||||
public boolean isDefaultStorageSystemDefined() {
|
||||
return defaultStorageSystemSupplier != null;
|
||||
}
|
||||
|
@ -1,10 +1,16 @@
|
||||
package net.minestom.server.storage;
|
||||
|
||||
/**
|
||||
* Represent a way of storing data
|
||||
* It works by using keys and values assigned to each one
|
||||
*/
|
||||
public interface StorageSystem {
|
||||
|
||||
/**
|
||||
* @param folderPath
|
||||
* @return true if the folder exists, false otherwise
|
||||
* Get if the folder exists
|
||||
*
|
||||
* @param folderPath the folder path
|
||||
* @return true if the folder exists
|
||||
*/
|
||||
boolean exists(String folderPath);
|
||||
|
||||
@ -17,7 +23,9 @@ public interface StorageSystem {
|
||||
void open(String folderPath, StorageOptions storageOptions);
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* Get the data associated to a key
|
||||
*
|
||||
* @param key the key to retrieve
|
||||
* @return the retrieved data
|
||||
*/
|
||||
byte[] get(String key);
|
||||
@ -25,15 +33,15 @@ public interface StorageSystem {
|
||||
/**
|
||||
* Set the specified data to the defined key
|
||||
*
|
||||
* @param key
|
||||
* @param data
|
||||
* @param key the key of the data
|
||||
* @param data the data
|
||||
*/
|
||||
void set(String key, byte[] data);
|
||||
|
||||
/**
|
||||
* Delete the specified key from the database
|
||||
*
|
||||
* @param key
|
||||
* @param key the key to delete
|
||||
*/
|
||||
void delete(String key);
|
||||
|
||||
|
@ -25,7 +25,6 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
|
||||
@Override
|
||||
public void onChunkLoad(Instance instance, int chunkX, int chunkZ) {
|
||||
|
||||
Map<ChunkCoordinate, Set<ChunkCoordinate>> chunksGroupMap = getChunksGroupMap(instance);
|
||||
Map<Set<ChunkCoordinate>, Instance> instanceMap = getInstanceMap(instance);
|
||||
|
||||
@ -56,10 +55,13 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
// Represent the merged group of all the neighbours
|
||||
Set<ChunkCoordinate> finalGroup = new HashSet<>();
|
||||
|
||||
// Add the newly loaded chunk to the group
|
||||
finalGroup.add(new ChunkCoordinate(chunkX, chunkZ));
|
||||
|
||||
// Add all the neighbours groups to the final one
|
||||
for (Set<ChunkCoordinate> chunkCoordinates : neighboursGroups) {
|
||||
finalGroup.addAll(chunkCoordinates);
|
||||
}
|
||||
@ -80,11 +82,13 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
|
||||
final ChunkCoordinate chunkCoordinate = new ChunkCoordinate(chunkX, chunkZ);
|
||||
if (chunksGroupMap.containsKey(chunkCoordinate)) {
|
||||
// The unloaded chunk is part of a group, remove it from the group
|
||||
Set<ChunkCoordinate> chunkCoordinates = chunksGroupMap.get(chunkCoordinate);
|
||||
chunkCoordinates.remove(chunkCoordinate);
|
||||
chunksGroupMap.remove(chunkCoordinate);
|
||||
|
||||
if (chunkCoordinates.isEmpty()) {
|
||||
// The chunk group is empty, remove it entirely
|
||||
instanceMap.entrySet().removeIf(entry -> entry.getKey().isEmpty());
|
||||
}
|
||||
}
|
||||
@ -92,20 +96,20 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
|
||||
@Override
|
||||
public void update(long time) {
|
||||
// Set of already-updated instances
|
||||
// Set of already-updated instances this tick
|
||||
final Set<Instance> updatedInstance = new HashSet<>();
|
||||
|
||||
|
||||
instanceInstanceMap.entrySet().forEach(entry -> {
|
||||
final Instance instance = entry.getKey();
|
||||
final Map<Set<ChunkCoordinate>, Instance> instanceMap = entry.getValue();
|
||||
|
||||
// Update all the chunks
|
||||
// Update all the chunks + instances
|
||||
for (Map.Entry<Set<ChunkCoordinate>, Instance> ent : instanceMap.entrySet()) {
|
||||
final Set<ChunkCoordinate> chunks = ent.getKey();
|
||||
|
||||
final boolean updateInstance = updatedInstance.add(instance);
|
||||
pool.execute(() -> {
|
||||
// Used to check if the instance has already been updated this tick
|
||||
if (updateInstance) {
|
||||
updateInstance(instance, time);
|
||||
}
|
||||
@ -127,6 +131,14 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the neighbours of a chunk and itself, no diagonals
|
||||
*
|
||||
* @param instance the instance of the chunks
|
||||
* @param chunkX the chunk X
|
||||
* @param chunkZ the chunk Z
|
||||
* @return the loaded neighbours of the chunk
|
||||
*/
|
||||
private List<ChunkCoordinate> getNeighbours(Instance instance, int chunkX, int chunkZ) {
|
||||
List<ChunkCoordinate> chunks = new ArrayList<>();
|
||||
// Constants used to loop through the neighbors
|
||||
@ -144,9 +156,8 @@ public class PerGroupChunkProvider extends ThreadProvider {
|
||||
final int targetZ = chunkZ + z;
|
||||
final Chunk chunk = instance.getChunk(targetX, targetZ);
|
||||
if (!ChunkUtils.isChunkUnloaded(chunk)) {
|
||||
// Chunk is loaded, add it
|
||||
chunks.add(toChunkCoordinate(chunk));
|
||||
} else {
|
||||
//System.out.println(targetX+" : "+targetZ);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ public class PerInstanceThreadProvider extends ThreadProvider {
|
||||
|
||||
@Override
|
||||
public void onChunkLoad(Instance instance, int chunkX, int chunkZ) {
|
||||
// Add the loaded chunk to the instance chunks list
|
||||
Set<ChunkCoordinate> chunkCoordinates = getChunkCoordinates(instance);
|
||||
chunkCoordinates.add(new ChunkCoordinate(chunkX, chunkZ));
|
||||
}
|
||||
@ -25,7 +26,7 @@ public class PerInstanceThreadProvider extends ThreadProvider {
|
||||
@Override
|
||||
public void onChunkUnload(Instance instance, int chunkX, int chunkZ) {
|
||||
Set<ChunkCoordinate> chunkCoordinates = getChunkCoordinates(instance);
|
||||
|
||||
// Remove the unloaded chunk from the instance list
|
||||
chunkCoordinates.removeIf(chunkCoordinate -> chunkCoordinate.chunkX == chunkX &&
|
||||
chunkCoordinate.chunkZ == chunkZ);
|
||||
|
||||
|
@ -183,10 +183,20 @@ public abstract class ThreadProvider {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a {@link Chunk} to a {@link ChunkCoordinate}
|
||||
*
|
||||
* @param chunk the chunk to convert
|
||||
* @return the converted {@link ChunkCoordinate}
|
||||
*/
|
||||
protected ChunkCoordinate toChunkCoordinate(Chunk chunk) {
|
||||
return new ChunkCoordinate(chunk.getChunkX(), chunk.getChunkZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Represent the coordinates of a {@link Chunk}
|
||||
* Used so the chunks objects can be cleared by the garbage collector properly¬
|
||||
*/
|
||||
protected static class ChunkCoordinate {
|
||||
public int chunkX, chunkZ;
|
||||
|
||||
|
@ -26,8 +26,10 @@ public class ArrayUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a
|
||||
* @param b
|
||||
* Get the differences between 2 arrays
|
||||
*
|
||||
* @param a the first array
|
||||
* @param b the second array
|
||||
* @return an array containing a's indexes that aren't in b array
|
||||
*/
|
||||
public static int[] getDifferencesBetweenArray(long[] a, long[] b) {
|
||||
|
@ -33,8 +33,8 @@ public class NBTUtils {
|
||||
/**
|
||||
* Loads all the items from the 'items' list into the given inventory
|
||||
*
|
||||
* @param items
|
||||
* @param destination
|
||||
* @param items the items to save
|
||||
* @param destination the inventory destination
|
||||
*/
|
||||
public static void loadAllItems(NBTList<NBTCompound> items, Inventory destination) {
|
||||
destination.clear();
|
||||
|
@ -36,7 +36,7 @@ public class WeightedRandom<E extends WeightedRandomItem> {
|
||||
* Gets a random element from this set
|
||||
*
|
||||
* @param rng Random Number Generator to generate random numbers with
|
||||
* @return
|
||||
* @return a random element from this set
|
||||
*/
|
||||
public E get(Random rng) {
|
||||
final double p = rng.nextDouble() * totalWeight;
|
||||
|
Loading…
Reference in New Issue
Block a user