From 74fd9e78fceedb2b8b8d909a9d5ed15acf585f7a Mon Sep 17 00:00:00 2001 From: Adrian Siekierka <kontakt@asie.pl> Date: Sat, 27 Apr 2019 01:53:03 +0200 Subject: [PATCH] fix handling (sending and receiving) of register-type packets --- .../network/ClientSidePacketRegistryImpl.java | 4 +- .../impl/network/PacketRegistryImpl.java | 17 ++++---- .../MixinClientPlayNetworkHandler.java | 8 +++- .../mixin/network/MixinPlayerManager.java | 42 +++++++++++++++++++ .../resources/fabric-networking.mixins.json | 1 + .../mixin/registry/MixinPlayerManager.java | 1 - 6 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinPlayerManager.java diff --git a/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/ClientSidePacketRegistryImpl.java b/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/ClientSidePacketRegistryImpl.java index f7e3275ed..3b8d4754b 100644 --- a/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/ClientSidePacketRegistryImpl.java +++ b/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/ClientSidePacketRegistryImpl.java @@ -69,7 +69,7 @@ public class ClientSidePacketRegistryImpl extends PacketRegistryImpl implements protected void onRegister(Identifier id) { ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler(); if (handler != null) { - handler.sendPacket(createRegisterTypePacket(PacketTypes.REGISTER, Collections.singleton(id))); + createRegisterTypePacket(PacketTypes.REGISTER, Collections.singleton(id)).ifPresent(handler::sendPacket); } } @@ -77,7 +77,7 @@ public class ClientSidePacketRegistryImpl extends PacketRegistryImpl implements protected void onUnregister(Identifier id) { ClientPlayNetworkHandler handler = MinecraftClient.getInstance().getNetworkHandler(); if (handler != null) { - handler.sendPacket(createRegisterTypePacket(PacketTypes.UNREGISTER, Collections.singleton(id))); + createRegisterTypePacket(PacketTypes.UNREGISTER, Collections.singleton(id)).ifPresent(handler::sendPacket); } } diff --git a/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/PacketRegistryImpl.java b/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/PacketRegistryImpl.java index 86c0d8cd0..3ce9bca5a 100644 --- a/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/PacketRegistryImpl.java +++ b/fabric-networking/src/main/java/net/fabricmc/fabric/impl/network/PacketRegistryImpl.java @@ -27,10 +27,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; public abstract class PacketRegistryImpl implements PacketRegistry { protected static final Logger LOGGER = LogManager.getLogger(); @@ -40,7 +37,7 @@ public abstract class PacketRegistryImpl implements PacketRegistry { consumerMap = new LinkedHashMap<>(); } - public static Packet<?> createInitialRegisterPacket(PacketRegistry registry) { + public static Optional<Packet<?>> createInitialRegisterPacket(PacketRegistry registry) { PacketRegistryImpl impl = (PacketRegistryImpl) registry; return impl.createRegisterTypePacket(PacketTypes.REGISTER, impl.consumerMap.keySet()); } @@ -75,7 +72,11 @@ public abstract class PacketRegistryImpl implements PacketRegistry { protected abstract void onReceivedUnregisterPacket(PacketContext context, Collection<Identifier> ids); - protected Packet<?> createRegisterTypePacket(Identifier id, Collection<Identifier> ids) { + protected Optional<Packet<?>> createRegisterTypePacket(Identifier id, Collection<Identifier> ids) { + if (ids.isEmpty()) { + return Optional.empty(); + } + PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer()); boolean first = true; for (Identifier a : ids) { @@ -86,7 +87,7 @@ public abstract class PacketRegistryImpl implements PacketRegistry { } buf.writeBytes(a.toString().getBytes(StandardCharsets.US_ASCII)); } - return toPacket(id, buf); + return Optional.of(toPacket(id, buf)); } private boolean acceptRegisterType(Identifier id, PacketContext context, PacketByteBuf buf) { @@ -96,6 +97,7 @@ public abstract class PacketRegistryImpl implements PacketRegistry { StringBuilder sb = new StringBuilder(); char c; + int oldIndex = buf.readerIndex(); while (buf.readerIndex() < buf.writerIndex()) { c = (char) buf.readByte(); if (c == 0) { @@ -108,6 +110,7 @@ public abstract class PacketRegistryImpl implements PacketRegistry { sb.append(c); } } + buf.readerIndex(oldIndex); String s = sb.toString(); if (!s.isEmpty()) { diff --git a/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinClientPlayNetworkHandler.java b/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinClientPlayNetworkHandler.java index 1f78e65d3..d37925fb7 100644 --- a/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinClientPlayNetworkHandler.java +++ b/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinClientPlayNetworkHandler.java @@ -35,6 +35,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Optional; + @Mixin(ClientPlayNetworkHandler.class) public abstract class MixinClientPlayNetworkHandler implements PacketContext { @Shadow @@ -45,7 +47,11 @@ public abstract class MixinClientPlayNetworkHandler implements PacketContext { @Inject(at = @At("RETURN"), method = "onGameJoin") public void onGameJoin(GameJoinS2CPacket packet, CallbackInfo info) { - sendPacket(PacketRegistryImpl.createInitialRegisterPacket(ClientSidePacketRegistry.INSTANCE)); + Optional<Packet<?>> optionalPacket = PacketRegistryImpl.createInitialRegisterPacket(ClientSidePacketRegistry.INSTANCE); + //noinspection OptionalIsPresent + if (optionalPacket.isPresent()) { + sendPacket(optionalPacket.get()); + } } // Optional hook: it only removes a warning message. diff --git a/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinPlayerManager.java b/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinPlayerManager.java new file mode 100644 index 000000000..6199eb71a --- /dev/null +++ b/fabric-networking/src/main/java/net/fabricmc/fabric/mixin/network/MixinPlayerManager.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.network; + +import net.fabricmc.fabric.api.network.ServerSidePacketRegistry; +import net.fabricmc.fabric.impl.network.PacketRegistryImpl; +import net.minecraft.network.ClientConnection; +import net.minecraft.network.Packet; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ServerPlayerEntity; +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 java.util.Optional; + +@Mixin(priority = 500, value = PlayerManager.class) +public abstract class MixinPlayerManager { + @Inject(method = "onPlayerConnect", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/packet/DifficultyS2CPacket;<init>(Lnet/minecraft/world/Difficulty;Z)V")) + public void onPlayerConnect(ClientConnection lvt1, ServerPlayerEntity lvt2, CallbackInfo info) { + Optional<Packet<?>> optionalPacket = PacketRegistryImpl.createInitialRegisterPacket(ServerSidePacketRegistry.INSTANCE); + //noinspection OptionalIsPresent + if (optionalPacket.isPresent()) { + lvt2.networkHandler.sendPacket(optionalPacket.get()); + } + } +} diff --git a/fabric-networking/src/main/resources/fabric-networking.mixins.json b/fabric-networking/src/main/resources/fabric-networking.mixins.json index 12a261327..ab9bd3d52 100644 --- a/fabric-networking/src/main/resources/fabric-networking.mixins.json +++ b/fabric-networking/src/main/resources/fabric-networking.mixins.json @@ -5,6 +5,7 @@ "mixins": [ "MixinCustomPayloadC2SPacket", "MixinEntityTracker", + "MixinPlayerManager", "MixinServerPlayNetworkHandler", "MixinThreadedAnvilChunkStorage" ], diff --git a/fabric-registry-sync/src/main/java/net/fabricmc/fabric/mixin/registry/MixinPlayerManager.java b/fabric-registry-sync/src/main/java/net/fabricmc/fabric/mixin/registry/MixinPlayerManager.java index 1a25d7164..7583431ff 100644 --- a/fabric-registry-sync/src/main/java/net/fabricmc/fabric/mixin/registry/MixinPlayerManager.java +++ b/fabric-registry-sync/src/main/java/net/fabricmc/fabric/mixin/registry/MixinPlayerManager.java @@ -33,7 +33,6 @@ public abstract class MixinPlayerManager { public void onPlayerConnect(ClientConnection lvt1, ServerPlayerEntity lvt2, CallbackInfo info) { // TODO: If integrated and local, don't send the packet (it's ignored) // TODO: Refactor out into network + move registry hook to event - lvt2.networkHandler.sendPacket(PacketRegistryImpl.createInitialRegisterPacket(ServerSidePacketRegistry.INSTANCE)); lvt2.networkHandler.sendPacket(RegistrySyncManager.createPacket()); } }