diff --git a/gradle.properties b/gradle.properties index 7b13390..7830ccb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,10 +2,10 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://modmuss50.me/fabric.html -minecraft_version=1.20 -yarn_mappings=1.20+build.1 -loader_version=0.14.17 +minecraft_version=1.20.2 +yarn_mappings=1.20.2+build.1 +loader_version=0.14.22 # Mod Properties -mod_version=0.2.3 +mod_version=0.2.4 maven_group=me.steinborn archives_base_name=krypton \ No newline at end of file diff --git a/src/main/java/me/steinborn/krypton/mixin/client/fastchunkentityaccess/ClientWorldMixin.java b/src/main/java/me/steinborn/krypton/mixin/client/fastchunkentityaccess/ClientWorldMixin.java deleted file mode 100644 index 5e15c51..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/client/fastchunkentityaccess/ClientWorldMixin.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.steinborn.krypton.mixin.client.fastchunkentityaccess; - -import me.steinborn.krypton.mod.shared.WorldEntityByChunkAccess; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.world.ClientEntityManager; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Collection; - -@Mixin(ClientWorld.class) -@Environment(EnvType.CLIENT) -public class ClientWorldMixin implements WorldEntityByChunkAccess { - - @Shadow @Final private ClientEntityManager entityManager; - - @Override - public Collection getEntitiesInChunk(int chunkX, int chunkZ) { - return ((WorldEntityByChunkAccess) this.entityManager.cache).getEntitiesInChunk(chunkX, chunkZ); - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/server/fastchunkentityaccess/ServerWorldMixin.java b/src/main/java/me/steinborn/krypton/mixin/server/fastchunkentityaccess/ServerWorldMixin.java deleted file mode 100644 index 07fe8be..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/server/fastchunkentityaccess/ServerWorldMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.steinborn.krypton.mixin.server.fastchunkentityaccess; - -import me.steinborn.krypton.mod.shared.WorldEntityByChunkAccess; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.entity.Entity; -import net.minecraft.server.world.ServerEntityManager; -import net.minecraft.server.world.ServerWorld; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.Collection; - -@Mixin(ServerWorld.class) -public class ServerWorldMixin implements WorldEntityByChunkAccess { - - @Shadow - @Final - private ServerEntityManager entityManager; - - @Override - public Collection getEntitiesInChunk(int chunkX, int chunkZ) { - return ((WorldEntityByChunkAccess) this.entityManager.cache).getEntitiesInChunk(chunkX, chunkZ); - } -} \ No newline at end of file diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/bugfix/CustomPayloadS2CPacketFixMemoryLeakMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/bugfix/CustomPayloadS2CPacketFixMemoryLeakMixin.java deleted file mode 100644 index 7e5a506..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/bugfix/CustomPayloadS2CPacketFixMemoryLeakMixin.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.steinborn.krypton.mixin.shared.bugfix; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import net.minecraft.network.PacketByteBuf; -import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; - -@Mixin(CustomPayloadS2CPacket.class) -public class CustomPayloadS2CPacketFixMemoryLeakMixin { - - @Redirect(method = "(Lnet/minecraft/network/PacketByteBuf;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/PacketByteBuf;readBytes(I)Lio/netty/buffer/ByteBuf;")) - private ByteBuf deserialize$shouldExplicitlyCopyAsUnpooledBufferDueToShenanigans(PacketByteBuf instance, int length) { - return Unpooled.copiedBuffer(instance.readSlice(length)); - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/EntityTrackingSectionAccessor.java b/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/EntityTrackingSectionAccessor.java deleted file mode 100644 index d718a28..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/EntityTrackingSectionAccessor.java +++ /dev/null @@ -1,13 +0,0 @@ -package me.steinborn.krypton.mixin.shared.fastchunkentityaccess; - -import net.minecraft.util.collection.TypeFilterableList; -import net.minecraft.world.entity.EntityTrackingSection; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; - -@Mixin(EntityTrackingSection.class) -public interface EntityTrackingSectionAccessor { - - @Accessor - TypeFilterableList getCollection(); -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/SectionedEntityCacheMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/SectionedEntityCacheMixin.java deleted file mode 100644 index d2d5bf2..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/fastchunkentityaccess/SectionedEntityCacheMixin.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.steinborn.krypton.mixin.shared.fastchunkentityaccess; - -import it.unimi.dsi.fastutil.longs.Long2ObjectMap; -import it.unimi.dsi.fastutil.longs.LongIterator; -import it.unimi.dsi.fastutil.longs.LongSortedSet; -import me.steinborn.krypton.mod.shared.WorldEntityByChunkAccess; -import net.minecraft.entity.Entity; -import net.minecraft.world.entity.EntityTrackingSection; -import net.minecraft.world.entity.SectionedEntityCache; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -/** - * Provides a fast way to search the section cache for entities present in a given chunk. - */ -@Mixin(SectionedEntityCache.class) -public abstract class SectionedEntityCacheMixin implements WorldEntityByChunkAccess { - - @Shadow @Final private Long2ObjectMap> trackingSections; - - @Override - public Collection getEntitiesInChunk(final int chunkX, final int chunkZ) { - final LongSortedSet set = this.getSections(chunkX, chunkZ); - if (set.isEmpty()) { - // Nothing in this map? - return List.of(); - } - - final List entities = new ArrayList<>(); - final LongIterator sectionsIterator = set.iterator(); - while (sectionsIterator.hasNext()) { - final long key = sectionsIterator.nextLong(); - final EntityTrackingSection value = this.trackingSections.get(key); - if (value != null && value.getStatus().shouldTrack()) { - entities.addAll(((EntityTrackingSectionAccessor) value).getCollection()); - } - } - - return entities; - } - - @Shadow protected abstract LongSortedSet getSections(int chunkX, int chunkZ); -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/avoidwork/ThreadedAnvilChunkStorageMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/avoidwork/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index bc9a465..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/avoidwork/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,72 +0,0 @@ -package me.steinborn.krypton.mixin.shared.network.avoidwork; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; -import me.steinborn.krypton.mod.shared.WorldEntityByChunkAccess; -import net.minecraft.entity.Entity; -import net.minecraft.entity.mob.MobEntity; -import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket; -import net.minecraft.network.packet.s2c.play.EntityAttachS2CPacket; -import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.world.chunk.WorldChunk; -import org.apache.commons.lang3.mutable.MutableObject; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -@Mixin(ThreadedAnvilChunkStorage.class) -public class ThreadedAnvilChunkStorageMixin { - - @Shadow @Final private Int2ObjectMap entityTrackers; - - @Inject(method = "sendChunkDataPackets", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/DebugInfoSender;sendChunkWatchingChange(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/math/ChunkPos;)V", shift = At.Shift.AFTER, by = 1)) - public void sendChunkDataPackets$beSmart(ServerPlayerEntity player, MutableObject mutableObject, WorldChunk chunk, CallbackInfo ci) { - // Synopsis: when sending chunk data to the player, sendChunkDataPackets iterates over EVERY tracked entity in - // the world, when it doesn't have to do so - we only need entities in the current chunk. A similar optimization - // is present in Paper. - final Collection entitiesInChunk = ((WorldEntityByChunkAccess) chunk.getWorld()).getEntitiesInChunk(chunk.getPos().x, chunk.getPos().z); - final List attachmentsToSend = new ArrayList<>(); - final List passengersToSend = new ArrayList<>(); - for (Entity entity : entitiesInChunk) { - final ThreadedAnvilChunkStorage.EntityTracker entityTracker = this.entityTrackers.get(entity.getId()); - if (entityTracker != null) { - entityTracker.updateTrackedStatus(player); - if (entity instanceof MobEntity && ((MobEntity)entity).getHoldingEntity() != null) { - attachmentsToSend.add(entity); - } - - if (!entity.getPassengerList().isEmpty()) { - passengersToSend.add(entity); - } - } - } - - if (!attachmentsToSend.isEmpty()) { - for (Entity entity : attachmentsToSend) { - player.networkHandler.sendPacket(new EntityAttachS2CPacket(entity, ((MobEntity) entity).getHoldingEntity())); - } - } - - if (!passengersToSend.isEmpty()) { - for (Entity entity : passengersToSend) { - player.networkHandler.sendPacket(new EntityPassengersSetS2CPacket(entity)); - } - } - } - - @Redirect(method = "sendChunkDataPackets", at = @At(value = "FIELD", target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;entityTrackers:Lit/unimi/dsi/fastutil/ints/Int2ObjectMap;", opcode = Opcodes.GETFIELD)) - public Int2ObjectMap sendChunkDataPackets$nullifyRest(ThreadedAnvilChunkStorage tacs) { - return Int2ObjectMaps.emptyMap(); - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ClientConnectionMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ClientConnectionMixin.java deleted file mode 100644 index 96eaa62..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ClientConnectionMixin.java +++ /dev/null @@ -1,121 +0,0 @@ -package me.steinborn.krypton.mixin.shared.network.flushconsolidation; - -import io.netty.channel.*; -import me.steinborn.krypton.mod.shared.network.ConfigurableAutoFlush; -import net.minecraft.network.ClientConnection; -import net.minecraft.network.NetworkState; -import net.minecraft.network.PacketCallbacks; -import net.minecraft.network.packet.Packet; -import org.jetbrains.annotations.Nullable; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.LocalCapture; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * Optimizes ClientConnection by adding the ability to skip auto-flushing and using void promises where possible. - */ -@Mixin(ClientConnection.class) -public abstract class ClientConnectionMixin implements ConfigurableAutoFlush { - @Shadow private Channel channel; - private AtomicBoolean autoFlush; - - @Shadow public abstract void setState(NetworkState state); - - @Inject(method = "", at = @At("RETURN")) - private void initAddedFields(CallbackInfo ci) { - this.autoFlush = new AtomicBoolean(true); - } - - /** - * Refactored sendImmediately method. This is a better fit for {@code @Overwrite} but we have to write it this way - * because the fabric-networking-api-v1 also mixes into this... - * - * @author Andrew Steinborn - */ - @Inject(locals = LocalCapture.CAPTURE_FAILHARD, - cancellable = true, - method = "sendImmediately", - at = @At(value = "FIELD", target = "Lnet/minecraft/network/ClientConnection;packetsSentCounter:I", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER)) - private void sendImmediately$rewrite(Packet packet, @Nullable PacketCallbacks callback, CallbackInfo info, NetworkState packetState, NetworkState protocolState) { - boolean newState = packetState != protocolState; - - if (this.channel.eventLoop().inEventLoop()) { - if (newState) { - this.setState(packetState); - } - doSendPacket(packet, callback); - } else { - // Note: In newer versions of Netty, we could use AbstractEventExecutor.LazyRunnable to avoid a wakeup. - // This has the advantage of requiring slightly less code. - // However, in practice, (almost) every write will use a WriteTask which doesn't wake up the event loop. - // The only exceptions are transitioning states (very rare) and when a listener is provided (but this is - // only upon disconnect of a client). So we can sit back and enjoy the GC savings. - if (!newState && callback == null) { - ChannelPromise voidPromise = this.channel.voidPromise(); - if (this.autoFlush.get()) { - this.channel.writeAndFlush(packet, voidPromise); - } else { - this.channel.write(packet, voidPromise); - } - } else { - // Fallback. - if (newState) { - this.channel.config().setAutoRead(false); - } - - this.channel.eventLoop().execute(() -> { - if (newState) { - this.setState(packetState); - } - doSendPacket(packet, callback); - }); - } - } - - info.cancel(); - } - - @Redirect(method = "tick", at = @At(value = "FIELD", target = "Lnet/minecraft/network/ClientConnection;channel:Lio/netty/channel/Channel;", opcode = Opcodes.GETFIELD)) - public Channel disableForcedFlushEveryTick(ClientConnection clientConnection) { - return null; - } - - private void doSendPacket(Packet packet, PacketCallbacks callback) { - if (callback == null) { - this.channel.write(packet, this.channel.voidPromise()); - } else { - ChannelFuture channelFuture = this.channel.write(packet); - channelFuture.addListener(listener -> { - if (listener.isSuccess()) { - callback.onSuccess(); - } else { - Packet failedPacket = callback.getFailurePacket(); - if (failedPacket != null) { - ChannelFuture failedChannelFuture = this.channel.writeAndFlush(failedPacket); - failedChannelFuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - } - }); - channelFuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); - } - - if (this.autoFlush.get()) { - this.channel.flush(); - } - } - - @Override - public void setShouldAutoFlush(boolean shouldAutoFlush) { - boolean prev = this.autoFlush.getAndSet(shouldAutoFlush); - if (!prev && shouldAutoFlush) { - this.channel.flush(); - } - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ThreadedAnvilChunkStorageMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ThreadedAnvilChunkStorageMixin.java deleted file mode 100644 index e085e61..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/flushconsolidation/ThreadedAnvilChunkStorageMixin.java +++ /dev/null @@ -1,300 +0,0 @@ -package me.steinborn.krypton.mixin.shared.network.flushconsolidation; - -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import me.steinborn.krypton.mod.shared.network.util.AutoFlushUtil; -import me.steinborn.krypton.mod.shared.player.KryptonServerPlayerEntity; -import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.server.world.PlayerChunkWatchingManager; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.server.world.ThreadedAnvilChunkStorage; -import net.minecraft.util.math.ChunkPos; -import net.minecraft.util.math.ChunkSectionPos; -import org.apache.commons.lang3.mutable.MutableObject; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -/** - * Mixes into various methods in {@code ThreadedAnvilChunkStorage} to utilize flush consolidation for sending chunks all at once to the - * client, along with loading chunks in a spiral order. Helpful for heavy server activity or flying very quickly. - *

- * Note for anyone attempting to modify this class in the future: for some reason, mojang includes both the chunk loading & chunk unloading - * packets in the same method. This is why chunks must always be sent to the player when they leave an area. - */ -@Mixin(ThreadedAnvilChunkStorage.class) -public abstract class ThreadedAnvilChunkStorageMixin { - @Shadow - @Final - private Int2ObjectMap entityTrackers; - - @Shadow - @Final - private PlayerChunkWatchingManager playerChunkWatchingManager; - - @Shadow - @Final - private ServerWorld world; - - @Shadow - @Final - private ThreadedAnvilChunkStorage.TicketManager ticketManager; - - @Shadow - private int watchDistance; - - @Shadow - public static boolean isWithinDistance(int x1, int y1, int x2, int y2, int maxDistance) { - // PAIL: isWithinEuclideanDistance(x1, y1, x2, y2, maxDistance) - throw new AssertionError("pedantic"); - } - - /** - * This is run on login. This method is overwritten to avoid sending duplicate chunks (which mc does by default) - * - * @reason optimize sending chunks - * @author solonovamax - */ - @Overwrite - public void handlePlayerAddedOrRemoved(ServerPlayerEntity player, boolean added) { - boolean doesNotGenerateChunks = this.doesNotGenerateChunks(player); - boolean isWatchingWorld = !this.playerChunkWatchingManager.isWatchInactive(player); - - int chunkPosX = ChunkSectionPos.getSectionCoord(player.getBlockX()); - int chunkPosZ = ChunkSectionPos.getSectionCoord(player.getBlockZ()); - - AutoFlushUtil.setAutoFlush(player, false); - try { - if (added) { - this.playerChunkWatchingManager.add(ChunkPos.toLong(chunkPosX, chunkPosZ), player, doesNotGenerateChunks); - this.updateWatchedSection(player); - - if (!doesNotGenerateChunks) { - this.ticketManager.handleChunkEnter(ChunkSectionPos.from(player), player); - } - - // Send spiral watch packets if added - sendSpiralChunkWatchPackets(player); - } else { - ChunkSectionPos chunkSectionPos = player.getWatchedSection(); - this.playerChunkWatchingManager.remove(chunkSectionPos.toChunkPos().toLong(), player); - - if (isWatchingWorld) { - this.ticketManager.handleChunkLeave(chunkSectionPos, player); - } - - // Loop through & unload chunks if removed - unloadChunks(player, chunkPosX, chunkPosZ, watchDistance); - } - } finally { - AutoFlushUtil.setAutoFlush(player, true); - } - } - - /** - * @author Andrew Steinborn - * @reason Add support for flush consolidation & optimize sending chunks - */ - @Overwrite - public void updatePosition(ServerPlayerEntity player) { - // TODO: optimize this further by only considering entities that the player is close to. - // use the FastChunkEntityAccess magic to do this. - for (ThreadedAnvilChunkStorage.EntityTracker entityTracker : this.entityTrackers.values()) { - if (entityTracker.entity == player) { - entityTracker.updateTrackedStatus(this.world.getPlayers()); - } else { - entityTracker.updateTrackedStatus(player); - } - } - - ChunkSectionPos oldPos = player.getWatchedSection(); - ChunkSectionPos newPos = ChunkSectionPos.from(player); - boolean isWatchingWorld = this.playerChunkWatchingManager.isWatchDisabled(player); - boolean noChunkGen = this.doesNotGenerateChunks(player); - boolean movedSections = !oldPos.equals(newPos); - - if (movedSections || isWatchingWorld != noChunkGen) { - this.updateWatchedSection(player); - - if (!isWatchingWorld) { - this.ticketManager.handleChunkLeave(oldPos, player); - } - - if (!noChunkGen) { - this.ticketManager.handleChunkEnter(newPos, player); - } - - if (!isWatchingWorld && noChunkGen) { - this.playerChunkWatchingManager.disableWatch(player); - } - - if (isWatchingWorld && !noChunkGen) { - this.playerChunkWatchingManager.enableWatch(player); - } - - long oldChunkPos = ChunkPos.toLong(oldPos.getX(), oldPos.getZ()); - long newChunkPos = ChunkPos.toLong(newPos.getX(), newPos.getZ()); - this.playerChunkWatchingManager.movePlayer(oldChunkPos, newChunkPos, player); - } - - // The player *always* needs to be send chunks, as for some reason both chunk loading & unloading packets are handled - // by the same method (why mojang) - if (player.getWorld() == this.world) - this.sendChunkWatchPackets(oldPos, player); - } - - @Inject(method = "tickEntityMovement", at = @At("HEAD")) - public void disableAutoFlushForEntityTracking(CallbackInfo info) { - for (ServerPlayerEntity player : world.getPlayers()) { - AutoFlushUtil.setAutoFlush(player, false); - } - } - - @Inject(method = "tickEntityMovement", at = @At("RETURN")) - public void enableAutoFlushForEntityTracking(CallbackInfo info) { - for (ServerPlayerEntity player : world.getPlayers()) { - AutoFlushUtil.setAutoFlush(player, true); - } - } - - /** - * @param player The player - * @param pos The position of the chunk to send - * @param mutableObject A new mutable object - * @param oldWithinViewDistance If the chunk was previously within the player's view distance - * @param newWithinViewDistance If the chunk is now within the player's view distance - */ - @Shadow - public abstract void sendWatchPackets(ServerPlayerEntity player, ChunkPos pos, MutableObject mutableObject, - boolean oldWithinViewDistance, boolean newWithinViewDistance); - - @Shadow - protected abstract boolean doesNotGenerateChunks(ServerPlayerEntity player); - - @Shadow - protected abstract ChunkSectionPos updateWatchedSection(ServerPlayerEntity serverPlayerEntity); - - private void sendChunkWatchPackets(ChunkSectionPos oldPos, ServerPlayerEntity player) { - AutoFlushUtil.setAutoFlush(player, false); - try { - int oldChunkX = oldPos.getSectionX(); - int oldChunkZ = oldPos.getSectionZ(); - - int newChunkX = ChunkSectionPos.getSectionCoord(player.getBlockX()); - int newChunkZ = ChunkSectionPos.getSectionCoord(player.getBlockZ()); - - int playerViewDistance = getPlayerViewDistance(player); // +1 for buffer - - if (shouldReloadAllChunks(player)) { // Player updated view distance, unload chunks & resend (only unload chunks not visible) - //noinspection InstanceofIncompatibleInterface - if (player instanceof KryptonServerPlayerEntity kryptonPlayer) - kryptonPlayer.setNeedsChunksReloaded(false); - - for (int curX = newChunkX - watchDistance - 1; curX <= newChunkX + watchDistance + 1; ++curX) { - for (int curZ = newChunkZ - watchDistance - 1; curZ <= newChunkZ + watchDistance + 1; ++curZ) { - ChunkPos chunkPos = new ChunkPos(curX, curZ); - boolean inNew = isWithinDistance(curX, curZ, newChunkX, newChunkZ, playerViewDistance); - - this.sendWatchPackets(player, chunkPos, new MutableObject<>(), true, inNew); - } - } - - // Send new chunks - sendSpiralChunkWatchPackets(player); - } else if (Math.abs(oldChunkX - newChunkX) > playerViewDistance * 2 || - Math.abs(oldChunkZ - newChunkZ) > playerViewDistance * 2) { - // If the player is not near the old chunks, send all new chunks & unload old chunks - - // Unload previous chunks - // Chunk unload packets are very light, so we can just do it like this - unloadChunks(player, oldChunkX, oldChunkZ, watchDistance); - - // Send new chunks - sendSpiralChunkWatchPackets(player); - } else { - int minSendChunkX = Math.min(newChunkX, oldChunkX) - playerViewDistance - 1; - int minSendChunkZ = Math.min(newChunkZ, oldChunkZ) - playerViewDistance - 1; - int maxSendChunkX = Math.max(newChunkX, oldChunkX) + playerViewDistance + 1; - int maxSendChunkZ = Math.max(newChunkZ, oldChunkZ) + playerViewDistance + 1; - - // We're sending *all* chunks in the range of where the player was, to where the player currently is. - // This is because the #sendWatchPackets method will also unload chunks. - // For chunks outside of the view distance, it does nothing. - for (int curX = minSendChunkX; curX <= maxSendChunkX; ++curX) { - for (int curZ = minSendChunkZ; curZ <= maxSendChunkZ; ++curZ) { - ChunkPos chunkPos = new ChunkPos(curX, curZ); - boolean inOld = isWithinDistance(curX, curZ, oldChunkX, oldChunkZ, playerViewDistance); - boolean inNew = isWithinDistance(curX, curZ, newChunkX, newChunkZ, playerViewDistance); - this.sendWatchPackets(player, chunkPos, new MutableObject<>(), inOld, inNew); - } - } - } - } finally { - AutoFlushUtil.setAutoFlush(player, true); - } - } - - /** - * Sends watch packets to the client in a spiral for a player, which has *no* chunks loaded in the area. - */ - private void sendSpiralChunkWatchPackets(ServerPlayerEntity player) { - int chunkPosX = ChunkSectionPos.getSectionCoord(player.getBlockX()); - int chunkPosZ = ChunkSectionPos.getSectionCoord(player.getBlockZ()); - - - // + 1 because mc adds 1 when it sends chunks - int playerViewDistance = getPlayerViewDistance(player) + 1; - - int x = 0, z = 0, dx = 0, dz = -1; - int t = playerViewDistance * 2; - int maxI = t * t * 2; - for (int i = 0; i < maxI; i++) { - if ((-playerViewDistance <= x) && (x <= playerViewDistance) && (-playerViewDistance <= z) && (z <= playerViewDistance)) { - boolean inNew = isWithinDistance(chunkPosX, chunkPosZ, chunkPosX + x, chunkPosZ + z, playerViewDistance); - - this.sendWatchPackets(player, - new ChunkPos(chunkPosX + x, chunkPosZ + z), - new MutableObject<>(), false, inNew - ); - } - if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z))) { - t = dx; - dx = -dz; - dz = t; - } - x += dx; - z += dz; - } - } - - private void unloadChunks(ServerPlayerEntity player, int chunkPosX, int chunkPosZ, int distance) { - for (int curX = chunkPosX - distance - 1; curX <= chunkPosX + distance + 1; ++curX) { - for (int curZ = chunkPosZ - distance - 1; curZ <= chunkPosZ + distance + 1; ++curZ) { - ChunkPos chunkPos = new ChunkPos(curX, curZ); - - this.sendWatchPackets(player, chunkPos, new MutableObject<>(), true, false); - } - } - } - - private int getPlayerViewDistance(ServerPlayerEntity playerEntity) { - //noinspection InstanceofIncompatibleInterface - return playerEntity instanceof KryptonServerPlayerEntity kryptonPlayerEntity - ? kryptonPlayerEntity.getPlayerViewDistance() != -1 - // if -1, the view distance hasn't been set - // We *actually* need to send view distance + 1, because mc doesn't render chunks adjacent to unloaded ones - ? Math.min(this.watchDistance, - kryptonPlayerEntity.getPlayerViewDistance() + - 1) - : this.watchDistance : this.watchDistance; - } - - private boolean shouldReloadAllChunks(ServerPlayerEntity playerEntity) { - //noinspection InstanceofIncompatibleInterface - return playerEntity instanceof KryptonServerPlayerEntity kryptonPlayerEntity && kryptonPlayerEntity.getNeedsChunksReloaded(); - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/PacketByteBufMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/PacketByteBufMixin.java deleted file mode 100644 index 1b55c7b..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/PacketByteBufMixin.java +++ /dev/null @@ -1,95 +0,0 @@ -package me.steinborn.krypton.mixin.shared.network.microopt; - -import io.netty.buffer.ByteBuf; -import io.netty.buffer.ByteBufUtil; -import io.netty.handler.codec.EncoderException; -import me.steinborn.krypton.mod.shared.network.util.VarIntUtil; -import net.minecraft.network.PacketByteBuf; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Shadow; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -/** - * Multiple micro-optimizations for packet writing. - */ -@Mixin(PacketByteBuf.class) -public abstract class PacketByteBufMixin extends ByteBuf { - - @Shadow @Final private ByteBuf parent; - - @Shadow public abstract int writeCharSequence(CharSequence charSequence, Charset charset); - - /** - * @author Andrew - * @reason Use optimized VarInt byte size lookup table - */ - @Overwrite - public static int getVarIntLength(int value) { - return VarIntUtil.getVarIntLength(value); - } - - /** - * @author Andrew - * @reason Use {@link ByteBuf#writeCharSequence(CharSequence, Charset)} instead for improved performance along with - * computing the byte size ahead of time with {@link ByteBufUtil#utf8Bytes(CharSequence)} - */ - @Overwrite - public PacketByteBuf writeString(String string, int i) { - if (string.length() > i) { - throw new EncoderException("String too big (was " + string.length() + " characters, max " + i + ")"); - } - int utf8Bytes = ByteBufUtil.utf8Bytes(string); - if (utf8Bytes > i * 3) { - throw new EncoderException("String too big (was " + utf8Bytes + " bytes encoded, max " + (i * 3) + ")"); - } else { - this.writeVarInt(utf8Bytes); - this.writeCharSequence(string, StandardCharsets.UTF_8); - return new PacketByteBuf(parent); - } - } - - /** - * @author Andrew - * @reason optimized VarInt writing - */ - @Overwrite - public PacketByteBuf writeVarInt(int value) { - // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes - // that the server will send, to improve inlining. - if ((value & (0xFFFFFFFF << 7)) == 0) { - parent.writeByte(value); - } else if ((value & (0xFFFFFFFF << 14)) == 0) { - int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); - parent.writeShort(w); - } else { - writeVarIntFull(parent, value); - } - return new PacketByteBuf(parent); - } - - private static void writeVarIntFull(ByteBuf buf, int value) { - // See https://steinborn.me/posts/performance/how-fast-can-you-write-a-varint/ - if ((value & (0xFFFFFFFF << 7)) == 0) { - buf.writeByte(value); - } else if ((value & (0xFFFFFFFF << 14)) == 0) { - int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); - buf.writeShort(w); - } else if ((value & (0xFFFFFFFF << 21)) == 0) { - int w = (value & 0x7F | 0x80) << 16 | ((value >>> 7) & 0x7F | 0x80) << 8 | (value >>> 14); - buf.writeMedium(w); - } else if ((value & (0xFFFFFFFF << 28)) == 0) { - int w = (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16) - | ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21); - buf.writeInt(w); - } else { - int w = (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16 - | ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80); - buf.writeInt(w); - buf.writeByte(value >>> 28); - } - } -} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/StringEncodingMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/StringEncodingMixin.java new file mode 100644 index 0000000..affdb94 --- /dev/null +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/StringEncodingMixin.java @@ -0,0 +1,34 @@ +package me.steinborn.krypton.mixin.shared.network.microopt; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; +import io.netty.handler.codec.EncoderException; +import net.minecraft.network.encoding.StringEncoding; +import net.minecraft.network.encoding.VarInts; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.nio.charset.StandardCharsets; + +@Mixin(StringEncoding.class) +public class StringEncodingMixin { + /** + * @author Andrew Steinborn + * @reason optimized version + */ + @Overwrite + public static void encode(ByteBuf buf, CharSequence string, int length) { + // Mojang _almost_ gets it right, but stumbles at the finish line... + if (string.length() > length) { + throw new EncoderException("String too big (was " + string.length() + " characters, max " + length + ")"); + } + int utf8Bytes = ByteBufUtil.utf8Bytes(string); + int maxBytesPermitted = ByteBufUtil.utf8MaxBytes(length); + if (utf8Bytes > maxBytesPermitted) { + throw new EncoderException("String too big (was " + utf8Bytes + " bytes encoded, max " + maxBytesPermitted + ")"); + } else { + VarInts.write(buf, utf8Bytes); + buf.writeCharSequence(string, StandardCharsets.UTF_8); + } + } +} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/VarIntsMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/VarIntsMixin.java new file mode 100644 index 0000000..8d2b27c --- /dev/null +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/microopt/VarIntsMixin.java @@ -0,0 +1,62 @@ +package me.steinborn.krypton.mixin.shared.network.microopt; + +import io.netty.buffer.ByteBuf; +import me.steinborn.krypton.mod.shared.network.util.VarIntUtil; +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.encoding.VarInts; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(VarInts.class) +public class VarIntsMixin { + /** + * @author Andrew Steinborn + * @reason optimized version + */ + @Overwrite + public static int getSizeInBytes(int v) { + return VarIntUtil.getVarIntLength(v); + } + + /** + * @author Andrew Steinborn + * @reason optimized version + */ + @Overwrite + public static ByteBuf write(ByteBuf buf, int value) { + // Peel the one and two byte count cases explicitly as they are the most common VarInt sizes + // that the server will send, to improve inlining. + if ((value & (0xFFFFFFFF << 7)) == 0) { + buf.writeByte(value); + } else if ((value & (0xFFFFFFFF << 14)) == 0) { + int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); + buf.writeShort(w); + } else { + writeVarIntFull(buf, value); + } + + return buf; + } + + private static void writeVarIntFull(ByteBuf buf, int value) { + // See https://steinborn.me/posts/performance/how-fast-can-you-write-a-varint/ + if ((value & (0xFFFFFFFF << 7)) == 0) { + buf.writeByte(value); + } else if ((value & (0xFFFFFFFF << 14)) == 0) { + int w = (value & 0x7F | 0x80) << 8 | (value >>> 7); + buf.writeShort(w); + } else if ((value & (0xFFFFFFFF << 21)) == 0) { + int w = (value & 0x7F | 0x80) << 16 | ((value >>> 7) & 0x7F | 0x80) << 8 | (value >>> 14); + buf.writeMedium(w); + } else if ((value & (0xFFFFFFFF << 28)) == 0) { + int w = (value & 0x7F | 0x80) << 24 | (((value >>> 7) & 0x7F | 0x80) << 16) + | ((value >>> 14) & 0x7F | 0x80) << 8 | (value >>> 21); + buf.writeInt(w); + } else { + int w = (value & 0x7F | 0x80) << 24 | ((value >>> 7) & 0x7F | 0x80) << 16 + | ((value >>> 14) & 0x7F | 0x80) << 8 | ((value >>> 21) & 0x7F | 0x80); + buf.writeInt(w); + buf.writeByte(value >>> 28); + } + } +} diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/LegacyQueryHandlerMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/LegacyQueryHandlerMixin.java index 9ceddf3..a11866f 100644 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/LegacyQueryHandlerMixin.java +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/LegacyQueryHandlerMixin.java @@ -2,7 +2,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; -import net.minecraft.network.LegacyQueryHandler; +import net.minecraft.network.handler.LegacyQueryHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/SplitterHandlerMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/SplitterHandlerMixin.java index b932a09..fa0085e 100644 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/SplitterHandlerMixin.java +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/SplitterHandlerMixin.java @@ -3,7 +3,7 @@ import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import me.steinborn.krypton.mod.shared.network.VarintByteDecoder; -import net.minecraft.network.SplitterHandler; +import net.minecraft.network.handler.SplitterHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Overwrite; diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/compression/ClientConnectionMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/compression/ClientConnectionMixin.java index c84b54c..5cdd889 100644 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/compression/ClientConnectionMixin.java +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/compression/ClientConnectionMixin.java @@ -7,8 +7,8 @@ import me.steinborn.krypton.mod.shared.network.compression.MinecraftCompressDecoder; import me.steinborn.krypton.mod.shared.network.compression.MinecraftCompressEncoder; import net.minecraft.network.ClientConnection; -import net.minecraft.network.PacketDeflater; -import net.minecraft.network.PacketInflater; +import net.minecraft.network.handler.PacketDeflater; +import net.minecraft.network.handler.PacketInflater; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/encryption/ServerLoginNetworkHandlerMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/encryption/ServerLoginNetworkHandlerMixin.java index f18a02a..50067c4 100644 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/encryption/ServerLoginNetworkHandlerMixin.java +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/pipeline/encryption/ServerLoginNetworkHandlerMixin.java @@ -16,7 +16,7 @@ @Mixin(ServerLoginNetworkHandler.class) public class ServerLoginNetworkHandlerMixin { - @Shadow @Final public ClientConnection connection; + @Shadow @Final ClientConnection connection; @Redirect(method = "onKey", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/encryption/NetworkEncryptionUtils;cipherFromKey(ILjava/security/Key;)Ljavax/crypto/Cipher;")) private Cipher onKey$initializeVelocityCipher(int ignored1, Key secretKey) throws GeneralSecurityException { diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerPlayNetworkHandlerAccessor.java b/src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerCommonNetworkHandlerAccessor.java similarity index 61% rename from src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerPlayNetworkHandlerAccessor.java rename to src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerCommonNetworkHandlerAccessor.java index 544348f..85c223c 100644 --- a/src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerPlayNetworkHandlerAccessor.java +++ b/src/main/java/me/steinborn/krypton/mixin/shared/network/util/ServerCommonNetworkHandlerAccessor.java @@ -1,12 +1,12 @@ package me.steinborn.krypton.mixin.shared.network.util; import net.minecraft.network.ClientConnection; -import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerCommonNetworkHandler; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -@Mixin(ServerPlayNetworkHandler.class) -public interface ServerPlayNetworkHandlerAccessor { +@Mixin(ServerCommonNetworkHandler.class) +public interface ServerCommonNetworkHandlerAccessor { @Accessor ClientConnection getConnection(); diff --git a/src/main/java/me/steinborn/krypton/mixin/shared/player/ServerPlayerEntityMixin.java b/src/main/java/me/steinborn/krypton/mixin/shared/player/ServerPlayerEntityMixin.java deleted file mode 100644 index 899a1d0..0000000 --- a/src/main/java/me/steinborn/krypton/mixin/shared/player/ServerPlayerEntityMixin.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.steinborn.krypton.mixin.shared.player; - - -import me.steinborn.krypton.mod.shared.player.KryptonServerPlayerEntity; -import net.minecraft.network.packet.c2s.play.ClientSettingsC2SPacket; -import net.minecraft.server.network.ServerPlayerEntity; -import org.spongepowered.asm.mixin.Implements; -import org.spongepowered.asm.mixin.Interface; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - - -@Mixin(ServerPlayerEntity.class) -@Implements(@Interface(iface = KryptonServerPlayerEntity.class, prefix = "krypton$", unique = true)) -public class ServerPlayerEntityMixin implements KryptonServerPlayerEntity { - @Unique - private int playerViewDistance = -1; - - @Unique - private boolean needsChunksReloaded = false; - - @Inject(method = "setClientSettings", at = @At("HEAD")) - public void setClientSettings(ClientSettingsC2SPacket packet, CallbackInfo ci) { - needsChunksReloaded = (playerViewDistance != packet.viewDistance()); - playerViewDistance = packet.viewDistance(); - } - - @Override - public boolean getNeedsChunksReloaded() { - return needsChunksReloaded; - } - - @Override - public void setNeedsChunksReloaded(boolean needsChunksReloaded) { - this.needsChunksReloaded = needsChunksReloaded; - } - - @Override - public int getPlayerViewDistance() { - return playerViewDistance; - } -} diff --git a/src/main/java/me/steinborn/krypton/mod/shared/WorldEntityByChunkAccess.java b/src/main/java/me/steinborn/krypton/mod/shared/WorldEntityByChunkAccess.java deleted file mode 100644 index e8a4239..0000000 --- a/src/main/java/me/steinborn/krypton/mod/shared/WorldEntityByChunkAccess.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.steinborn.krypton.mod.shared; - -import net.minecraft.entity.Entity; - -import java.util.Collection; - -public interface WorldEntityByChunkAccess { - Collection getEntitiesInChunk(final int chunkX, final int chunkZ); -} diff --git a/src/main/java/me/steinborn/krypton/mod/shared/network/util/AutoFlushUtil.java b/src/main/java/me/steinborn/krypton/mod/shared/network/util/AutoFlushUtil.java deleted file mode 100644 index 6001e1c..0000000 --- a/src/main/java/me/steinborn/krypton/mod/shared/network/util/AutoFlushUtil.java +++ /dev/null @@ -1,16 +0,0 @@ -package me.steinborn.krypton.mod.shared.network.util; - -import me.steinborn.krypton.mixin.shared.network.util.ServerPlayNetworkHandlerAccessor; -import me.steinborn.krypton.mod.shared.network.ConfigurableAutoFlush; -import net.minecraft.server.network.ServerPlayerEntity; - -public class AutoFlushUtil { - public static void setAutoFlush(ServerPlayerEntity player, boolean val) { - if (player.getClass() == ServerPlayerEntity.class) { - ConfigurableAutoFlush configurableAutoFlusher = ((ConfigurableAutoFlush) ((ServerPlayNetworkHandlerAccessor) player.networkHandler).getConnection()); - configurableAutoFlusher.setShouldAutoFlush(val); - } - } - - private AutoFlushUtil() {} -} diff --git a/src/main/java/me/steinborn/krypton/mod/shared/player/KryptonServerPlayerEntity.java b/src/main/java/me/steinborn/krypton/mod/shared/player/KryptonServerPlayerEntity.java deleted file mode 100644 index 8a756fa..0000000 --- a/src/main/java/me/steinborn/krypton/mod/shared/player/KryptonServerPlayerEntity.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.steinborn.krypton.mod.shared.player; - - -public interface KryptonServerPlayerEntity { - void setNeedsChunksReloaded(boolean needsChunksReloaded); - - int getPlayerViewDistance(); - - boolean getNeedsChunksReloaded(); -} diff --git a/src/main/resources/krypton.mixins.json b/src/main/resources/krypton.mixins.json index 0cfd457..65fd851 100644 --- a/src/main/resources/krypton.mixins.json +++ b/src/main/resources/krypton.mixins.json @@ -1,32 +1,23 @@ { - "required": true, - "minVersion": "0.8", - "package": "me.steinborn.krypton.mixin", + "required": true, + "minVersion": "0.8", + "package": "me.steinborn.krypton.mixin", "compatibilityLevel": "JAVA_16", - "plugin": "me.steinborn.krypton.mod.shared.KryptonMixinPlugin", - "client": [ - "client.fastchunkentityaccess.ClientWorldMixin" - ], - "mixins": [ - "server.fastchunkentityaccess.ServerWorldMixin", - "shared.bugfix.CustomPayloadS2CPacketFixMemoryLeakMixin", + "plugin": "me.steinborn.krypton.mod.shared.KryptonMixinPlugin", + "client": [], + "mixins": [ "shared.debugaid.ResourceLeakDetectorDisableConditionalMixin", - "shared.fastchunkentityaccess.EntityTrackingSectionAccessor", - "shared.fastchunkentityaccess.SectionedEntityCacheMixin", - "shared.network.avoidwork.ThreadedAnvilChunkStorageMixin", - "shared.network.flushconsolidation.ClientConnectionMixin", - "shared.network.flushconsolidation.ThreadedAnvilChunkStorageMixin", "shared.network.microopt.EntityTrackerEntryMixin", - "shared.network.microopt.PacketByteBufMixin", + "shared.network.microopt.StringEncodingMixin", + "shared.network.microopt.VarIntsMixin", "shared.network.pipeline.LegacyQueryHandlerMixin", "shared.network.pipeline.SplitterHandlerMixin", "shared.network.pipeline.compression.ClientConnectionMixin", "shared.network.pipeline.encryption.ClientConnectionMixin", "shared.network.pipeline.encryption.ServerLoginNetworkHandlerMixin", - "shared.network.util.ServerPlayNetworkHandlerAccessor", - "shared.player.ServerPlayerEntityMixin" + "shared.network.util.ServerCommonNetworkHandlerAccessor" ], - "injectors": { + "injectors": { "defaultRequire": 1 } }