# Hand fixes applied on top of FernFlower's output.
#
# Decompiling is repeatable; these corrections are not, so they live here and
# get re-applied by tools/apply_patches.py after every re-decompile.
#
# Why each one is needed is in the patch body.

=== FILE net/minecraft/block/BlockPortal.java
--- BEFORE
PropertyEnum.create("axis", EnumFacing.Axis.class, (Enum[])(EnumFacing.Axis.X, EnumFacing.Axis.Z));
--- AFTER
PropertyEnum.create("axis", EnumFacing.Axis.class, new EnumFacing.Axis[]{EnumFacing.Axis.X, EnumFacing.Axis.Z});

=== FILE net/minecraft/util/IObjectIntIterable.java
--- REPLACE
package net.minecraft.util;

/**
 * Signature restored by hand.
 *
 * ProGuard dropped the generic Signature attribute from this class, so the
 * decompiler emitted it raw while every use site still carried a type argument.
 * That single missing parameter produced the majority of the compile errors:
 * raw here means raw everywhere downstream.
 *
 * There is no method on this interface. The "object to int" name comes from the
 * classes that implement it, which each expose their own lookup; declaring one
 * here would force every implementation to invent it.
 */
public interface IObjectIntIterable<K> extends Iterable<K> {
}
# An Object[] cast assigned into a K[] field. Vanilla writes (K[])new Object[n],
# an unchecked cast that compiles; the decompiler emitted the erased type
# instead, which does not.
=== FILE net/minecraft/util/IntIdentityHashBiMap.java
--- BEFORE
(Object[]) (new Object[i])
--- AFTER
(K[]) (new Object[i])

# getEntities/getPlayers take Predicate<? super T>, but the decompiler typed the
# loop variable as raw Entity, so the call cannot be checked. Declaring it as T
# is what vanilla does. Multi-line context on purpose: a bare "list.add(entity)"
# would also rewrite this.loadedEntityList.add(entity).
=== FILE net/minecraft/world/storage/loot/properties/EntityPropertyManager.java
--- BEFORE
            throw new IllegalArgumentException("Unknown loot entity property " + t0);
        } else {
            return entityproperty_serializer;
--- AFTER
            throw new IllegalArgumentException("Unknown loot entity property " + t0);
        } else {
            return (EntityProperty.Serializer<T>) entityproperty_serializer;

=== FILE net/minecraft/world/World.java
--- BEFORE
            if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply(entity)) {
                list.add(entity);
            }
--- AFTER
            if (oclass.isAssignableFrom(entity.getClass()) && predicate.apply((T) entity)) {
                list.add((T) entity);
            }

=== FILE net/minecraft/world/World.java
--- BEFORE
            T t2 = (Entity) list.get(i);
--- AFTER
            T t2 = (T) list.get(i);

# Overriding methods came out protected while every one of them is public in
# MinecraftServer. Narrowing visibility is not an override, so all six fail.
=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected ServerCommandManager createCommandManager() {
--- AFTER
    public ServerCommandManager createCommandManager() {

=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected void loadAllWorlds(String s, String s1, long i, WorldType worldtype, String s2) {
--- AFTER
    public void loadAllWorlds(String s, String s1, long i, WorldType worldtype, String s2) {

=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected boolean init() throws IOException {
--- AFTER
    public boolean init() throws IOException {

=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected void tick() {
--- AFTER
    public void tick() {

=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected void saveAllWorlds(boolean flag) {
--- AFTER
    public void saveAllWorlds(boolean flag) {

=== FILE net/minecraft/server/integrated/IntegratedServer.java
--- BEFORE
    protected void finalTick(CrashReport crashreport) {
--- AFTER
    public void finalTick(CrashReport crashreport) {

# The constructor took a raw Function, so no constructor reference could bind to
# it. Typing it as the field is what lets MovementStep::new resolve.
=== FILE net/minecraft/client/tutorial/TutorialSteps.java
--- BEFORE
    private TutorialSteps(String s, Function function) {
--- AFTER
    private TutorialSteps(String s, Function<Tutorial, ? extends ITutorialStep> function) {

# Erased types where the surrounding signature is generic: Object[] cannot be
# assigned to T[], and a raw Iterator yields Object.
=== FILE net/minecraft/util/math/Cartesian.java
--- BEFORE
        Iterator iterator = iterable.iterator();

        while (iterator.hasNext()) {
            T t0 = iterator.next();
--- AFTER
        Iterator<? extends T> iterator = iterable.iterator();

        while (iterator.hasNext()) {
            T t0 = iterator.next();

=== FILE net/minecraft/util/math/Cartesian.java
--- BEFORE
        return (Object[]) list.toArray(createArray(oclass, list.size()));
--- AFTER
        return (T[]) list.toArray(createArray(oclass, list.size()));

=== FILE net/minecraft/util/math/Cartesian.java
--- BEFORE
        return (Object[]) ((Object[]) Array.newInstance(oclass, i));
--- AFTER
        return (T[]) Array.newInstance(oclass, i);

=== FILE net/minecraft/util/math/Cartesian.java
--- BEFORE
                    return (Object[]) this.results.clone();
--- AFTER
                    return (T[]) this.results.clone();

# matchOneEntity returns T, not Entity. And the team/name/tag arguments are
# rewritten below their own declaration, so they cannot be final.
=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        return list.size() == 1 ? (Entity) list.get(0) : null;
--- AFTER
        return list.size() == 1 ? (T) list.get(0) : null;

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
                                        return Lists.newArrayList(new Entity[]{entity});
--- AFTER
                                        return Lists.newArrayList((T) entity);

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        final String s = getArgument(map, EntitySelector.ARGUMENT_TEAM_NAME);
--- AFTER
        String s = getArgument(map, EntitySelector.ARGUMENT_TEAM_NAME);

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        final String s = getArgument(map, EntitySelector.ARGUMENT_PLAYER_NAME);
--- AFTER
        String s = getArgument(map, EntitySelector.ARGUMENT_PLAYER_NAME);

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        final String s = getArgument(map, EntitySelector.ARGUMENT_ENTITY_TAG);
--- AFTER
        String s = getArgument(map, EntitySelector.ARGUMENT_ENTITY_TAG);

# FernFlower wrote "null." where the owning type belonged, so every setRespawnState
# call referenced a literal null. The constants live on DragonSpawnManager itself.
=== FILE net/minecraft/world/end/DragonSpawnManager.java
--- BEFORE
setRespawnState(null.
--- AFTER
setRespawnState(DragonSpawnManager.

# getEntityClassRenderObject is generic in T but the local was declared with a
# wildcard, so the recursive call and the return could not be checked. Also the
# ternary has no inferable T at all.
=== FILE net/minecraft/client/renderer/entity/RenderManager.java
--- BEFORE
        Render<? extends Entity> render = (Render) this.entityRenderMap.get(oclass);
--- AFTER
        Render<T> render = (Render) this.entityRenderMap.get(oclass);

=== FILE net/minecraft/client/renderer/entity/RenderManager.java
--- BEFORE
            render = this.getEntityClassRenderObject(oclass.getSuperclass());
--- AFTER
            render = (Render) this.getEntityClassRenderObject(oclass.getSuperclass());

=== FILE net/minecraft/client/renderer/entity/RenderManager.java
--- BEFORE
            return renderplayer != null ? renderplayer : this.playerRenderer;
--- AFTER
            return (Render) (renderplayer != null ? renderplayer : this.playerRenderer);

# UserListEntry is the erased supertype; the method is generic in V, so the cast
# has to be to V. createEntry also needs its type argument spelled out because the
# null argument gives the compiler nothing to infer from.
=== FILE net/minecraft/server/management/UserList.java
--- BEFORE
        return (UserListEntry) this.values.get(this.getObjectKey(k0));
--- AFTER
        return (V) this.values.get(this.getObjectKey(k0));

=== FILE net/minecraft/server/management/UserList.java
--- BEFORE
            V v0 = (UserListEntry) iterator.next();
--- AFTER
            V v0 = (V) iterator.next();

=== FILE net/minecraft/server/management/UserList.java
--- BEFORE
            K k0 = iterator.next();
--- AFTER
            K k0 = (K) iterator.next();

=== FILE net/minecraft/server/management/UserList.java
--- BEFORE
        return new UserListEntry<>((Object) null, jsonobject);
--- AFTER
        return new UserListEntry<K>((Object) null, jsonobject);

# Erased types where the surrounding signature is generic. In every case below
# the decompiler substituted the supertype it could see for the type parameter.
=== FILE net/minecraft/util/ClassInheritanceMultiMap.java
--- BEFORE
            T t0 = iterator.next();
--- AFTER
            T t0 = (T) iterator.next();

=== FILE net/minecraft/util/ClassInheritanceMultiMap.java
--- BEFORE
            this.map.put(oclass, Lists.newArrayList(new Object[]{t0}));
--- AFTER
            this.map.put(oclass, Lists.newArrayList(t0));

=== FILE net/minecraft/util/ClassInheritanceMultiMap.java
--- BEFORE
        T t0 = object;
--- AFTER
        T t0 = (T) object;

# getName is generic in the property's own type, so the redundant (Enum) cast
# forced the argument to Enum and broke the call.
=== FILE net/minecraft/client/renderer/BlockModelShapes.java
--- BEFORE
BlockDirt.VARIANT.getName((Enum) ((BlockDirt.DirtType) map.remove(BlockDirt.VARIANT)))
--- AFTER
BlockDirt.VARIANT.getName((BlockDirt.DirtType) map.remove(BlockDirt.VARIANT))

=== FILE net/minecraft/client/renderer/BlockModelShapes.java
--- BEFORE
BlockStoneSlab.VARIANT.getName((Enum) ((BlockStoneSlab.EnumType) map.remove(BlockStoneSlab.VARIANT)))
--- AFTER
BlockStoneSlab.VARIANT.getName((BlockStoneSlab.EnumType) map.remove(BlockStoneSlab.VARIANT))

=== FILE net/minecraft/client/renderer/BlockModelShapes.java
--- BEFORE
BlockStoneSlabNew.VARIANT.getName((Enum) ((BlockStoneSlabNew.EnumType) map.remove(BlockStoneSlabNew.VARIANT)))
--- AFTER
BlockStoneSlabNew.VARIANT.getName((BlockStoneSlabNew.EnumType) map.remove(BlockStoneSlabNew.VARIANT))

# readArray returns List<T extends Number> but stores byte, long and int, none of
# which is T. Vanilla keeps this list raw for exactly that reason.
=== FILE net/minecraft/nbt/JsonToNBT.java
--- BEFORE
        List<T> list = Lists.newArrayList();
--- AFTER
        List list = Lists.newArrayList();

=== FILE net/minecraft/block/state/BlockStateContainer.java
--- BEFORE
                T t0 = (Comparable) iterator.next();
--- AFTER
                T t0 = (T) iterator.next();

=== FILE net/minecraft/block/state/BlockStateContainer.java
--- BEFORE
                return (Comparable) iproperty.getValueClass().cast(comparable);
--- AFTER
                return (T) iproperty.getValueClass().cast(comparable);

# RoomCollection and SecondFloor both have no-argument constructors; the
# decompiler passed a literal null that could not match any of them.
=== FILE net/minecraft/world/gen/structure/WoodlandMansionPieces.java
--- BEFORE
            super(null);
--- AFTER
            super();

=== FILE net/minecraft/command/CommandBase.java
--- BEFORE
            return (Entity) object;
--- AFTER
            return (T) object;

=== FILE net/minecraft/command/CommandBase.java
--- BEFORE
        return iblockstate.withProperty(iproperty, comparable);
--- AFTER
        return iblockstate.withProperty(iproperty, (T) comparable);

=== FILE net/minecraft/command/CommandBase.java
--- BEFORE
        return (Comparable) iproperty.parseValue(s).orNull();
--- AFTER
        return (T) iproperty.parseValue(s).orNull();

# withProperty and getName both need the property's own type parameter, not the
# Comparable supertype the decompiler settled on.
=== FILE net/minecraft/nbt/NBTUtil.java
--- BEFORE
            return iblockstate.withProperty(iproperty, (Comparable) optional.get());
--- AFTER
            return iblockstate.withProperty(iproperty, (T) optional.get());

=== FILE net/minecraft/nbt/NBTUtil.java
--- BEFORE
        return iproperty.getName(comparable);
--- AFTER
        return iproperty.getName((T) comparable);

# raw Entry, so getKey() is Object and cannot go straight into a Map<String, ...>
=== FILE net/minecraft/profiler/Snooper.java
--- BEFORE
                map.put(entry.getKey(), entry.getValue().toString());
--- AFTER
                map.put((String) entry.getKey(), entry.getValue().toString());

# getPropertyName returns String, so the cast belongs on the argument, not on
# the call. Casting the result produced a second error instead of fixing one.
=== FILE net/minecraft/block/state/BlockStateBase.java
--- BEFORE
            return iproperty.getName(comparable);
--- AFTER
            return iproperty.getName((T) comparable);

=== FILE net/minecraft/client/renderer/block/statemap/StateMapperBase.java
--- BEFORE
        return iproperty.getName(comparable);
--- AFTER
        return iproperty.getName((T) comparable);

# Advancement.Builder.resolveParent takes a java.util.function.Function while
# Guava's forMap hands back com.google.common.base.Function. Bridging with a
# method reference keeps both sides on their own interface.
=== FILE net/minecraft/advancements/AdvancementList.java
--- BEFORE
        Function<ResourceLocation, Advancement> function = Functions.forMap(this.advancements, (Object) null);
--- AFTER
        Function<ResourceLocation, Advancement> function = Functions.forMap(this.advancements, null)::apply;

# criteria is keyed by String, the set is a keySet: the second pass needs its
# own iterator of the right element type.
=== FILE net/minecraft/advancements/AdvancementProgress.java
--- BEFORE
        iterator = set.iterator();

        while (iterator.hasNext()) {
            String s = (String) iterator.next();
--- AFTER
        Iterator<String> iterator1 = set.iterator();

        while (iterator1.hasNext()) {
            String s = iterator1.next();

=== FILE net/minecraft/block/state/BlockStateBase.java
--- BEFORE
        return this.withProperty(iproperty, (Comparable) cyclePropertyValue(iproperty.getAllowedValues(), this.getValue(iproperty)));
--- AFTER
        return this.withProperty(iproperty, (T) cyclePropertyValue(iproperty.getAllowedValues(), this.getValue(iproperty)));

# getAllowedValues hands back Collection<capture>, which is not the declared
# element type. Vanilla keeps this list raw for the same reason.
=== FILE net/minecraft/block/state/BlockStateContainer.java
--- BEFORE
        List<Iterable<Comparable<?>>> list = Lists.newArrayList();
--- AFTER
        List list = Lists.newArrayList();

=== FILE net/minecraft/block/state/pattern/BlockStateMatcher.java
--- BEFORE
        return predicate.apply(iblockstate.getValue(iproperty));
--- AFTER
        return ((Predicate) predicate).apply(iblockstate.getValue(iproperty));

=== FILE net/minecraft/block/state/pattern/FactoryBlockPattern.java
--- BEFORE
                            this.symbolMap.put(c0, (Object) null);
--- AFTER
                            this.symbolMap.put(c0, (Predicate<BlockWorldState>) null);

# the local is filled from an ArrayList and from a List, so List is the only
# type both fit
=== FILE net/minecraft/client/gui/GuiIngame.java
--- BEFORE
        ArrayList arraylist;
--- AFTER
        List<Score> arraylist;

=== FILE net/minecraft/client/gui/toasts/GuiToast.java
--- BEFORE
                return guitoast_toastinstance.getToast();
--- AFTER
                return (T) guitoast_toastinstance.getToast();

# the counter is reused below the loop, so it cannot be final
=== FILE net/minecraft/client/particle/ParticleManager.java
--- BEFORE
        for (final int i = 0; i < 3; ++i) {
--- AFTER
        for (int i = 0; i < 3; ++i) {

=== FILE net/minecraft/client/renderer/ItemRenderer.java
--- BEFORE
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.getEntityRenderObject(entityplayersp);
--- AFTER
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.getEntityRenderObject(entityplayersp, RenderPlayer.class);

# getHardware() is declared without getProcessors in the public interface; the
# com.sun one is needed, and its Processor type is not named so the class does
# not have to be resolved at compile time.
=== FILE net/minecraft/client/renderer/OpenGlHelper.java
--- BEFORE
            Processor[] aprocessor = (new SystemInfo()).getHardware().getProcessors();
--- AFTER
            Object[] aprocessor = (Object[]) ((com.sun.management.SystemInfo) new SystemInfo()).getHardware().getProcessors();



=== FILE net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java
--- BEFORE
        TileEntitySpecialRenderer<? extends TileEntity> tileentityspecialrenderer = (TileEntitySpecialRenderer) this.renderers.get(oclass);
--- AFTER
        TileEntitySpecialRenderer<T> tileentityspecialrenderer = (TileEntitySpecialRenderer) this.renderers.get(oclass);

=== FILE net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java
--- BEFORE
            tileentityspecialrenderer = this.getRenderer(oclass.getSuperclass());
--- AFTER
            tileentityspecialrenderer = (TileEntitySpecialRenderer) this.getRenderer(oclass.getSuperclass());

# listFiles is overloaded on FileFilter and FilenameFilter, and the filter is
# an IOFileFilter implementing both
=== FILE net/minecraft/client/resources/FolderResourcePack.java
--- BEFORE
            File[] afile = file.listFiles(DirectoryFileFilter.DIRECTORY);
--- AFTER
            File[] afile = file.listFiles((java.io.FileFilter) DirectoryFileFilter.DIRECTORY);

=== FILE net/minecraft/client/util/SearchTree.java
--- BEFORE
            this.byName.add(t0, s.toLowerCase(Locale.ROOT));
--- AFTER
            this.byName.add(t0, ((String) s).toLowerCase(Locale.ROOT));

=== FILE net/minecraft/command/CommandSpreadPlayers.java
--- BEFORE
                set.add((Object) null);
--- AFTER
                set.add((Team) null);

=== FILE net/minecraft/util/NonNullList.java
--- BEFORE
        return new NonNullList<>(Arrays.asList(aobject), e0);
--- AFTER
        return new NonNullList<E>(Arrays.asList(aobject), e0);

=== FILE net/minecraft/util/datafix/walkers/Filtered.java
--- BEFORE
            this.key = EntityList.getKey(oclass);
--- AFTER
            this.key = EntityList.getKey((Class<? extends Entity>) (Class<?>) oclass);

=== FILE net/minecraft/util/datafix/walkers/Filtered.java
--- BEFORE
            this.key = TileEntity.getKey(oclass);
--- AFTER
            this.key = TileEntity.getKey((Class<? extends TileEntity>) (Class<?>) oclass);

# getEntityRenderObject infers its type parameter from the assignment target and
# lands on Entity. Naming it gives the right renderer type.
=== FILE net/minecraft/client/renderer/ItemRenderer.java
--- BEFORE
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.getEntityRenderObject(entityplayersp, RenderPlayer.class);
--- AFTER
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.<EntityPlayer>getEntityRenderObject(entityplayersp);

# oshi exposes the processor list through CentralProcessor, not directly on
# HardwareAbstractionLayer. Naming Processor is unnecessary, so the class does
# not need to be resolved.
=== FILE net/minecraft/client/renderer/OpenGlHelper.java
--- BEFORE
            Object[] aprocessor = (Object[]) ((com.sun.management.SystemInfo) new SystemInfo()).getHardware().getProcessors();
--- AFTER
            Object[] aprocessor = (Object[]) systeminfo.getHardware().getProcessor().getProcessors();

=== FILE net/minecraft/client/renderer/debug/DebugRendererNeighborsUpdate.java
--- BEFORE
        iterator = map.entrySet().iterator();
--- AFTER
        iterator = (Iterator) map.entrySet().iterator();

=== FILE net/minecraft/client/renderer/entity/RenderLivingBase.java
--- BEFORE
        return this.layerRenderers.add(u0);
--- AFTER
        return this.layerRenderers.add((LayerRenderer<T>) u0);

=== FILE net/minecraft/client/renderer/entity/RenderManager.java
--- BEFORE
            render = (Render) this.getEntityClassRenderObject(oclass.getSuperclass());
--- AFTER
            render = (Render) this.getEntityClassRenderObject((Class<? extends Entity>) (Class<?>) oclass.getSuperclass());

=== FILE net/minecraft/client/renderer/texture/TextureAtlasSprite.java
--- BEFORE
                this.framesTextureData.add((Object) null);
--- AFTER
                this.framesTextureData.add((int[][]) null);

=== FILE net/minecraft/client/renderer/tileentity/TileEntityRendererDispatcher.java
--- BEFORE
            tileentityspecialrenderer = (TileEntitySpecialRenderer) this.getRenderer(oclass.getSuperclass());
--- AFTER
            tileentityspecialrenderer = (TileEntitySpecialRenderer) this.getRenderer((Class<? extends TileEntity>) (Class<?>) oclass.getSuperclass());

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
            list = Lists.newArrayList(new Entity[]{entity});
--- AFTER
            list = Lists.newArrayList((T) entity);

=== FILE net/minecraft/entity/Entity.java
--- BEFORE
                set.add(entity);
--- AFTER
                set.add((T) entity);

=== FILE net/minecraft/entity/EntityList.java
--- BEFORE
                EntityList.OLD_NAMES.add((Object) null);
--- AFTER
                EntityList.OLD_NAMES.add((String) null);

=== FILE net/minecraft/entity/ai/EntityAINearestAttackableTarget.java
--- BEFORE
            }, this.targetEntitySelector);
--- AFTER
            }, (Predicate) this.targetEntitySelector);

=== FILE net/minecraft/item/ItemSlab.java
--- BEFORE
        return this.doubleSlab.getDefaultState().withProperty(iproperty, comparable);
--- AFTER
        return this.doubleSlab.getDefaultState().withProperty(iproperty, (T) comparable);

# Packet<T>.processPacket takes T, which here is the concrete handler subtype.
# Erasing the packet keeps the INetHandler it already is.
=== FILE net/minecraft/network/NetworkManager.java
--- BEFORE
                packet.processPacket(this.packetListener);
--- AFTER
                ((Packet) packet).processPacket(this.packetListener);

=== FILE net/minecraft/tileentity/TileEntityPiston.java
--- BEFORE
TileEntityPiston.MOVING_ENTITY.set((Object) null);
--- AFTER
TileEntityPiston.MOVING_ENTITY.set((EnumFacing) null);

=== FILE net/minecraft/network/datasync/EntityDataManager.java
--- BEFORE
            list.add(new EntityDataManager.DataEntry<>(dataserializer.createKey(short0), dataserializer.read(packetbuffer)));
--- AFTER
            list.add(new EntityDataManager.DataEntry<Object>(dataserializer.createKey(short0), dataserializer.read(packetbuffer)));



=== FILE net/minecraft/client/renderer/OpenGlHelper.java
--- BEFORE
            Object[] aprocessor = (Object[]) systeminfo.getHardware().getProcessor().getProcessors();
--- AFTER
            Object[] aprocessor = (Object[]) (new SystemInfo()).getHardware().getProcessor().getProcessors();

=== FILE net/minecraft/entity/ai/EntityAINearestAttackableTarget.java
--- BEFORE
            this.targetEntity = this.taskOwner.world.getNearestAttackablePlayer(
--- AFTER
            this.targetEntity = (EntityLivingBase) this.taskOwner.world.getNearestAttackablePlayer(

=== FILE net/minecraft/network/datasync/EntityDataManager.java
--- BEFORE
            list.add(new EntityDataManager.DataEntry<Object>(dataserializer.createKey(short0), dataserializer.read(packetbuffer)));
--- AFTER
            list.add(new EntityDataManager.DataEntry<Object>((DataParameter<Object>) dataserializer.createKey(short0), dataserializer.read(packetbuffer)));

=== FILE net/minecraft/network/datasync/EntityDataManager.java
--- BEFORE
        entitydatamanager_dataentry.setValue(entitydatamanager_dataentry1.getValue());
--- AFTER
        entitydatamanager_dataentry.setValue((T) entitydatamanager_dataentry1.getValue());

=== FILE net/minecraft/util/HttpUtil.java
--- BEFORE
        return listenablefuture;
--- AFTER
        return (ListenableFuture<Object>) listenablefuture;

=== FILE net/minecraft/util/JsonUtils.java
--- BEFORE
            return gson.getAdapter(TypeToken.get(type)).read(jsonreader);
--- AFTER
            return (T) gson.getAdapter(TypeToken.get(type)).read(jsonreader);

=== FILE net/minecraft/util/NonNullList.java
--- BEFORE
        return new NonNullList<E>(Arrays.asList(aobject), e0);
--- AFTER
        return new NonNullList<E>((List) Arrays.asList(aobject), e0);

=== FILE net/minecraft/util/math/Cartesian.java
--- BEFORE
            return Arrays.asList((Object[]) aobject);
--- AFTER
            return Arrays.asList((T[]) aobject);


# EntityPlayer is not imported here, so the type witness needs its full name.
=== FILE net/minecraft/client/renderer/ItemRenderer.java
--- BEFORE
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.<EntityPlayer>getEntityRenderObject(entityplayersp);
--- AFTER
        RenderPlayer renderplayer = (RenderPlayer) this.renderManager.<net.minecraft.client.entity.AbstractClientPlayer>getEntityRenderObject(entityplayersp);

# The bundled oshi is 5.8.5, where CentralProcessor no longer has
# getProcessors(); getProcessorIdentifier() is the replacement that still yields
# a name for this label.
=== FILE net/minecraft/client/renderer/OpenGlHelper.java
--- BEFORE
            Object[] aprocessor = (Object[]) (new SystemInfo()).getHardware().getProcessor().getProcessors();
--- AFTER
            Object[] aprocessor = new Object[]{String.valueOf((new SystemInfo()).getHardware().getProcessor().getProcessorIdentifier())};

# the parameter is final, so the fallback needs its own local
=== FILE net/minecraft/client/renderer/texture/TextureManager.java
--- BEFORE
            itextureobject = TextureUtil.MISSING_TEXTURE;
            this.mapTextureObjects.put(resourcelocation, itextureobject);
--- AFTER
            ITextureObject missing = TextureUtil.MISSING_TEXTURE;
            this.mapTextureObjects.put(resourcelocation, missing);

# targetEntity is declared as T, the class's own type parameter
=== FILE net/minecraft/entity/ai/EntityAINearestAttackableTarget.java
--- BEFORE
            this.targetEntity = (EntityLivingBase) this.taskOwner.world.getNearestAttackablePlayer(
--- AFTER
            this.targetEntity = (T) this.taskOwner.world.getNearestAttackablePlayer(


# The anonymous class captures the loop variable, which a for-loop never lets be
# effectively final. Capturing a copy is what the original bytecode did.
=== FILE net/minecraft/client/particle/ParticleManager.java
--- BEFORE
                            crashreportcategory.addDetail("Particle Type", new ICrashReportDetail<String>() {
                                public String call() throws Exception {
                                    return i == 0 ? "MISC_TEXTURE" : (i == 1 ? "TERRAIN_TEXTURE" : (i == 3 ? "ENTITY_PARTICLE_TEXTURE" : "Unknown - " + i));
                                }
                            });
--- AFTER
                            final int layer = i;
                            crashreportcategory.addDetail("Particle Type", new ICrashReportDetail<String>() {
                                public String call() throws Exception {
                                    return layer == 0 ? "MISC_TEXTURE" : (layer == 1 ? "TERRAIN_TEXTURE" : (layer == 3 ? "ENTITY_PARTICLE_TEXTURE" : "Unknown - " + layer));
                                }
                            });

# j is a mouse-Y scratch value reused a second time further down. The decompiler
# declared it final, which makes the second assignment an error.
=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
        final int j;
--- AFTER
        int j;

# j is assigned twice, so it is not effectively final, and the crash report
# class captures it. Capturing a copy keeps the report correct.
=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
                    crashreportcategory.addDetail("Mouse location", new ICrashReportDetail<String>() {
                        public String call() throws Exception {
                            return String.format("Scaled: (%d, %d). Absolute: (%d, %d)", i1, j, Mouse.getX(), Mouse.getY());
                        }
                    });
--- AFTER
                    final int scaledMouseY = j;
                    crashreportcategory.addDetail("Mouse location", new ICrashReportDetail<String>() {
                        public String call() throws Exception {
                            return String.format("Scaled: (%d, %d). Absolute: (%d, %d)", i1, scaledMouseY, Mouse.getX(), Mouse.getY());
                        }
                    });

# A blank final assigned in both try and catch is rejected: the catch may run
# after the try already stored a value. Computing into a plain local first and
# freezing it afterwards says the same thing and is legal.
=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
            final GameType gametype;

            try {
                int i = Integer.parseInt(s);

                gametype = GameType.parseGameTypeWithDefault(i, GameType.NOT_SET);
            } catch (Throwable throwable) {
                gametype = GameType.parseGameTypeWithDefault(s, GameType.NOT_SET);
            }
--- AFTER
            GameType parsedGameType;

            try {
                int i = Integer.parseInt(s);

                parsedGameType = GameType.parseGameTypeWithDefault(i, GameType.NOT_SET);
            } catch (Throwable throwable) {
                parsedGameType = GameType.parseGameTypeWithDefault(s, GameType.NOT_SET);
            }

            final GameType gametype = parsedGameType;

# s is rewritten when the argument is negated, so the predicate captures a copy.
=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        if (s != null) {
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (!(entity instanceof EntityLivingBase)) {
--- AFTER
        if (s != null) {
            final String teamName = s;
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (!(entity instanceof EntityLivingBase)) {

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
                        return s1.equals(s) != flag;
--- AFTER
                        return s1.equals(teamName) != flag;

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        if (s != null) {
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    return entity != null && entity.getName().equals(s) != flag;
                }
            });
        }
--- AFTER
        if (s != null) {
            final String playerName = s;
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    return entity != null && entity.getName().equals(playerName) != flag;
                }
            });
        }

# i and j are blank finals assigned in two separate blocks, and each predicate
# captures them. One pair of locals per block is what the original meant.
=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        final int i;
        final int j;

        if (map.containsKey(EntitySelector.ARGUMENT_ROTY_MIN) || map.containsKey(EntitySelector.ARGUMENT_ROTY_MAX)) {
            i = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTY_MIN, 0));
            j = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTY_MAX, 359));
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (entity == null) {
                        return false;
                    } else {
                        int k = MathHelper.wrapDegrees(MathHelper.floor(entity.rotationYaw));

                        return i > j ? k >= i || k <= j : k >= i && k <= j;
                    }
                }
            });
        }

        if (map.containsKey(EntitySelector.ARGUMENT_ROTX_MIN) || map.containsKey(EntitySelector.ARGUMENT_ROTX_MAX)) {
            i = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTX_MIN, 0));
            j = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTX_MAX, 359));
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (entity == null) {
                        return false;
                    } else {
                        int k = MathHelper.wrapDegrees(MathHelper.floor(entity.rotationPitch));

                        return i > j ? k >= i || k <= j : k >= i && k <= j;
                    }
                }
            });
        }
--- AFTER
        if (map.containsKey(EntitySelector.ARGUMENT_ROTY_MIN) || map.containsKey(EntitySelector.ARGUMENT_ROTY_MAX)) {
            final int minYaw = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTY_MIN, 0));
            final int maxYaw = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTY_MAX, 359));
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (entity == null) {
                        return false;
                    } else {
                        int k = MathHelper.wrapDegrees(MathHelper.floor(entity.rotationYaw));

                        return minYaw > maxYaw ? k >= minYaw || k <= maxYaw : k >= minYaw && k <= maxYaw;
                    }
                }
            });
        }

        if (map.containsKey(EntitySelector.ARGUMENT_ROTX_MIN) || map.containsKey(EntitySelector.ARGUMENT_ROTX_MAX)) {
            final int minPitch = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTX_MIN, 0));
            final int maxPitch = MathHelper.wrapDegrees(getInt(map, EntitySelector.ARGUMENT_ROTX_MAX, 359));
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    if (entity == null) {
                        return false;
                    } else {
                        int k = MathHelper.wrapDegrees(MathHelper.floor(entity.rotationPitch));

                        return minPitch > maxPitch ? k >= minPitch || k <= maxPitch : k >= minPitch && k <= maxPitch;
                    }
                }
            });
        }

=== FILE net/minecraft/command/EntitySelector.java
--- BEFORE
        if (s != null) {
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    return entity == null ? false : ("".equals(s) ? entity.getTags().isEmpty() != flag : entity.getTags().contains(s) != flag);
                }
            });
        }
--- AFTER
        if (s != null) {
            final String tag = s;
            list.add(new Predicate<Entity>() {
                public boolean apply(@Nullable Entity entity) {
                    return entity == null ? false : ("".equals(tag) ? entity.getTags().isEmpty() != flag : entity.getTags().contains(tag) != flag);
                }
            });
        }

# FernFlower moved shutdownMinecraftApplet() into a finally on the game loop
# body. A continue inside a try runs the finally first, so the client shut
# down after one frame. javap on the original bytecode shows shutdown is
# only reached at loop exit (offset 103) and from the catch handlers.
=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
    public void run() {
        this.running = true;

        CrashReport crashreport;

        try {
            this.init();
        } catch (Throwable throwable) {
            crashreport = CrashReport.makeCrashReport(throwable, "Initializing game");
            crashreport.makeCategory("Initialization");
            this.displayCrashReport(this.addGraphicsAndWorldToCrashReport(crashreport));
            return;
        }

        while (true) {
            try {
                if (!this.running) {
                    break;
                }

                if (!this.hasCrashed || this.crashReporter == null) {
                    try {
                        this.runGameLoop();
                    } catch (OutOfMemoryError outofmemoryerror) {
                        this.freeMemory();
                        this.displayGuiScreen(new GuiMemoryErrorScreen());
                        System.gc();
                    }
                    continue;
                }

                this.displayCrashReport(this.crashReporter);
            } catch (MinecraftError minecrafterror) {
                break;
            } catch (ReportedException reportedexception) {
                this.addGraphicsAndWorldToCrashReport(reportedexception.getCrashReport());
                this.freeMemory();
                Minecraft.LOGGER.fatal("Reported exception thrown!", reportedexception);
                this.displayCrashReport(reportedexception.getCrashReport());
                break;
            } catch (Throwable throwable1) {
                crashreport = this.addGraphicsAndWorldToCrashReport(new CrashReport("Unexpected error", throwable1));
                this.freeMemory();
                Minecraft.LOGGER.fatal("Unreported exception thrown!", throwable1);
                this.displayCrashReport(crashreport);
                break;
            } finally {
                this.shutdownMinecraftApplet();
            }

            return;
        }

    }
--- AFTER
    public void run() {
        this.running = true;

        CrashReport crashreport;

        try {
            this.init();
        } catch (Throwable throwable) {
            crashreport = CrashReport.makeCrashReport(throwable, "Initializing game");
            crashreport.makeCategory("Initialization");
            this.displayCrashReport(this.addGraphicsAndWorldToCrashReport(crashreport));
            return;
        }

        try {
            while (true) {
                if (!this.running) {
                    break;
                }

                if (this.hasCrashed && this.crashReporter != null) {
                    this.displayCrashReport(this.crashReporter);
                    this.shutdownMinecraftApplet();
                    return;
                }

                try {
                    this.runGameLoop();
                } catch (OutOfMemoryError outofmemoryerror) {
                    this.freeMemory();
                    this.displayGuiScreen(new GuiMemoryErrorScreen());
                    System.gc();
                }
            }

            this.shutdownMinecraftApplet();
        } catch (MinecraftError minecrafterror) {
            this.shutdownMinecraftApplet();
        } catch (ReportedException reportedexception) {
            this.addGraphicsAndWorldToCrashReport(reportedexception.getCrashReport());
            this.freeMemory();
            Minecraft.LOGGER.fatal("Reported exception thrown!", reportedexception);
            this.displayCrashReport(reportedexception.getCrashReport());
            this.shutdownMinecraftApplet();
        } catch (Throwable throwable1) {
            crashreport = this.addGraphicsAndWorldToCrashReport(new CrashReport("Unexpected error", throwable1));
            this.freeMemory();
            Minecraft.LOGGER.fatal("Unreported exception thrown!", throwable1);
            this.displayCrashReport(crashreport);
            this.shutdownMinecraftApplet();
        }
    }

=== FILE net/minecraft/entity/player/EntityPlayerMP.java
--- BEFORE
        this.entityRemoveQueue.remove(entity.getEntityId());
--- AFTER
        this.entityRemoveQueue.remove(Integer.valueOf(entity.getEntityId()));

=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
this.renderGlobal.makeEntityOutlineShader();
    }

    private void populateSearchTreeManager() {
--- AFTER
net.rustnotmc.client.RsxBootstrap.start(this);
        this.renderGlobal.makeEntityOutlineShader();
    }

    private void populateSearchTreeManager() {

=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
GlStateManager.popMatrix();
        this.profiler.startSection("root");
        this.updateDisplay();
--- AFTER
GlStateManager.popMatrix();
        net.rustnotmc.client.RsxBootstrap.renderFrame(this);
        this.profiler.startSection("root");
        this.updateDisplay();

=== FILE net/minecraft/client/gui/GuiScreen.java
--- BEFORE
public void sendChatMessage(String s, boolean flag) {
        if (flag) {
            this.mc.ingameGUI.getChatGUI().addToSentMessages(s);
        }

        this.mc.player.sendChatMessage(s);
    }
--- AFTER
public void sendChatMessage(String s, boolean flag) {
        if (flag) {
            this.mc.ingameGUI.getChatGUI().addToSentMessages(s);
        }

        // a mod command scoped to the client is carried out here and stops here.
        // Anything the server owns is left alone so it still reaches the server.
        if (net.rustnotmc.client.RsxBootstrap.handleChatCommand(s)) {
            return;
        }

        this.mc.player.sendChatMessage(s);
    }

=== FILE net/minecraft/entity/Entity.java
--- BEFORE
this.collidedHorizontally = d7 != d0 || d9 != d2;
            this.collidedVertically = d1 != d1;
            this.onGround = this.collidedVertically && d8 < 0.0D;
--- AFTER
this.collidedHorizontally = d7 != d0 || d9 != d2;
            this.collidedVertically = d8 != d1;
            this.onGround = this.collidedVertically && d8 < 0.0D;

=== FILE net/minecraft/client/particle/Particle.java
--- BEFORE
this.onGround = d1 != d1 && d3 < 0.0D;
        if (d0 != d0) {
            this.motionX = 0.0D;
        }

        if (d2 != d2) {
            this.motionZ = 0.0D;
        }
--- AFTER
this.onGround = originalY != d1 && originalY < 0.0D;
        if (originalX != d0) {
            this.motionX = 0.0D;
        }

        if (originalZ != d2) {
            this.motionZ = 0.0D;
        }

=== FILE net/minecraft/client/particle/Particle.java
--- BEFORE
double d3 = d1;

        if (this.canCollide) {
--- AFTER
// the motion before collision; the axis is only stopped when collision
        // actually changed it, which a comparison against itself can never see
        double originalX = d0;
        double originalY = d1;
        double originalZ = d2;

        if (this.canCollide) {

=== FILE net/minecraft/entity/Entity.java
--- BEFORE
boolean flag = this.onGround || d1 != d1 && d1 < 0.0D;
--- AFTER
boolean flag = this.onGround || d8 != d1 && d8 < 0.0D;





=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
for (int k = 0; k < Math.min(10, this.timer.elapsedTicks); ++k) {
            this.runTick();
        }
--- AFTER
for (int k = 0; k < Math.min(10, this.timer.elapsedTicks); ++k) {
            this.runTick();
            net.rustnotmc.client.RsxBootstrap.clientTick();
        }

=== FILE net/minecraft/client/LoadingScreenRenderer.java
--- BEFORE
this.framebuffer.framebufferRender(l * k, i1 * k);
                }

                this.mc.updateDisplay();
--- AFTER
this.framebuffer.framebufferRender(l * k, i1 * k);
                }

                net.rustnotmc.client.RsxBootstrap.renderLoadingScreen(this.mc);

                this.mc.updateDisplay();

=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
                this.mouseHelper.grabMouseCursor();
                this.displayGuiScreen((GuiScreen) null);
                this.leftClickCounter = 10000;
--- AFTER
                this.mouseHelper.grabMouseCursor();
                // the login screen has to survive the window being focused.
                // Focusing the window is exactly what a player does before
                // typing their password, and the game would otherwise put the
                // main menu up in the moment the cursor lands in the box.
                if (!(this.currentScreen instanceof GuiConnecting)) {
                    this.displayGuiScreen((GuiScreen) null);
                }
                this.leftClickCounter = 10000;


=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
import org.lwjgl.opengl.ContextCapabilities;
--- AFTER
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.ContextCapabilities;

=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
        try {
            Display.create((new PixelFormat()).withDepthBits(24));
        } catch (LWJGLException lwjglexception) {
            Minecraft.LOGGER.error("Couldn't set pixel format", lwjglexception);

            try {
                Thread.sleep(1000L);
            } catch (InterruptedException interruptedexception) {
                ;
            }

            if (this.fullscreen) {
                this.updateDisplayMode();
            }

            Display.create();
        }
--- AFTER
        try {
            Display.create((new PixelFormat()).withDepthBits(24).withStencilBits(8),
                    new ContextAttribs(3, 3).withProfileCompatibility(true));
        } catch (LWJGLException noContext) {
            // The driver may have no 3.3 context, and the game is perfectly
            // happy on an older one. The far view wants a modern one, but it
            // can be written for whatever the context turns out to be.
            Minecraft.LOGGER.warn("Could not create a 3.3 context, trying an older one", noContext);

            try {
                Display.create((new PixelFormat()).withDepthBits(24));
            } catch (LWJGLException lwjglexception) {
                Minecraft.LOGGER.error("Couldn't set pixel format", lwjglexception);

                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException interruptedexception) {
                    ;
                }

                if (this.fullscreen) {
                    this.updateDisplayMode();
                }

                Display.create();
            }
        }

        net.rustnotmc.client.RsxBootstrap.logGl();


=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
        this.sendClickBlockToController(this.currentScreen == null && this.gameSettings.keyBindAttack.isKeyDown() && this.inGameHasFocus);
--- AFTER
        // Breaking happens on the press, in clickMouse, and not on every frame
        // the button is held. The game sends a dig packet for each of those
        // frames, so a held button used to break a whole line of blocks across
        // the world instead of the one under the crosshair.
        this.sendClickBlockToController(false);

=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
    private void clickMouse() {
        if (this.leftClickCounter <= 0) {
            if (this.objectMouseOver == null) {
--- AFTER
    private void clickMouse() {
        if (this.leftClickCounter <= 0) {
            net.rustnotmc.client.net.RsxClientMode.onLeftClick(this);
            if (this.objectMouseOver == null) {

=== FILE net/minecraft/client/multiplayer/PlayerControllerMP.java
--- BEFORE
    public boolean clickBlock(BlockPos blockpos, EnumFacing enumfacing) {
        if (this.currentGameType.hasLimitedInteractions()) {
--- AFTER
    public boolean clickBlock(BlockPos blockpos, EnumFacing enumfacing) {
        // in a survival world the player breaks nothing, so the game is not
        // allowed to start breaking either
        if (!net.rustnotmc.client.net.RsxClientMode.canBreakBlocks()) {
            return false;
        }

        if (this.currentGameType.hasLimitedInteractions()) {

=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
    private boolean isDrawBlockOutline() {
        if (!this.drawBlockOutline) {
            return false;
        } else {
            Entity entity = this.mc.getRenderViewEntity();
--- AFTER
    private boolean isDrawBlockOutline() {
        if (!this.drawBlockOutline) {
            return false;
        } else {
            // a block that cannot be broken is not pointed out either: the
            // highlight says "here" and then nothing happens
            if (!net.rustnotmc.client.net.RsxClientMode.canBreakBlocks()) {
                return false;
            }

            Entity entity = this.mc.getRenderViewEntity();

# Our player. The class is ours, the behaviour is the vanilla one, and the two
# numbers that differ from the vanilla live in RsxPlayerTuning.
=== FILE net/minecraft/client/multiplayer/PlayerControllerMP.java
--- BEFORE
        return new EntityPlayerSP(this.mc, world, this.connection, statisticsmanager, recipebook);
--- AFTER
        return new net.rustnotmc.client.RsxPlayer(this.mc, world, this.connection, statisticsmanager, recipebook);

# The movement input of our player: the same input with our crouch in it.
=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
        this.player.movementInput = new MovementInputFromOptions(this.gameSettings);
--- AFTER
        this.player.movementInput = new net.rustnotmc.client.RsxMovementInput(this.gameSettings);

# Our crouch is lower than the vanilla one, so the player fits through a hole
# of one and a half blocks. The number lives in RsxPlayerTuning.
=== FILE net/minecraft/entity/player/EntityPlayer.java
--- BEFORE
        } else if (this.isSneaking()) {
            f = 0.6F;
            f1 = 1.65F;
        } else {
--- AFTER
        } else if (this.isSneaking()) {
            f = 0.6F;
            f1 = net.rustnotmc.client.RsxPlayerTuning.crouchHeight();
        } else {

# A hit has to say where it landed, because the head is worth more than the
# body. The vanilla packet does not carry that, so the server gets one of ours.
=== FILE net/minecraft/client/multiplayer/PlayerControllerMP.java
--- BEFORE
    public void attackEntity(EntityPlayer entityplayer, Entity entity) {
        this.syncCurrentPlayItem();
        this.connection.sendPacket(new CPacketUseEntity(entity));
--- AFTER
    public void attackEntity(EntityPlayer entityplayer, Entity entity) {
        this.syncCurrentPlayItem();
        this.connection.sendPacket(new CPacketUseEntity(entity));
        net.rustnotmc.client.net.RsxNetworkManager.reportAttack(this.mc, entity);

# The chat goes to our server, which is the one who decides who said what.
=== FILE net/minecraft/client/entity/EntityPlayerSP.java
--- BEFORE
    public void sendChatMessage(String s) {
        this.connection.sendPacket(new CPacketChatMessage(s));
    }
--- AFTER
    public void sendChatMessage(String s) {
        this.connection.sendPacket(new CPacketChatMessage(s));
        net.rustnotmc.client.net.RsxNetworkManager.sendChat(s);
    }

# F3+B shows the boxes of the world, and that belongs to the administrators.
# The server says who they are, and a right that is taken away while the
# player is looking takes the boxes with it.
=== FILE net/minecraft/client/Minecraft.java
--- BEFORE
            if (i == 48) {
                flag = !this.renderManager.isDebugBoundingBox();
                this.renderManager.setDebugBoundingBox(flag);
                this.debugFeedbackTranslated(flag ? "debug.show_hitboxes.on" : "debug.show_hitboxes.off");
                return true;
--- AFTER
            if (i == 48) {
                if (!net.rustnotmc.client.net.RsxClientMode.isAdmin()) {
                    this.ingameGUI.getChatGUI().printChatMessage(
                            new net.minecraft.util.text.TextComponentString(
                                    "only an administrator may look at the boxes"));
                    return true;
                }

                flag = !this.renderManager.isDebugBoundingBox();
                this.renderManager.setDebugBoundingBox(flag);
                net.rustnotmc.client.RsxHitboxDebug.setVisible(flag);
                this.debugFeedbackTranslated(flag ? "debug.show_hitboxes.on" : "debug.show_hitboxes.off");
                return true;


# The far view of the world is drawn before the chunks, so that the chunks,
# which are nearer and have all the detail, cover it where they overlap.
=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
        this.mc.profiler.endStartSection("terrain_setup");
        renderglobal.setupTerrain(entity, (double) f, frustum, this.frameCount++, this.mc.player.isSpectator());
--- AFTER
        this.mc.profiler.endStartSection("terrain_setup");
        net.rustnotmc.client.RsxLod.render(this.mc);
        renderglobal.setupTerrain(entity, (double) f, frustum, this.frameCount++, this.mc.player.isSpectator());

# The post effects read the projection the world was drawn with.
=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
            if (this.mc.gameSettings.viewBobbing) {
                this.applyBobbing(f);
            }

        }
    }

    public void disableLightmap() {
--- AFTER
            if (this.mc.gameSettings.viewBobbing) {
                this.applyBobbing(f);
            }
            net.rustnotmc.client.RsxPostPipeline.captureProjection();

        }
    }

    public void disableLightmap() {

# The post effects run on what the world drew, before the hand and the
# interface come over it.
=== FILE net/minecraft/client/renderer/EntityRenderer.java
--- BEFORE
        this.mc.profiler.endStartSection("hand");
        if (this.renderHand) {
--- AFTER
        this.mc.profiler.endStartSection("rsxpost");
        if (i == 2 && !this.mc.gameSettings.anaglyph) {
            net.rustnotmc.client.RsxPostPipeline.apply(this.mc);
        }

        this.mc.profiler.endStartSection("hand");
        if (this.renderHand) {