collect all server options in ServerFlag file, other minor changes

This commit is contained in:
mworzala 2023-09-08 08:18:48 -04:00 committed by Matt Worzala
parent 7e2eb9c67b
commit 351d2197b1
23 changed files with 171 additions and 152 deletions

View File

@ -63,6 +63,7 @@ dependencies {
api(libs.bundles.kotlin)
api(libs.bundles.hephaistos)
implementation(libs.minestomData)
implementation(libs.dependencyGetter)
// Libraries required for the terminal
implementation(libs.bundles.terminal)

View File

@ -6,6 +6,7 @@ metadata.format.version = "1.1"
data = "1.20-rv1"
adventure = "4.12.0"
kotlin = "1.7.22"
dependencyGetter = "v1.0.1"
hydrazine = "1.7.2"
hephaistos = "2.6.1"
jetbrainsAnnotations = "23.0.0"
@ -55,6 +56,7 @@ kotlin-stdlib-jdk8 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk
# Miscellaneous
hydrazine = { group = "com.github.MadMartian", name = "hydrazine-path-finding", version.ref = "hydrazine" }
minestomData = { group = "net.minestom", name = "data", version.ref = "data" }
dependencyGetter = { group = "com.github.Minestom", name = "DependencyGetter", version.ref = "dependencyGetter" }
jetbrainsAnnotations = { group = "org.jetbrains", name = "annotations", version.ref = "jetbrainsAnnotations" }
hephaistos-common = { group = "io.github.jglrxavpok.hephaistos", name = "common", version.ref = "hephaistos" }
hephaistos-gson = { group = "io.github.jglrxavpok.hephaistos", name = "gson", version.ref = "hephaistos" }

View File

@ -29,6 +29,7 @@ import net.minestom.server.world.DimensionTypeManager;
import net.minestom.server.world.biomes.BiomeManager;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import java.io.IOException;
@ -56,16 +57,14 @@ public final class MinecraftServer {
// Config
// Can be modified at performance cost when increased
public static final int TICK_PER_SECOND = Integer.getInteger("minestom.tps", 20);
@Deprecated
public static final int TICK_PER_SECOND = ServerFlag.SERVER_TICKS_PER_SECOND;
public static final int TICK_MS = 1000 / TICK_PER_SECOND;
// In-Game Manager
private static volatile ServerProcess serverProcess;
private static int chunkViewDistance = Integer.getInteger("minestom.chunk-view-distance", 8);
private static int entityViewDistance = Integer.getInteger("minestom.entity-view-distance", 5);
private static int compressionThreshold = 256;
private static boolean terminalEnabled = System.getProperty("minestom.terminal.disabled") == null;
private static String brandName = "Minestom";
private static Difficulty difficulty = Difficulty.NORMAL;
@ -199,50 +198,26 @@ public final class MinecraftServer {
/**
* Gets the chunk view distance of the server.
* <p>
* Deprecated in favor of {@link ServerFlag#CHUNK_VIEW_DISTANCE}
*
* @return the chunk view distance
*/
public static int getChunkViewDistance() {
return chunkViewDistance;
}
/**
* Changes the chunk view distance of the server.
*
* @param chunkViewDistance the new chunk view distance
* @throws IllegalArgumentException if {@code chunkViewDistance} is not between 2 and 32
* @deprecated should instead be defined with a java property
*/
@Deprecated
public static void setChunkViewDistance(int chunkViewDistance) {
Check.stateCondition(serverProcess.isAlive(), "You cannot change the chunk view distance after the server has been started.");
Check.argCondition(!MathUtils.isBetween(chunkViewDistance, 2, 32),
"The chunk view distance must be between 2 and 32");
MinecraftServer.chunkViewDistance = chunkViewDistance;
public static int getChunkViewDistance() {
return ServerFlag.CHUNK_VIEW_DISTANCE;
}
/**
* Gets the entity view distance of the server.
* <p>
* Deprecated in favor of {@link ServerFlag#ENTITY_VIEW_DISTANCE}
*
* @return the entity view distance
*/
public static int getEntityViewDistance() {
return entityViewDistance;
}
/**
* Changes the entity view distance of the server.
*
* @param entityViewDistance the new entity view distance
* @throws IllegalArgumentException if {@code entityViewDistance} is not between 0 and 32
* @deprecated should instead be defined with a java property
*/
@Deprecated
public static void setEntityViewDistance(int entityViewDistance) {
Check.stateCondition(serverProcess.isAlive(), "You cannot change the entity view distance after the server has been started.");
Check.argCondition(!MathUtils.isBetween(entityViewDistance, 0, 32),
"The entity view distance must be between 0 and 32");
MinecraftServer.entityViewDistance = entityViewDistance;
public static int getEntityViewDistance() {
return ServerFlag.ENTITY_VIEW_DISTANCE;
}
/**
@ -267,25 +242,6 @@ public final class MinecraftServer {
MinecraftServer.compressionThreshold = compressionThreshold;
}
/**
* Gets if the built in Minestom terminal is enabled.
*
* @return true if the terminal is enabled
*/
public static boolean isTerminalEnabled() {
return terminalEnabled;
}
/**
* Enabled/disables the built in Minestom terminal.
*
* @param enabled true to enable, false to disable
*/
public static void setTerminalEnabled(boolean enabled) {
Check.stateCondition(serverProcess.isAlive(), "Terminal settings may not be changed after starting the server.");
MinecraftServer.terminalEnabled = enabled;
}
public static DimensionTypeManager getDimensionTypeManager() {
return serverProcess.dimension();
}
@ -298,7 +254,7 @@ public final class MinecraftServer {
return serverProcess.advancement();
}
public static ExtensionManager getExtensionManager() {
public static @Nullable ExtensionManager getExtensionManager() {
return serverProcess.extension();
}

View File

@ -0,0 +1,69 @@
package net.minestom.server;
import net.minestom.server.utils.PropertyUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Contains server settings/flags to be set with system properties.
* <p/>
* Some flags (labeled at the bottom) are experimental. They may be removed without notice, and may have issues.
*/
public final class ServerFlag {
// Server Behavior
public static final int SERVER_TICKS_PER_SECOND = Integer.getInteger("minestom.tps", 20);
public static final int CHUNK_VIEW_DISTANCE = Integer.getInteger("minestom.chunk-view-distance", 8);
public static final int ENTITY_VIEW_DISTANCE = Integer.getInteger("minestom.entity-view-distance", 5);
public static final int WORKER_COUNT = Integer.getInteger("minestom.workers", Runtime.getRuntime().availableProcessors());
public static final int MAX_PACKET_SIZE = Integer.getInteger("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
public static final int SOCKET_SEND_BUFFER_SIZE = Integer.getInteger("minestom.send-buffer-size", 262_143);
public static final int SOCKET_RECEIVE_BUFFER_SIZE = Integer.getInteger("minestom.receive-buffer-size", 32_767);
public static final int POOLED_BUFFER_SIZE = Integer.getInteger("minestom.pooled-buffer-size", 262_143);
public static final int PLAYER_PACKET_PER_TICK = Integer.getInteger("minestom.packet-per-tick", 20);
public static final int PLAYER_PACKET_QUEUE_SIZE = Integer.getInteger("minestom.packet-queue-size", 1000);
// Packet sending optimizations
public static final boolean GROUPED_PACKET = PropertyUtils.getBoolean("minestom.grouped-packet", true);
public static final boolean CACHED_PACKET = PropertyUtils.getBoolean("minestom.cached-packet", true);
public static final boolean VIEWABLE_PACKET = PropertyUtils.getBoolean("minestom.viewable-packet", true);
// Tags
public static final boolean TAG_HANDLER_CACHE_ENABLED = PropertyUtils.getBoolean("minestom.tag-handler-cache", true);
public static final boolean SERIALIZE_EMPTY_COMPOUND = PropertyUtils.getBoolean("minestom.serialization.serialize-empty-nbt-compound", false);
// Online Mode
public static final @NotNull String AUTH_URL = System.getProperty("minestom.auth.url", "https://sessionserver.mojang.com/session/minecraft/hasJoined");
// World
public static final @Nullable String STACKING_RULE = System.getProperty("minestom.stacking-rule");
public static final int WORLD_BORDER_SIZE = Integer.getInteger("minestom.world-border-size", 29999984);
// Terminal
public static final boolean TERMINAL_ENABLED = System.getProperty("minestom.terminal.disabled") == null;
public static final boolean TERMINAL_SUPPORT_HEX_COLOR = PropertyUtils.getBoolean("minestom.terminal.support-hex-color", true);
public static final boolean TERMINAL_SUPPORT_COLOR = PropertyUtils.getBoolean("minestom.terminal.support-color", true);
// Extensions todo use enabled flag
public static final boolean EXTENSIONS_ENABLED = PropertyUtils.getBoolean("minestom.extension.enabled", false);
public static final @NotNull String EXTENSIONS_FOLDER = System.getProperty("minestom.extension.folder", "extensions");
public static final @Nullable String EXTENSIONS_DEV_CLASSES = System.getProperty("minestom.extension.indevfolder.classes");
public static final @Nullable String EXTENSIONS_DEV_RESOURCES = System.getProperty("minestom.extension.indevfolder.resources");
// Maps
public static final @NotNull String MAP_RGB_MAPPING = System.getProperty("minestom.map.rgbmapping", "lazy");
public static final @Nullable String MAP_RGB_REDUCTION = System.getProperty("minestom.map.rgbreduction"); // Only used if rgb mapping is "approximate"
// Experimental/Unstable
public static final boolean USE_NEW_CHUNK_SENDING = Boolean.getBoolean("minestom.use-new-chunk-sending");
public static final int NEW_CHUNK_COUNT_PER_INTERVAL = Integer.getInteger("minestom.new-chunk-sending-count-per-interval", 50);
public static final int NEW_CHUNK_SEND_INTERVAL = Integer.getInteger("minestom.new-chunk-sending-send-interval", 20);
public static final int LIGHTING_CHUNKS_PER_SEND = Integer.getInteger("minestom.lighting.chunks-per-send", 10);
public static final int LIGHTING_CHUNKS_SEND_DELAY = Integer.getInteger("minestom.lighting.chunks-send-delay", 100);
public static final boolean EVENT_NODE_ALLOW_MULTIPLE_PARENTS = Boolean.getBoolean("minestom.event.multiple-parents");
private ServerFlag() {}
}

View File

@ -25,6 +25,7 @@ import net.minestom.server.world.DimensionTypeManager;
import net.minestom.server.world.biomes.BiomeManager;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.net.SocketAddress;
@ -99,7 +100,7 @@ public interface ServerProcess extends Snapshotable {
/**
* Loads and handle extensions.
*/
@NotNull ExtensionManager extension();
@Nullable ExtensionManager extension();
/**
* Handles registry tags.

View File

@ -33,6 +33,7 @@ import net.minestom.server.utils.collection.MappedCollection;
import net.minestom.server.world.DimensionTypeManager;
import net.minestom.server.world.biomes.BiomeManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -74,7 +75,7 @@ final class ServerProcessImpl implements ServerProcess {
public ServerProcessImpl() throws IOException {
this.exception = new ExceptionManager();
this.extension = new ExtensionManager(this);
this.extension = ServerFlag.EXTENSIONS_ENABLED ? new ExtensionManager(this) : null;
this.connection = new ConnectionManager();
this.packetProcessor = new PacketProcessor();
this.packetListener = new PacketListenerManager(this);
@ -163,7 +164,7 @@ final class ServerProcessImpl implements ServerProcess {
}
@Override
public @NotNull ExtensionManager extension() {
public @Nullable ExtensionManager extension() {
return extension;
}
@ -208,12 +209,16 @@ final class ServerProcessImpl implements ServerProcess {
throw new IllegalStateException("Server already started");
}
if (ServerFlag.EXTENSIONS_ENABLED) {
extension.start();
extension.gotoPreInit();
}
LOGGER.info("Starting " + MinecraftServer.getBrandName() + " server.");
if (ServerFlag.EXTENSIONS_ENABLED) {
extension.gotoInit();
}
// Init server
try {
@ -226,11 +231,13 @@ final class ServerProcessImpl implements ServerProcess {
// Start server
server.start();
if (ServerFlag.EXTENSIONS_ENABLED) {
extension.gotoPostInit();
}
LOGGER.info(MinecraftServer.getBrandName() + " server started successfully.");
if (MinecraftServer.isTerminalEnabled()) {
if (ServerFlag.TERMINAL_ENABLED) {
MinestomTerminal.start();
}
// Stop the server on SIGINT
@ -242,8 +249,10 @@ final class ServerProcessImpl implements ServerProcess {
if (!stopped.compareAndSet(false, true))
return;
LOGGER.info("Stopping " + MinecraftServer.getBrandName() + " server.");
if (ServerFlag.EXTENSIONS_ENABLED) {
LOGGER.info("Unloading all extensions.");
extension.shutdown();
}
scheduler.shutdown();
connection.shutdown();
server.stop();

View File

@ -16,6 +16,7 @@ import net.kyori.adventure.text.event.HoverEventSource;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.title.TitlePart;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.advancements.AdvancementTab;
import net.minestom.server.adventure.AdventurePacketConvertor;
import net.minestom.server.adventure.Localizable;
@ -112,8 +113,6 @@ import java.util.function.UnaryOperator;
*/
public class Player extends LivingEntity implements CommandSender, Localizable, HoverEventSource<ShowEntity>, Identified, NamedAndIdentified {
private static final Component REMOVE_MESSAGE = Component.text("You have been removed from the server without reason.", NamedTextColor.RED);
private static final int PACKET_PER_TICK = Integer.getInteger("minestom.packet-per-tick", 20);
private static final int PACKET_QUEUE_SIZE = Integer.getInteger("minestom.packet-queue-size", 1000);
private long lastKeepAlive;
private boolean answerKeepAlive;
@ -706,21 +705,21 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
chunkUpdateLimitChecker.addToHistory(getChunk());
sendPacket(new UpdateViewPositionPacket(chunkX, chunkZ));
if (ChunkUtils.USE_NEW_CHUNK_SENDING) {
if (ServerFlag.USE_NEW_CHUNK_SENDING) {
// FIXME: Improve this queueing. It is pretty scuffed
var chunkQueue = new LongArrayList();
ChunkUtils.forChunksInRange(spawnPosition, MinecraftServer.getChunkViewDistance(),
(x, z) -> chunkQueue.add(ChunkUtils.getChunkIndex(x, z)));
var iter = chunkQueue.iterator();
Supplier<TaskSchedule> taskRunnable = () -> {
for (int i = 0; i < ChunkUtils.NEW_CHUNK_COUNT_PER_INTERVAL; i++) {
for (int i = 0; i < ServerFlag.NEW_CHUNK_COUNT_PER_INTERVAL; i++) {
if (!iter.hasNext()) return TaskSchedule.stop();
var next = iter.nextLong();
chunkAdder.accept(ChunkUtils.getChunkCoordX(next), ChunkUtils.getChunkCoordZ(next));
}
return TaskSchedule.tick(ChunkUtils.NEW_CHUNK_SEND_INTERVAL);
return TaskSchedule.tick(ServerFlag.NEW_CHUNK_SEND_INTERVAL);
};
scheduler().submitTask(taskRunnable);
} else {
@ -1873,13 +1872,13 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
@ApiStatus.Internal
@ApiStatus.Experimental
public void interpretPacketQueue() {
if (this.packets.size() >= PACKET_QUEUE_SIZE) {
if (this.packets.size() >= ServerFlag.PLAYER_PACKET_QUEUE_SIZE) {
kick(Component.text("Too Many Packets", NamedTextColor.RED));
return;
}
final PacketListenerManager manager = MinecraftServer.getPacketListenerManager();
// This method is NOT thread-safe
this.packets.drain(packet -> manager.processClientPacket(packet, this), PACKET_PER_TICK);
this.packets.drain(packet -> manager.processClientPacket(packet, this), ServerFlag.PLAYER_PACKET_PER_TICK);
}
/**

View File

@ -2,6 +2,7 @@ package net.minestom.server.event;
import com.github.benmanes.caffeine.cache.Caffeine;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.event.trait.RecursiveEvent;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Contract;
@ -18,7 +19,6 @@ import java.util.function.BiPredicate;
import java.util.function.Consumer;
non-sealed class EventNodeImpl<T extends Event> implements EventNode<T> {
private static final boolean ALLOW_MULTIPLE_PARENTS = Boolean.getBoolean("minestom.event.multiple-parents");
static final Object GLOBAL_CHILD_LOCK = new Object();
@ -109,7 +109,7 @@ non-sealed class EventNodeImpl<T extends Event> implements EventNode<T> {
public @NotNull EventNode<T> addChild(@NotNull EventNode<? extends T> child) {
synchronized (GLOBAL_CHILD_LOCK) {
final var childImpl = (EventNodeImpl<? extends T>) child;
Check.stateCondition(!ALLOW_MULTIPLE_PARENTS && childImpl.parent != null, "Node already has a parent");
Check.stateCondition(!ServerFlag.EVENT_NODE_ALLOW_MULTIPLE_PARENTS && childImpl.parent != null, "Node already has a parent");
Check.stateCondition(Objects.equals(parent, child), "Cannot have a child as parent");
if (!children.add((EventNodeImpl<T>) childImpl)) return this; // Couldn't add the child (already present?)
childImpl.parent = this;
@ -220,7 +220,7 @@ non-sealed class EventNodeImpl<T extends Event> implements EventNode<T> {
@Override
public @Nullable EventNode<? super T> getParent() {
Check.stateCondition(ALLOW_MULTIPLE_PARENTS, "Cannot use getParent when multiple parents are allowed");
Check.stateCondition(ServerFlag.EVENT_NODE_ALLOW_MULTIPLE_PARENTS, "Cannot use getParent when multiple parents are allowed");
return parent;
}

View File

@ -4,6 +4,7 @@ import com.google.gson.Gson;
import net.minestom.dependencies.DependencyGetter;
import net.minestom.dependencies.ResolvedDependency;
import net.minestom.dependencies.maven.MavenRepository;
import net.minestom.server.ServerFlag;
import net.minestom.server.ServerProcess;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.ApiStatus;
@ -26,8 +27,6 @@ public class ExtensionManager {
public final static Logger LOGGER = LoggerFactory.getLogger(ExtensionManager.class);
public final static String INDEV_CLASSES_FOLDER = "minestom.extension.indevfolder.classes";
public final static String INDEV_RESOURCES_FOLDER = "minestom.extension.indevfolder.resources";
private final static Gson GSON = new Gson();
private final ServerProcess serverProcess;
@ -36,7 +35,7 @@ public class ExtensionManager {
private final Map<String, Extension> extensions = new LinkedHashMap<>();
private final Map<String, Extension> immutableExtensions = Collections.unmodifiableMap(extensions);
private final File extensionFolder = new File(System.getProperty("minestom.extension.folder", "extensions"));
private final File extensionFolder = new File(ServerFlag.EXTENSIONS_FOLDER);
private final File dependenciesFolder = new File(extensionFolder, ".libs");
private Path extensionDataRoot = extensionFolder.toPath();
@ -371,14 +370,13 @@ public class ExtensionManager {
//TODO(mattw): Should show a warning if one is set and not the other. It is most likely a mistake.
// this allows developers to have their extension discovered while working on it, without having to build a jar and put in the extension folder
if (System.getProperty(INDEV_CLASSES_FOLDER) != null && System.getProperty(INDEV_RESOURCES_FOLDER) != null) {
if (ServerFlag.EXTENSIONS_DEV_CLASSES != null && ServerFlag.EXTENSIONS_DEV_RESOURCES != null) {
LOGGER.info("Found indev folders for extension. Adding to list of discovered extensions.");
final String extensionClasses = System.getProperty(INDEV_CLASSES_FOLDER);
final String extensionResources = System.getProperty(INDEV_RESOURCES_FOLDER);
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(new File(extensionResources, "extension.json")))) {
final File extensionJsonFile = new File(ServerFlag.EXTENSIONS_DEV_RESOURCES, "extension.json");
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(extensionJsonFile))) {
DiscoveredExtension extension = GSON.fromJson(reader, DiscoveredExtension.class);
extension.files.add(new File(extensionClasses).toURI().toURL());
extension.files.add(new File(extensionResources).toURI().toURL());
extension.files.add(new File(ServerFlag.EXTENSIONS_DEV_CLASSES).toURI().toURL());
extension.files.add(new File(ServerFlag.EXTENSIONS_DEV_RESOURCES).toURI().toURL());
extension.setDataDirectory(getExtensionDataRoot().resolve(extension.getName()));
// Verify integrity and ensure defaults

View File

@ -1,6 +1,7 @@
package net.minestom.server.extras;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.extras.mojangAuth.MojangCrypt;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.Nullable;
@ -8,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
import java.security.KeyPair;
public final class MojangAuth {
public static final String AUTH_URL = System.getProperty("minestom.auth.url", "https://sessionserver.mojang.com/session/minecraft/hasJoined").concat("?username=%s&serverId=%s");
public static final String AUTH_URL = ServerFlag.AUTH_URL.concat("?username=%s&serverId=%s");
private static volatile boolean enabled = false;
private static volatile KeyPair keyPair;

View File

@ -3,6 +3,7 @@ package net.minestom.server.instance;
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.collision.Shape;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
@ -31,9 +32,6 @@ import static net.minestom.server.instance.light.LightCompute.emptyContent;
public class LightingChunk extends DynamicChunk {
private static final int LIGHTING_CHUNKS_PER_SEND = Integer.getInteger("minestom.lighting.chunks-per-send", 10);
private static final int LIGHTING_CHUNKS_SEND_DELAY = Integer.getInteger("minestom.lighting.chunks-send-delay", 100);
private static final ExecutorService pool = Executors.newWorkStealingPool();
private int[] heightmap;
@ -291,10 +289,10 @@ public class LightingChunk extends DynamicChunk {
}
count++;
if (count % LIGHTING_CHUNKS_PER_SEND == 0) {
if (count % ServerFlag.LIGHTING_CHUNKS_PER_SEND == 0) {
// System.out.println("Sent " + count + " lighting chunks " + (count * 100 / copy.size()) + "%");
try {
Thread.sleep(LIGHTING_CHUNKS_SEND_DELAY);
Thread.sleep(ServerFlag.LIGHTING_CHUNKS_SEND_DELAY);
} catch (InterruptedException e) {
e.printStackTrace();
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.instance;
import net.minestom.server.ServerFlag;
import net.minestom.server.coordinate.Point;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
@ -39,7 +40,7 @@ public class WorldBorder {
this.speed = 0;
this.portalTeleportBoundary = Integer.getInteger("minestom.world-border-size", 29999984);
this.portalTeleportBoundary = ServerFlag.WORLD_BORDER_SIZE;
}
/**

View File

@ -1,5 +1,6 @@
package net.minestom.server.item;
import net.minestom.server.ServerFlag;
import net.minestom.server.item.rule.VanillaStackingRule;
import net.minestom.server.tag.Tag;
import net.minestom.server.tag.TagHandler;
@ -18,13 +19,12 @@ record ItemStackImpl(Material material, int amount, ItemMetaImpl meta) implement
static final @NotNull StackingRule DEFAULT_STACKING_RULE;
static {
final String stackingRuleProperty = System.getProperty("minestom.stacking-rule");
if (stackingRuleProperty == null) {
if (ServerFlag.STACKING_RULE == null) {
DEFAULT_STACKING_RULE = new VanillaStackingRule();
} else {
try {
DEFAULT_STACKING_RULE = (StackingRule) ClassLoader.getSystemClassLoader()
.loadClass(stackingRuleProperty).getConstructor().newInstance();
.loadClass(ServerFlag.STACKING_RULE).getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Could not instantiate default stacking rule", e);
}

View File

@ -1,6 +1,9 @@
package net.minestom.server.map;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@ -70,44 +73,35 @@ public enum MapColors {
private final int green;
private final int blue;
private static final Logger logger = LoggerFactory.getLogger(MapColors.class);
private static final ConcurrentHashMap<Integer, PreciseMapColor> rgbMap = new ConcurrentHashMap<>();
// only used if mappingStrategy == ColorMappingStrategy.PRECISE
private static volatile PreciseMapColor[] rgbArray = null;
private static final ColorMappingStrategy mappingStrategy;
private static final String MAPPING_ARGUMENT = "minestom.map.rgbmapping";
// only used if MAPPING_ARGUMENT is "approximate"
private static final String REDUCTION_ARGUMENT = "minestom.map.rgbreduction";
private static final int colorReduction;
static {
ColorMappingStrategy strategy;
String strategyStr = System.getProperty(MAPPING_ARGUMENT);
if (strategyStr == null) {
strategy = ColorMappingStrategy.LAZY;
} else {
try {
strategy = ColorMappingStrategy.valueOf(strategyStr.toUpperCase());
strategy = ColorMappingStrategy.valueOf(ServerFlag.MAP_RGB_MAPPING.toUpperCase());
} catch (IllegalArgumentException e) {
System.err.println("Unknown color mapping strategy: " + strategyStr);
System.err.println("Defaulting to LAZY.");
logger.warn("Unknown color mapping strategy '{}', defaulting to LAZY.", ServerFlag.MAP_RGB_MAPPING);
strategy = ColorMappingStrategy.LAZY;
}
}
mappingStrategy = strategy;
int reduction = 10;
String reductionStr = System.getProperty(REDUCTION_ARGUMENT);
if (reductionStr != null) {
if (ServerFlag.MAP_RGB_REDUCTION != null) {
try {
reduction = Integer.parseInt(reductionStr);
reduction = Integer.parseInt(ServerFlag.MAP_RGB_REDUCTION);
} catch (NumberFormatException e) {
System.err.println("Invalid integer in reduction argument: " + reductionStr);
logger.error("Invalid integer in reduction argument: {}", ServerFlag.MAP_RGB_REDUCTION);
MinecraftServer.getExceptionManager().handleException(e);
}
if (reduction < 0 || reduction >= 255) {
System.err.println("Reduction was found to be invalid: " + reduction + ". Must in 0-255, defaulting to 10.");
logger.warn("Reduction was found to be invalid: {}. Must in 0-255, defaulting to 10.", reduction);
reduction = 10;
}
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.network.packet.server;
import net.minestom.server.ServerFlag;
import net.minestom.server.utils.PacketUtils;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ -44,7 +45,7 @@ public final class CachedPacket implements SendablePacket {
}
private @Nullable FramedPacket updatedCache() {
if (!PacketUtils.CACHED_PACKET)
if (!ServerFlag.CACHED_PACKET)
return null;
SoftReference<FramedPacket> ref = packet;
FramedPacket cache;

View File

@ -1,6 +1,7 @@
package net.minestom.server.network.socket;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.network.PacketProcessor;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ -16,10 +17,6 @@ import java.util.Arrays;
import java.util.List;
public final class Server {
public static final int WORKER_COUNT = Integer.getInteger("minestom.workers", Runtime.getRuntime().availableProcessors());
public static final int MAX_PACKET_SIZE = Integer.getInteger("minestom.max-packet-size", 2_097_151); // 3 bytes var-int
public static final int SOCKET_SEND_BUFFER_SIZE = Integer.getInteger("minestom.send-buffer-size", 262_143);
public static final int SOCKET_RECEIVE_BUFFER_SIZE = Integer.getInteger("minestom.receive-buffer-size", 32_767);
public static final boolean NO_DELAY = true;
@ -37,7 +34,7 @@ public final class Server {
public Server(PacketProcessor packetProcessor) throws IOException {
this.packetProcessor = packetProcessor;
Worker[] workers = new Worker[WORKER_COUNT];
Worker[] workers = new Worker[ServerFlag.WORKER_COUNT];
Arrays.setAll(workers, value -> new Worker(this));
this.workers = List.of(workers);
}
@ -133,7 +130,7 @@ public final class Server {
}
private Worker findWorker() {
this.index = ++index % WORKER_COUNT;
this.index = ++index % ServerFlag.WORKER_COUNT;
return workers.get(index);
}
}

View File

@ -1,6 +1,7 @@
package net.minestom.server.network.socket;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.network.player.PlayerSocketConnection;
import net.minestom.server.thread.MinestomThread;
import net.minestom.server.utils.ObjectPool;
@ -112,8 +113,8 @@ public final class Worker extends MinestomThread {
channel.register(selector, SelectionKey.OP_READ);
if (channel.getLocalAddress() instanceof InetSocketAddress) {
Socket socket = channel.socket();
socket.setSendBufferSize(Server.SOCKET_SEND_BUFFER_SIZE);
socket.setReceiveBufferSize(Server.SOCKET_RECEIVE_BUFFER_SIZE);
socket.setSendBufferSize(ServerFlag.SOCKET_SEND_BUFFER_SIZE);
socket.setReceiveBufferSize(ServerFlag.SOCKET_RECEIVE_BUFFER_SIZE);
socket.setTcpNoDelay(Server.NO_DELAY);
socket.setSoTimeout(30 * 1000); // 30 seconds
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.tag;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minestom.server.ServerFlag;
import net.minestom.server.item.ItemStack;
import org.jglrxavpok.hephaistos.nbt.*;
@ -12,8 +13,6 @@ import java.util.function.Function;
* Basic serializers for {@link Tag tags}.
*/
final class Serializers {
static final boolean SERIALIZE_EMPTY_COMPOUND = System.getProperty("minestom.serialization.serialize-empty-nbt-compound", "false").equalsIgnoreCase("true");
static final Entry<Byte, NBTByte> BYTE = new Entry<>(NBTType.TAG_Byte, NBTByte::getValue, NBT::Byte);
static final Entry<Boolean, NBTByte> BOOLEAN = new Entry<>(NBTType.TAG_Byte, NBTByte::asBoolean, NBT::Boolean);
static final Entry<Short, NBTShort> SHORT = new Entry<>(NBTType.TAG_Short, NBTShort::getValue, NBT::Short);
@ -35,7 +34,7 @@ final class Serializers {
static <T> Entry<T, NBTCompound> fromTagSerializer(TagSerializer<T> serializer) {
return new Serializers.Entry<>(NBTType.TAG_Compound,
(NBTCompound compound) -> {
if ((!SERIALIZE_EMPTY_COMPOUND) && compound.isEmpty()) return null;
if ((!ServerFlag.SERIALIZE_EMPTY_COMPOUND) && compound.isEmpty()) return null;
return serializer.read(TagHandler.fromCompound(compound));
},
(value) -> {

View File

@ -1,5 +1,6 @@
package net.minestom.server.tag;
import net.minestom.server.ServerFlag;
import net.minestom.server.utils.PropertyUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@ -16,7 +17,6 @@ import java.util.Map;
import java.util.function.UnaryOperator;
final class TagHandlerImpl implements TagHandler {
private static final boolean CACHE_ENABLE = PropertyUtils.getBoolean("minestom.tag-handler-cache", true);
static final Serializers.Entry<Node, NBTCompound> NODE_SERIALIZER = new Serializers.Entry<>(NBTType.TAG_Compound, entries -> fromCompound(entries).root, Node::compound, true);
private final Node root;
@ -276,12 +276,12 @@ final class TagHandlerImpl implements TagHandler {
NBTCompound compound() {
NBTCompound compound;
if (!CACHE_ENABLE || (compound = this.compound) == null) {
if (!ServerFlag.TAG_HANDLER_CACHE_ENABLED || (compound = this.compound) == null) {
MutableNBTCompound tmp = new MutableNBTCompound();
this.entries.forValues(entry -> {
final Tag tag = entry.tag;
final NBT nbt = entry.updatedNbt();
if (nbt != null && !tag.entry.isPath() || (!Serializers.SERIALIZE_EMPTY_COMPOUND) && !((NBTCompound) nbt).isEmpty()) {
if (nbt != null && !tag.entry.isPath() || (!ServerFlag.SERIALIZE_EMPTY_COMPOUND) && !((NBTCompound) nbt).isEmpty()) {
tmp.put(tag.getKey(), nbt);
}
});
@ -314,7 +314,7 @@ final class TagHandlerImpl implements TagHandler {
tmp.put(tag.getKey(), nbt);
entries.put(tag.index, valueToEntry(result, tag, value));
});
if ((!Serializers.SERIALIZE_EMPTY_COMPOUND) && tmp.isEmpty() && parent != null)
if ((!ServerFlag.SERIALIZE_EMPTY_COMPOUND) && tmp.isEmpty() && parent != null)
return null; // Empty child node
result.compound = tmp.toCompound();
return result;

View File

@ -2,6 +2,7 @@ package net.minestom.server.terminal;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.minestom.server.ServerFlag;
import net.minestom.server.utils.PropertyUtils;
import java.util.regex.Matcher;
@ -14,8 +15,6 @@ import java.util.regex.Pattern;
* @see <a href="https://github.com/PaperMC/Paper/blob/41647af74caed955c1fd5b38d458ee59298ae5d4/patches/server/0591-Add-support-for-hex-color-codes-in-console.patch">Paper</a>
*/
final class TerminalColorConverter {
private static final boolean SUPPORT_HEX_COLOR = PropertyUtils.getBoolean("minestom.terminal.support-hex-color", true);
private static final boolean SUPPORT_COLOR = PropertyUtils.getBoolean("minestom.terminal.support-color", true);
private static final String RGB_ANSI = "\u001B[38;2;%d;%d;%dm";
private static final String ANSI_RESET = "\u001B[m";
@ -55,7 +54,7 @@ final class TerminalColorConverter {
}
private static String getAnsiColorFromHexColor(int color, String fallback) {
return SUPPORT_HEX_COLOR ? String.format(RGB_ANSI, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF) : fallback;
return ServerFlag.TERMINAL_SUPPORT_HEX_COLOR ? String.format(RGB_ANSI, (color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF) : fallback;
}
private static String getAnsiColorFromHexColor(int color) {
@ -74,7 +73,7 @@ final class TerminalColorConverter {
}
string = RGB_PATTERN.matcher(string).replaceAll(match -> {
if (SUPPORT_COLOR) {
if (ServerFlag.TERMINAL_SUPPORT_COLOR) {
String hex = match.group(1);
return getAnsiColorFromHexColor(Integer.parseInt(hex, 16));
} else {
@ -87,14 +86,14 @@ final class TerminalColorConverter {
while (matcher.find()) {
int format = LOOKUP.indexOf(Character.toLowerCase(matcher.group().charAt(1)));
if (format != -1) {
matcher.appendReplacement(builder, SUPPORT_COLOR ? ANSI_CODES[format] : "");
matcher.appendReplacement(builder, ServerFlag.TERMINAL_SUPPORT_COLOR ? ANSI_CODES[format] : "");
} else {
matcher.appendReplacement(builder, matcher.group());
}
}
matcher.appendTail(builder);
if (SUPPORT_COLOR) {
if (ServerFlag.TERMINAL_SUPPORT_COLOR) {
builder.append(ANSI_RESET);
}
return builder.toString();

View File

@ -1,5 +1,6 @@
package net.minestom.server.utils;
import net.minestom.server.ServerFlag;
import net.minestom.server.network.socket.Server;
import net.minestom.server.utils.binary.BinaryBuffer;
import org.jctools.queues.MessagePassingQueue;
@ -20,10 +21,9 @@ import java.util.function.UnaryOperator;
@ApiStatus.Experimental
public final class ObjectPool<T> {
private static final int QUEUE_SIZE = 32_768;
private static final int BUFFER_SIZE = Integer.getInteger("minestom.pooled-buffer-size", 262_143);
public static final ObjectPool<BinaryBuffer> BUFFER_POOL = new ObjectPool<>(() -> BinaryBuffer.ofSize(BUFFER_SIZE), BinaryBuffer::clear);
public static final ObjectPool<ByteBuffer> PACKET_POOL = new ObjectPool<>(() -> ByteBuffer.allocateDirect(Server.MAX_PACKET_SIZE), ByteBuffer::clear);
public static final ObjectPool<BinaryBuffer> BUFFER_POOL = new ObjectPool<>(() -> BinaryBuffer.ofSize(ServerFlag.POOLED_BUFFER_SIZE), BinaryBuffer::clear);
public static final ObjectPool<ByteBuffer> PACKET_POOL = new ObjectPool<>(() -> ByteBuffer.allocateDirect(ServerFlag.MAX_PACKET_SIZE), ByteBuffer::clear);
private final Cleaner cleaner = Cleaner.create();
private final MessagePassingQueue<SoftReference<T>> pool = new MpmcUnboundedXaddArrayQueue<>(QUEUE_SIZE);

View File

@ -11,6 +11,7 @@ import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.minestom.server.MinecraftServer;
import net.minestom.server.ServerFlag;
import net.minestom.server.Viewable;
import net.minestom.server.adventure.ComponentHolder;
import net.minestom.server.adventure.MinestomAdventure;
@ -47,10 +48,6 @@ import java.util.zip.Inflater;
public final class PacketUtils {
private static final ThreadLocal<Deflater> LOCAL_DEFLATER = ThreadLocal.withInitial(Deflater::new);
public static final boolean GROUPED_PACKET = PropertyUtils.getBoolean("minestom.grouped-packet", true);
public static final boolean CACHED_PACKET = PropertyUtils.getBoolean("minestom.cached-packet", true);
public static final boolean VIEWABLE_PACKET = PropertyUtils.getBoolean("minestom.viewable-packet", true);
// Viewable packets
private static final Cache<Viewable, ViewableStorage> VIEWABLE_STORAGE_MAP = Caffeine.newBuilder().weakKeys().build();
@ -113,11 +110,10 @@ public final class PacketUtils {
* Note: {@link ComponentHoldingServerPacket}s are not translated inside a {@link CachedPacket}.
*
* @see CachedPacket#body()
* @see PlayerSocketConnection#writePacketSync(SendablePacket, boolean)
*/
static boolean shouldUseCachePacket(final @NotNull ServerPacket packet) {
if (!MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION) return GROUPED_PACKET;
if (!(packet instanceof ComponentHoldingServerPacket holder)) return GROUPED_PACKET;
if (!MinestomAdventure.AUTOMATIC_COMPONENT_TRANSLATION) return ServerFlag.GROUPED_PACKET;
if (!(packet instanceof ComponentHoldingServerPacket holder)) return ServerFlag.GROUPED_PACKET;
return !containsTranslatableComponents(holder);
}
@ -164,7 +160,7 @@ public final class PacketUtils {
entity.sendPacketToViewers(serverPacket);
return;
}
if (!VIEWABLE_PACKET) {
if (!ServerFlag.VIEWABLE_PACKET) {
sendGroupedPacket(viewable.getViewers(), serverPacket, value -> !Objects.equals(value, entity));
return;
}
@ -180,7 +176,7 @@ public final class PacketUtils {
@ApiStatus.Internal
public static void flush() {
if (VIEWABLE_PACKET) {
if (ServerFlag.VIEWABLE_PACKET) {
VIEWABLE_STORAGE_MAP.asMap().entrySet().parallelStream().forEach(entry ->
entry.getValue().process(entry.getKey()));
}

View File

@ -1,5 +1,6 @@
package net.minestom.server.utils.chunk;
import net.minestom.server.ServerFlag;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.instance.Chunk;
@ -16,10 +17,6 @@ import java.util.function.Consumer;
@ApiStatus.Internal
public final class ChunkUtils {
public static final boolean USE_NEW_CHUNK_SENDING = Boolean.getBoolean("minestom.use-new-chunk-sending");
public static final int NEW_CHUNK_COUNT_PER_INTERVAL = Integer.getInteger("minestom.new-chunk-sending-count-per-interval", 50);
public static final int NEW_CHUNK_SEND_INTERVAL = Integer.getInteger("minestom.new-chunk-sending-send-interval", 20);
private ChunkUtils() {
}
@ -178,7 +175,7 @@ public final class ChunkUtils {
* which comes from kotlin port by <a href="https://github.com/Esophose">Esophose</a>, which comes from <a href="https://stackoverflow.com/questions/398299/looping-in-a-spiral">a stackoverflow answer</a>.
*/
public static void forChunksInRange(int chunkX, int chunkZ, int range, IntegerBiConsumer consumer) {
if (!USE_NEW_CHUNK_SENDING) {
if (!ServerFlag.USE_NEW_CHUNK_SENDING) {
for (int x = -range; x <= range; ++x) {
for (int z = -range; z <= range; ++z) {
consumer.accept(chunkX + x, chunkZ + z);