/* * Decompiled with CFR 0.152. * * Could not load the following classes: * io.netty.buffer.ByteBuf * io.netty.handler.codec.DecoderException * io.netty.handler.codec.EncoderException * it.unimi.dsi.fastutil.objects.Object2IntMap * it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap */ package net.minecraft.network.codec; import io.netty.buffer.ByteBuf; import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.EncoderException; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.util.ArrayList; import java.util.List; import java.util.function.Function; import net.minecraft.network.VarInt; import net.minecraft.network.codec.StreamCodec; public class IdDispatchCodec implements StreamCodec { private static final int UNKNOWN_TYPE = -1; private final Function typeGetter; private final List> byId; private final Object2IntMap toId; private IdDispatchCodec(Function typeGetter, List> byId, Object2IntMap toId) { this.typeGetter = typeGetter; this.byId = byId; this.toId = toId; } @Override public V decode(B input) { int id = VarInt.read(input); if (id < 0 || id >= this.byId.size()) { throw new DecoderException("Received unknown packet id " + id); } Entry entry = this.byId.get(id); try { return (V)entry.serializer.decode(input); } catch (Exception e) { if (e instanceof DontDecorateException) { throw e; } throw new DecoderException("Failed to decode packet '" + String.valueOf(entry.type) + "'", (Throwable)e); } } @Override public void encode(B output, V value) { T type = this.typeGetter.apply(value); int id = this.toId.getOrDefault(type, -1); if (id == -1) { throw new EncoderException("Sending unknown packet '" + String.valueOf(type) + "'"); } VarInt.write(output, id); Entry entry = this.byId.get(id); try { StreamCodec codec = entry.serializer; codec.encode(output, value); } catch (Exception e) { if (e instanceof DontDecorateException) { throw e; } throw new EncoderException("Failed to encode packet '" + String.valueOf(type) + "'", (Throwable)e); } } public static Builder builder(Function typeGetter) { return new Builder(typeGetter); } private record Entry(StreamCodec serializer, T type) { } public static interface DontDecorateException { } public static class Builder { private final List> entries = new ArrayList>(); private final Function typeGetter; private Builder(Function typeGetter) { this.typeGetter = typeGetter; } public Builder add(T type, StreamCodec serializer) { this.entries.add(new Entry(serializer, type)); return this; } public IdDispatchCodec build() { Object2IntOpenHashMap toId = new Object2IntOpenHashMap(); toId.defaultReturnValue(-2); for (Entry entry : this.entries) { int id = toId.size(); int previous = toId.putIfAbsent(entry.type, id); if (previous == -2) continue; throw new IllegalStateException("Duplicate registration for type " + String.valueOf(entry.type)); } return new IdDispatchCodec(this.typeGetter, List.copyOf(this.entries), toId); } } }