fix handling (sending and receiving) of register-type packets

This commit is contained in:
Adrian Siekierka 2019-04-27 01:53:03 +02:00
parent 78659a5bf2
commit 74fd9e78fc
6 changed files with 62 additions and 11 deletions
fabric-networking/src/main
fabric-registry-sync/src/main/java/net/fabricmc/fabric/mixin/registry

View file

@ -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);
}
}

View file

@ -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()) {

View file

@ -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.

View file

@ -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());
}
}
}

View file

@ -5,6 +5,7 @@
"mixins": [
"MixinCustomPayloadC2SPacket",
"MixinEntityTracker",
"MixinPlayerManager",
"MixinServerPlayNetworkHandler",
"MixinThreadedAnvilChunkStorage"
],

View file

@ -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());
}
}