diff --git a/gradle.properties b/gradle.properties index 106dbdf..7b7604f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ loader_version=0.18.4 loom_version=1.15-SNAPSHOT # Mod Properties -mod_version = 2.4.3+26.1 +mod_version = 2.4.4+26.1 maven_group = net.treset archives_base_name = adaptiveview diff --git a/src/main/java/net/treset/adaptiveview/AdaptiveViewMod.java b/src/main/java/net/treset/adaptiveview/AdaptiveViewMod.java index 48ff0db..25eb42e 100644 --- a/src/main/java/net/treset/adaptiveview/AdaptiveViewMod.java +++ b/src/main/java/net/treset/adaptiveview/AdaptiveViewMod.java @@ -1,81 +1,85 @@ -package net.treset.adaptiveview; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.context.CommandContext; -import net.fabricmc.api.ModInitializer; -import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; -import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; -import net.minecraft.commands.CommandSourceStack; -import net.minecraft.commands.Commands; -import net.minecraft.server.MinecraftServer; -import net.treset.adaptiveview.commands.ConfigCommandHandler; -import net.treset.adaptiveview.commands.LockCommandHandler; -import net.treset.adaptiveview.commands.NotificationCommandHandler; -import net.treset.adaptiveview.config.Config; -import net.treset.adaptiveview.distance.ServerHandler; -import net.treset.adaptiveview.distance.ViewDistanceHandler; -import net.treset.adaptiveview.tools.TextTools; -import net.treset.adaptiveview.unlocking.LockManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class AdaptiveViewMod implements ModInitializer { - public static final Logger LOGGER = LoggerFactory.getLogger("adaptiveview"); - - private static final Config config = Config.loadOrDefault(); - private static final NotificationCommandHandler notificationCommandHandler = new NotificationCommandHandler(config); - private static final ConfigCommandHandler configCommandHandler = new ConfigCommandHandler(config); - private static final ViewDistanceHandler viewDistanceHandler = new ViewDistanceHandler(config); - private static final LockManager lockManager = new LockManager(config, viewDistanceHandler); - private static final LockCommandHandler lockCommandHandler = new LockCommandHandler(config, lockManager); - private static final ServerHandler serverHandler = new ServerHandler(config, lockManager, viewDistanceHandler); - private static MinecraftServer server; - - private static boolean client = false; - - public static Config getConfig() { - return config; - } - - public static MinecraftServer getServer() { - return server; - } - - public static boolean isClient() { - return client; - } - - public static void setClient(boolean client) { - AdaptiveViewMod.client = client; - } - - @Override - public void onInitialize() { - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> this.registerCommands(dispatcher, environment)); - - ServerLifecycleEvents.SERVER_STARTED.register((s) -> server = s); - ServerTickEvents.END_SERVER_TICK.register(serverHandler::onTick); - } - - private void registerCommands(CommandDispatcher dispatcher, Commands.CommandSelection selection) { - if(!selection.includeDedicated && !config.isAllowOnClient()) return; - LiteralArgumentBuilder builder = Commands.literal("adaptiveview") - .executes(this::status) - .then(Commands.literal("status") - .executes(this::status) - ); - notificationCommandHandler.registerCommands(builder); - configCommandHandler.registerCommands(builder); - lockCommandHandler.registerCommands(builder); - - dispatcher.register(builder); - } - - private int status(CommandContext ctx) { - TextTools.replyFormatted(ctx, "View Distance: $b%s chunks", ViewDistanceHandler.getViewDistance()); - TextTools.replyFormatted(ctx, "Simulation Distance: $b%s chunks", ViewDistanceHandler.getSimDistance()); - return 1; - } -} +package net.treset.adaptiveview; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.context.CommandContext; +import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.commands.Commands; +import net.minecraft.server.MinecraftServer; +import net.treset.adaptiveview.commands.ConfigCommandHandler; +import net.treset.adaptiveview.commands.LockCommandHandler; +import net.treset.adaptiveview.commands.NotificationCommandHandler; +import net.treset.adaptiveview.config.Config; +import net.treset.adaptiveview.distance.ServerHandler; +import net.treset.adaptiveview.distance.ViewDistanceHandler; +import net.treset.adaptiveview.tools.TextTools; +import net.treset.adaptiveview.unlocking.LockManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdaptiveViewMod implements ModInitializer { + public static final Logger LOGGER = LoggerFactory.getLogger("adaptiveview"); + + private static final Config config = Config.loadOrDefault(); + private static final NotificationCommandHandler notificationCommandHandler = new NotificationCommandHandler(config); + private static final ConfigCommandHandler configCommandHandler = new ConfigCommandHandler(config); + private static final ViewDistanceHandler viewDistanceHandler = new ViewDistanceHandler(config); + private static final LockManager lockManager = new LockManager(config, viewDistanceHandler); + private static final LockCommandHandler lockCommandHandler = new LockCommandHandler(config, lockManager); + private static final ServerHandler serverHandler = new ServerHandler(config, lockManager, viewDistanceHandler); + private static MinecraftServer server; + + private static boolean client = false; + + public static Config getConfig() { + return config; + } + + public static MinecraftServer getServer() { + return server; + } + + public static ServerHandler getServerHandler() { + return serverHandler; + } + + public static boolean isClient() { + return client; + } + + public static void setClient(boolean client) { + AdaptiveViewMod.client = client; + } + + @Override + public void onInitialize() { + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> this.registerCommands(dispatcher, environment)); + + ServerLifecycleEvents.SERVER_STARTED.register((s) -> server = s); + ServerTickEvents.END_SERVER_TICK.register(serverHandler::onTick); + } + + private void registerCommands(CommandDispatcher dispatcher, Commands.CommandSelection selection) { + if(!selection.includeDedicated && !config.isAllowOnClient()) return; + LiteralArgumentBuilder builder = Commands.literal("adaptiveview") + .executes(this::status) + .then(Commands.literal("status") + .executes(this::status) + ); + notificationCommandHandler.registerCommands(builder); + configCommandHandler.registerCommands(builder); + lockCommandHandler.registerCommands(builder); + + dispatcher.register(builder); + } + + private int status(CommandContext ctx) { + TextTools.replyFormatted(ctx, "View Distance: $b%s chunks", ViewDistanceHandler.getViewDistance()); + TextTools.replyFormatted(ctx, "Simulation Distance: $b%s chunks", ViewDistanceHandler.getSimDistance()); + return 1; + } +} diff --git a/src/main/java/net/treset/adaptiveview/distance/DistanceData.java b/src/main/java/net/treset/adaptiveview/distance/DistanceData.java index 4896df3..a4aa088 100644 --- a/src/main/java/net/treset/adaptiveview/distance/DistanceData.java +++ b/src/main/java/net/treset/adaptiveview/distance/DistanceData.java @@ -1,13 +1,12 @@ package net.treset.adaptiveview.distance; import net.treset.adaptiveview.config.Rule; -import net.treset.adaptiveview.tools.MathTools; import java.util.List; record DistanceData(int maxDistance, int minDistance, int updateRate, int step) { public int getTargetDistance(int currentDistance) { - return MathTools.clamp(currentDistance + step, minDistance, maxDistance); + return Math.clamp(currentDistance + step, minDistance, maxDistance); } public static DistanceData extract(List rules, int defaultMax, int defaultMin) { diff --git a/src/main/java/net/treset/adaptiveview/distance/ServerHandler.java b/src/main/java/net/treset/adaptiveview/distance/ServerHandler.java index 67b4a27..812d2fd 100644 --- a/src/main/java/net/treset/adaptiveview/distance/ServerHandler.java +++ b/src/main/java/net/treset/adaptiveview/distance/ServerHandler.java @@ -1,68 +1,68 @@ -package net.treset.adaptiveview.distance; - -import net.minecraft.server.MinecraftServer; -import net.treset.adaptiveview.AdaptiveViewMod; -import net.treset.adaptiveview.config.Config; -import net.treset.adaptiveview.config.ServerState; -import net.treset.adaptiveview.tools.MathTools; -import net.treset.adaptiveview.unlocking.LockManager; - -import java.util.*; - -public class ServerHandler { - private static final ArrayList tickLengths = new ArrayList<>(); - - public static ArrayList getTickLengths() { - return tickLengths; - } - - private final Config config; - private final LockManager lockManager; - private final ViewDistanceHandler viewDistanceHandler; - - private int tickCounter = 0; - - private int nextUpdate; - - public ServerHandler(Config config, LockManager lockManager, ViewDistanceHandler viewDistanceHandler) { - this.config = config; - this.lockManager = lockManager; - this.viewDistanceHandler = viewDistanceHandler; - this.nextUpdate = config.getUpdateRate(); - } - - - public void onTick(MinecraftServer server) { - if(AdaptiveViewMod.isClient() && !config.isAllowOnClient()) { - return; - } - lockManager.onTick(); - - tickCounter++; - - if(tickCounter == nextUpdate) { - ServerState state = new ServerState( - ViewDistanceHandler.getViewDistance(), - ViewDistanceHandler.getSimDistance(), - (double)MathTools.longArrayAverage(tickLengths.toArray(new Long[0])) / 1000000d, - getMemory(), - getPlayers() - ); - - tickCounter = 0; - nextUpdate = viewDistanceHandler.updateViewDistance(state); - tickLengths.clear(); - } - } - - public static double getMemory() { - long allocatedMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); - long maxMemory = Runtime.getRuntime().maxMemory(); - return allocatedMemory/(double)maxMemory*100; - } - - public static List getPlayers() { - MinecraftServer server = AdaptiveViewMod.getServer(); - return Arrays.stream(server.getPlayerNames()).toList(); - } -} +package net.treset.adaptiveview.distance; + +import net.minecraft.server.MinecraftServer; +import net.treset.adaptiveview.AdaptiveViewMod; +import net.treset.adaptiveview.config.Config; +import net.treset.adaptiveview.config.ServerState; +import net.treset.adaptiveview.unlocking.LockManager; + +import java.util.*; + +public class ServerHandler { + private TickLengthBuffer tickLengths; + + public TickLengthBuffer getTickLengths() { + return tickLengths; + } + + private final Config config; + private final LockManager lockManager; + private final ViewDistanceHandler viewDistanceHandler; + + private int tickCounter = 0; + + private int nextUpdate; + + public ServerHandler(Config config, LockManager lockManager, ViewDistanceHandler viewDistanceHandler) { + this.config = config; + this.lockManager = lockManager; + this.viewDistanceHandler = viewDistanceHandler; + this.nextUpdate = config.getUpdateRate(); + this.tickLengths = new TickLengthBuffer(config.getUpdateRate()); + } + + + public void onTick(MinecraftServer server) { + if(AdaptiveViewMod.isClient() && !config.isAllowOnClient()) { + return; + } + lockManager.onTick(); + + tickCounter++; + + if(tickCounter == nextUpdate) { + ServerState state = new ServerState( + ViewDistanceHandler.getViewDistance(), + ViewDistanceHandler.getSimDistance(), + tickLengths.averageMillis(), + getMemory(), + getPlayers() + ); + + tickCounter = 0; + nextUpdate = viewDistanceHandler.updateViewDistance(state); + tickLengths.reset(); + } + } + + public static double getMemory() { + long allocatedMemory = Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory(); + long maxMemory = Runtime.getRuntime().maxMemory(); + return allocatedMemory/(double)maxMemory*100; + } + + public static List getPlayers() { + MinecraftServer server = AdaptiveViewMod.getServer(); + return Arrays.stream(server.getPlayerNames()).toList(); + } +} diff --git a/src/main/java/net/treset/adaptiveview/distance/TickLengthBuffer.java b/src/main/java/net/treset/adaptiveview/distance/TickLengthBuffer.java new file mode 100644 index 0000000..e581311 --- /dev/null +++ b/src/main/java/net/treset/adaptiveview/distance/TickLengthBuffer.java @@ -0,0 +1,31 @@ +package net.treset.adaptiveview.distance; + +public class TickLengthBuffer { + private final long[] buffer; + private int index = 0; + private int count = 0; + + public TickLengthBuffer(int capacity) { + this.buffer = new long[capacity]; + } + + public void add(long value) { + buffer[index] = value; + index = (index + 1) % buffer.length; + if (count < buffer.length) count++; + } + + public double averageMillis() { + if (count == 0) return 0d; + long sum = 0; + for (int i = 0; i < count; i++) { + sum += buffer[i]; + } + return (sum / (double) count) / 1_000_000d; + } + + public void reset() { + index = 0; + count = 0; + } +} diff --git a/src/main/java/net/treset/adaptiveview/mixin/MinecraftServerMixin.java b/src/main/java/net/treset/adaptiveview/mixin/MinecraftServerMixin.java index c80069c..78cefbd 100644 --- a/src/main/java/net/treset/adaptiveview/mixin/MinecraftServerMixin.java +++ b/src/main/java/net/treset/adaptiveview/mixin/MinecraftServerMixin.java @@ -1,21 +1,21 @@ -package net.treset.adaptiveview.mixin; - -import com.llamalad7.mixinextras.sugar.Local; -import net.minecraft.server.MinecraftServer; -import net.treset.adaptiveview.distance.ServerHandler; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.function.BooleanSupplier; - -@Mixin(MinecraftServer.class) -public class MinecraftServerMixin { - - @Inject(method="tickServer(Ljava/util/function/BooleanSupplier;)V", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) - private void tick(BooleanSupplier shouldKeepTicking, CallbackInfo ci, @Local(ordinal = 1) long tickTime) { - ServerHandler.getTickLengths().add(tickTime); - } -} +package net.treset.adaptiveview.mixin; + +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.server.MinecraftServer; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import net.treset.adaptiveview.AdaptiveViewMod; + +import java.util.function.BooleanSupplier; + +@Mixin(MinecraftServer.class) +public class MinecraftServerMixin { + + @Inject(method="tickServer(Ljava/util/function/BooleanSupplier;)V", at = @At("TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) + private void tick(BooleanSupplier shouldKeepTicking, CallbackInfo ci, @Local(ordinal = 1) long tickTime) { + AdaptiveViewMod.getServerHandler().getTickLengths().add(tickTime); + } +} diff --git a/src/main/java/net/treset/adaptiveview/tools/MathTools.java b/src/main/java/net/treset/adaptiveview/tools/MathTools.java deleted file mode 100644 index 5583179..0000000 --- a/src/main/java/net/treset/adaptiveview/tools/MathTools.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.treset.adaptiveview.tools; - -public class MathTools { - public static long longArrayAverage(Long[] values) { - if (values == null || values.length == 0) { - return 0; - } - - long sum = 0; - for (long e : values) { - sum += e; - } - return sum / values.length; - } - - public static int clamp(int value, int min, int max) { - return Math.max(min, Math.min(max, value)); - } -}