From d0fddeafd93762eacf604bea6406c28a46551db2 Mon Sep 17 00:00:00 2001 From: Fox2Code Date: Mon, 4 Sep 2023 19:31:30 +0200 Subject: [PATCH] Update 1.2.12 --- .../foxloader/client/KeyBindingAPI.java | 4 +- .../client/gui/ContainerWrapped.java | 21 +++ .../client/gui/InventoryBasicClientOnly.java | 9 ++ .../client/gui/InventoryClientOnly.java | 9 ++ .../client/mixins/MixinContainer.java | 19 +++ .../client/mixins/MixinContainerCreative.java | 11 +- .../client/mixins/MixinGameSettings.java | 9 ++ .../client/mixins/MixinGuiIngameMenu.java | 27 ++++ .../client/mixins/MixinItemStack.java | 13 ++ .../client/mixins/MixinNetClientHandler.java | 3 +- .../registry/GameRegistryClient.java | 4 +- .../spark/FoxLoaderClientSparkPlugin.java | 2 +- .../resources/foxloader.client.mixins.json | 1 + .../foxloader/loader/ModContainer.java | 22 +++ .../fox2code/foxloader/loader/ModLoader.java | 8 +- .../fox2code/foxloader/loader/PreLoader.java | 18 ++- .../loader/mixin/MixinTestModePlugin.java | 3 +- .../loader/rebuild/ClassDataProvider.java | 10 +- .../ClientOnlyInventoryTransformer.java | 142 ++++++++++++++++++ .../DevelopmentSourceTransformer.java | 3 +- .../foxloader/registry/GameRegistry.java | 16 +- .../fox2code/foxloader/installer/Main.java | 4 +- gradle.properties | 4 +- .../registry/GameRegistryServer.java | 4 +- .../server/mixins/MixinNetLoginHandler.java | 62 +------- .../foxloader/server/network/LoginState.java | 5 - .../spark/FoxLoaderServerSparkPlugin.java | 2 +- 27 files changed, 345 insertions(+), 90 deletions(-) create mode 100644 client/src/main/java/com/fox2code/foxloader/client/gui/ContainerWrapped.java create mode 100644 client/src/main/java/com/fox2code/foxloader/client/gui/InventoryBasicClientOnly.java create mode 100644 client/src/main/java/com/fox2code/foxloader/client/gui/InventoryClientOnly.java create mode 100644 client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGuiIngameMenu.java create mode 100644 common/src/main/java/com/fox2code/foxloader/loader/transformer/ClientOnlyInventoryTransformer.java delete mode 100644 server/src/main/java/com/fox2code/foxloader/server/network/LoginState.java diff --git a/client/src/main/java/com/fox2code/foxloader/client/KeyBindingAPI.java b/client/src/main/java/com/fox2code/foxloader/client/KeyBindingAPI.java index 67113d2..94e9aba 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/KeyBindingAPI.java +++ b/client/src/main/java/com/fox2code/foxloader/client/KeyBindingAPI.java @@ -11,8 +11,8 @@ public class KeyBindingAPI { public static void registerKeyBinding(KeyBinding keyBinding) { if (loaded) throw new IllegalStateException("Options are already loaded"); - if (registeredKeyBindings.size() >= 9) // This limit will be fixed in future update! - throw new IllegalStateException("Cannot register more than 9 custom key-binds!"); + if (registeredKeyBindings.size() >= 8) // This limit will be fixed in future update! + throw new IllegalStateException("Cannot register more than 8 custom key-binds!"); registeredKeyBindings.add(keyBinding); } diff --git a/client/src/main/java/com/fox2code/foxloader/client/gui/ContainerWrapped.java b/client/src/main/java/com/fox2code/foxloader/client/gui/ContainerWrapped.java new file mode 100644 index 0000000..012277c --- /dev/null +++ b/client/src/main/java/com/fox2code/foxloader/client/gui/ContainerWrapped.java @@ -0,0 +1,21 @@ +package com.fox2code.foxloader.client.gui; + +import net.minecraft.src.client.gui.Container; + +/** + * Tells FoxLoader that the container is a wrapped container. + *

+ * If your container has client side only inventory slots please use {@link InventoryClientOnly} too + */ +public interface ContainerWrapped { + Container getParentContainer(); + + static Container getNetworkContainer(Container container) { + int antiSoftLock = 0; + while (container instanceof ContainerWrapped) { + container = ((ContainerWrapped) container).getParentContainer(); + if (antiSoftLock++>100) return null; + } + return container; + } +} diff --git a/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryBasicClientOnly.java b/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryBasicClientOnly.java new file mode 100644 index 0000000..dfe23b1 --- /dev/null +++ b/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryBasicClientOnly.java @@ -0,0 +1,9 @@ +package com.fox2code.foxloader.client.gui; + +import net.minecraft.src.client.inventory.InventoryBasic; + +public class InventoryBasicClientOnly extends InventoryBasic implements InventoryClientOnly { + public InventoryBasicClientOnly(String var1, int var2) { + super(var1, var2); + } +} diff --git a/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryClientOnly.java b/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryClientOnly.java new file mode 100644 index 0000000..0abc608 --- /dev/null +++ b/client/src/main/java/com/fox2code/foxloader/client/gui/InventoryClientOnly.java @@ -0,0 +1,9 @@ +package com.fox2code.foxloader.client.gui; + +import net.minecraft.src.client.inventory.IInventory; + +/** + * Mark a {@link IInventory} as client side only, and to avoid any network inconsistencies + */ +public interface InventoryClientOnly extends IInventory { +} diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainer.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainer.java index eec68a5..5b01a67 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainer.java +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainer.java @@ -1,11 +1,20 @@ package com.fox2code.foxloader.client.mixins; +import com.fox2code.foxloader.client.gui.ContainerWrapped; import net.minecraft.src.client.gui.Container; +import net.minecraft.src.client.gui.GuiContainer; +import net.minecraft.src.client.gui.Slot; import net.minecraft.src.game.entity.player.EntityPlayer; +import net.minecraft.src.game.item.ItemStack; 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; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; @Mixin(Container.class) @@ -16,4 +25,14 @@ public void hotfix_onCraftGuiClosedHook(EntityPlayer var1, CallbackInfo ci) { ci.cancel(); } } + + /** + * Disable default behaviour on wrapped container for better stability. + */ + @Inject(method = "quickMove", at = @At("HEAD"), cancellable = true) + public void onQuickMove(int var1, CallbackInfoReturnable cir) { + if (this instanceof ContainerWrapped) { + cir.setReturnValue(null); + } + } } diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainerCreative.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainerCreative.java index 3816af1..d5a9af5 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainerCreative.java +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinContainerCreative.java @@ -1,6 +1,8 @@ package com.fox2code.foxloader.client.mixins; import com.fox2code.foxloader.client.CreativeItems; +import com.fox2code.foxloader.client.gui.ContainerWrapped; +import net.minecraft.src.client.gui.Container; import net.minecraft.src.client.gui.ContainerCreative; import net.minecraft.src.game.entity.player.EntityPlayer; import net.minecraft.src.game.item.ItemStack; @@ -14,11 +16,13 @@ import java.util.List; @Mixin(ContainerCreative.class) -public abstract class MixinContainerCreative { +public abstract class MixinContainerCreative implements ContainerWrapped { @Shadow public List itemList; @Shadow public abstract void addToSlot(ItemStack itemstack); + @Shadow private EntityPlayer player; + @Inject(method = "addItems", at = @At("HEAD"), cancellable = true) public void onAddItems(EntityPlayer player, CallbackInfo ci) { List creativeItemStacks = @@ -36,4 +40,9 @@ public void onAddItems(EntityPlayer player, CallbackInfo ci) { public void onItemsAdded(EntityPlayer player, CallbackInfo ci) { CreativeItems.Internal.markLoadFinished(this.itemList); } + + @Override + public Container getParentContainer() { + return this.player.playerContainer; + } } diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGameSettings.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGameSettings.java index c848a87..2e01979 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGameSettings.java +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGameSettings.java @@ -4,6 +4,7 @@ import net.minecraft.src.client.EnumOptions; import net.minecraft.src.client.GameSettings; import net.minecraft.src.client.KeyBinding; +import org.lwjgl.input.Keyboard; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -27,4 +28,12 @@ public void onLoadOptionInit(GameSettings instance) { public void onOptionInit(CallbackInfo ci) { this.keyBindings = KeyBindingAPI.Internal.inject(this.keyBindings); } + + @Redirect(method = "*", at = @At(value = "INVOKE", target = + "Lorg/lwjgl/input/Keyboard;getKeyName(I)Ljava/lang/String;")) + public String getKeyName(int i) { + if (i > Keyboard.KEYBOARD_SIZE || i < 0) + return "#" + i; + return Keyboard.getKeyName(i); + } } diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGuiIngameMenu.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGuiIngameMenu.java new file mode 100644 index 0000000..fb1ac04 --- /dev/null +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinGuiIngameMenu.java @@ -0,0 +1,27 @@ +package com.fox2code.foxloader.client.mixins; + +import com.fox2code.foxloader.client.gui.GuiModList; +import com.fox2code.foxloader.client.gui.GuiUpdateButton; +import net.minecraft.src.client.gui.GuiButton; +import net.minecraft.src.client.gui.GuiIngameMenu; +import net.minecraft.src.client.gui.GuiScreen; +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; + +@Mixin(GuiIngameMenu.class) +public class MixinGuiIngameMenu extends GuiScreen { + @Inject(method = "initGui", at = @At(value = "RETURN")) + public void onInitGui(CallbackInfo ci) { + this.controlList.add(new GuiUpdateButton(500, this.width - 62, 2, 60, 20, "Mods")); + } + + @Inject(method = "actionPerformed", at = @At(value = "HEAD"), cancellable = true) + public void onActionPerformed(GuiButton var1, CallbackInfo ci) { + if (var1.id == 500) { + this.mc.displayGuiScreen(new GuiModList(this)); + ci.cancel(); + } + } +} diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinItemStack.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinItemStack.java index eba9aa7..d5acdb7 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinItemStack.java +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinItemStack.java @@ -9,6 +9,9 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; 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.CallbackInfoReturnable; @Mixin(ItemStack.class) public abstract class MixinItemStack implements RegisteredItemStack, NetworkItemStack { @@ -22,6 +25,16 @@ public abstract class MixinItemStack implements RegisteredItemStack, NetworkItem @Shadow public abstract void setItemName(String par1Str); @Shadow public abstract boolean hasDisplayName(); + @Inject(method = "splitStack", at = @At("RETURN")) + public void onSplitStack(int stacksize, CallbackInfoReturnable cir) { + ((NetworkItemStack) (Object) cir.getReturnValue()).setRemoteNetworkId(this.networkId); + } + + @Inject(method = "copy", at = @At("RETURN")) + public void onCopy(CallbackInfoReturnable cir) { + ((NetworkItemStack) (Object) cir.getReturnValue()).setRemoteNetworkId(this.networkId); + } + @Override public RegisteredItem getRegisteredItem() { return (RegisteredItem) this.getItem(); diff --git a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinNetClientHandler.java b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinNetClientHandler.java index a0817d8..6d8396a 100644 --- a/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinNetClientHandler.java +++ b/client/src/main/java/com/fox2code/foxloader/client/mixins/MixinNetClientHandler.java @@ -10,6 +10,7 @@ import net.minecraft.src.client.packets.*; import net.minecraft.src.game.level.WorldClient; 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.Redirect; @@ -17,7 +18,7 @@ @Mixin(NetClientHandler.class) public class MixinNetClientHandler implements NetClientHandlerExtensions { - boolean isFoxLoader = false; + @Unique boolean isFoxLoader = false; @Inject(method = "handlePickupSpawn", at = @At("HEAD")) public void onHandlePickupSpawn(Packet21PickupSpawn packet21, CallbackInfo ci) { diff --git a/client/src/main/java/com/fox2code/foxloader/registry/GameRegistryClient.java b/client/src/main/java/com/fox2code/foxloader/registry/GameRegistryClient.java index 9da11d6..0d9e69f 100644 --- a/client/src/main/java/com/fox2code/foxloader/registry/GameRegistryClient.java +++ b/client/src/main/java/com/fox2code/foxloader/registry/GameRegistryClient.java @@ -140,7 +140,7 @@ public int generateNewItemId(String name, int fallbackId) { @Override public RegisteredBlock registerNewBlock(String name, BlockBuilder blockBuilder, int fallbackId) { - validateRegistryName(name); + name = validateAndFixRegistryName(name); if (blockBuilder == null) blockBuilder = DEFAULT_BLOCK_BUILDER; String secondaryExt = blockBuilder.builtInBlockType.secRegistryExt; Block mainBlock = this.registerNewBlock0(name, blockBuilder, fallbackId, true); @@ -245,7 +245,7 @@ public Block registerNewBlock0(String name, BlockBuilder blockBuilder, int fallb @Override public RegisteredItem registerNewItem(String name, ItemBuilder itemBuilder, int fallbackId) { - validateRegistryName(name); + name = validateAndFixRegistryName(name); return this.registerNewItem0(name, itemBuilder, null, null, this.generateNewItemId(name, fallbackId), true); } diff --git a/client/src/main/java/com/fox2code/foxloader/spark/FoxLoaderClientSparkPlugin.java b/client/src/main/java/com/fox2code/foxloader/spark/FoxLoaderClientSparkPlugin.java index 5dd54d1..4ce2ca6 100644 --- a/client/src/main/java/com/fox2code/foxloader/spark/FoxLoaderClientSparkPlugin.java +++ b/client/src/main/java/com/fox2code/foxloader/spark/FoxLoaderClientSparkPlugin.java @@ -6,7 +6,7 @@ import java.util.stream.Stream; -public class FoxLoaderClientSparkPlugin extends FoxLoaderSparkPlugin { +public class FoxLoaderClientSparkPlugin extends FoxLoaderSparkPlugin implements ClientMod { public FoxLoaderClientSparkPlugin() { super(PlatformInfo.Type.CLIENT); } diff --git a/client/src/main/resources/foxloader.client.mixins.json b/client/src/main/resources/foxloader.client.mixins.json index 0e21bd8..f603ced 100644 --- a/client/src/main/resources/foxloader.client.mixins.json +++ b/client/src/main/resources/foxloader.client.mixins.json @@ -19,6 +19,7 @@ "MixinEntityRenderer", "MixinGameSettings", "MixinGuiDebug", + "MixinGuiIngameMenu", "MixinGuiMainMenu", "MixinGuiTextField", "MixinItem", diff --git a/common/src/main/java/com/fox2code/foxloader/loader/ModContainer.java b/common/src/main/java/com/fox2code/foxloader/loader/ModContainer.java index 0433c50..4cb2f08 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/ModContainer.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/ModContainer.java @@ -19,6 +19,7 @@ import java.util.logging.Logger; public final class ModContainer { + private static final ThreadLocal activeModContainer = new ThreadLocal<>(); // tmp is used to make getModContainer work in constructor. static ModContainer tmp; public final File file; @@ -67,6 +68,27 @@ public final class ModContainer { } } + private ModContainer markActive() { + ModContainer modContainer = activeModContainer.get(); + activeModContainer.set(this); + return modContainer; + } + + public static ModContainer getActiveModContainer() { + return activeModContainer.get(); + } + + static void setActiveModContainer(ModContainer modContainer) { + if (modContainer == null) activeModContainer.remove(); + else activeModContainer.set(modContainer); + } + + public void runInContext(Runnable runnable) { + ModContainer modContainer = markActive(); + runnable.run(); + setActiveModContainer(modContainer); + } + public Mod getClientMod() { return clientMod; } diff --git a/common/src/main/java/com/fox2code/foxloader/loader/ModLoader.java b/common/src/main/java/com/fox2code/foxloader/loader/ModLoader.java index b912e6c..6e5056f 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/ModLoader.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/ModLoader.java @@ -152,6 +152,7 @@ static void initializeModdedInstance(boolean client) { static void initializeMods(boolean client) { gameThread = Thread.currentThread(); for (ModContainer modContainer : modContainers.values()) { + ModContainer.setActiveModContainer(modContainer); try { modContainer.applyMod(client); } catch (ReflectiveOperationException e) { @@ -159,18 +160,23 @@ static void initializeMods(boolean client) { } } for (ModContainer modContainer : modContainers.values()) { + ModContainer.setActiveModContainer(modContainer); modContainer.notifyOnPreInit(); } for (ModContainer modContainer : modContainers.values()) { + ModContainer.setActiveModContainer(modContainer); modContainer.notifyOnInit(); } + ModContainer.setActiveModContainer(null); allModsLoaded = true; } static void postInitializeMods() { for (ModContainer modContainer : modContainers.values()) { + ModContainer.setActiveModContainer(modContainer); modContainer.notifyOnPostInit(); } + ModContainer.setActiveModContainer(null); } @Override @@ -271,7 +277,7 @@ private static void loadModContainerFromLua(File file) { Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { String line; while ((line = bufferedReader.readLine()) != null - && line.startsWith("-- ")) { + && (line.equals("--") || line.startsWith("-- "))) { if (line.startsWith(MOD_ID_LUA_PREFIX)) { id = line.substring(MOD_ID_LUA_PREFIX.length()); } else if (line.startsWith(MOD_NAME_LUA_PREFIX)) { diff --git a/common/src/main/java/com/fox2code/foxloader/loader/PreLoader.java b/common/src/main/java/com/fox2code/foxloader/loader/PreLoader.java index 4a9d8fc..87abc5b 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/PreLoader.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/PreLoader.java @@ -37,6 +37,7 @@ public class PreLoader { private static final String metaInfPath = "META-INF/MANIFEST.MF"; private static final byte[] metaInf = ("Manifest-Version: 1.0\n" + "FoxLoader-Transformer-Version: " + BuildConfig.FOXLOADER_TRANSFORMER_VERSION + + "FoxLoader-ReIndev-Version: " + BuildConfig.REINDEV_VERSION + "Multi-Release: true\n").getBytes(StandardCharsets.UTF_8); private static JvmCompatTransformer jvmCompatTransformer = null; private static final boolean devFoxLoader = FoxLauncher.foxLoaderFile.getAbsolutePath().replace('\\', '/') @@ -47,6 +48,7 @@ public class PreLoader { static { if (devFoxLoader) { + // Workaround FoxLoader not updating properly in dev mode preLoadMetaJarHash.addLong(FoxLauncher.foxLoaderFile.length()); } preComputedFilesForHash.add(FoxLauncher.foxLoaderFile); @@ -190,6 +192,7 @@ static void loadPrePatches(boolean client) { registerPrePatch(new MinecraftClientDebugTransformer()); registerPrePatch(new FrustrumHelperTransformer()); registerPrePatch(new NetworkMappingTransformer()); + registerPrePatch(new ClientOnlyInventoryTransformer()); } } @@ -286,7 +289,20 @@ public static ClassDataProvider getClassDataProvider() { static void registerPrePatch(PreClassTransformer classTransformer) { if (prePatchInitialized) throw new IllegalStateException("Minecraft already pre patched"); - File file = SourceUtil.getSourceFile(classTransformer.getClass()); + Class prePatch = classTransformer.getClass(); + FoxClassLoader foxClassLoader = FoxLauncher.getFoxClassLoader(); + if (foxClassLoader != null) { // <- Can be null when making dev jar + PrePatcher prePatcher = prePatch.getAnnotation(PrePatcher.class); + if (prePatcher != null) { + for (String exclusion : prePatcher.transformerExclusions()) { + if (exclusion.indexOf('.') != -1 && // Add exclusion! + !foxClassLoader.isTransformExclude(exclusion)) { + foxClassLoader.addTransformerExclusion(exclusion); + } + } + } + } + File file = SourceUtil.getSourceFile(prePatch); if (!preComputedFilesForHash.add(file)) { preLoadMetaJarHash.addLong(file.length()); } diff --git a/common/src/main/java/com/fox2code/foxloader/loader/mixin/MixinTestModePlugin.java b/common/src/main/java/com/fox2code/foxloader/loader/mixin/MixinTestModePlugin.java index 4562bc4..a58c450 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/mixin/MixinTestModePlugin.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/mixin/MixinTestModePlugin.java @@ -12,7 +12,8 @@ public class MixinTestModePlugin implements IMixinConfigPlugin { private static final HashSet testModeMixins = new HashSet<>( - Arrays.asList("MixinEntityPlayerMP", "MixinMinecraftServer")); + Arrays.asList("MixinEntity", "MixinEntityPlayerMP", + "MixinMinecraftServer", "MixinStringTranslate")); @Override public void onLoad(String mixinPackage) { diff --git a/common/src/main/java/com/fox2code/foxloader/loader/rebuild/ClassDataProvider.java b/common/src/main/java/com/fox2code/foxloader/loader/rebuild/ClassDataProvider.java index 292f92e..a44bdcc 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/rebuild/ClassDataProvider.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/rebuild/ClassDataProvider.java @@ -34,7 +34,7 @@ public ClassDataProvider(ClassLoader classLoader, Consumer clPatcher) this.clDataHashMap = new HashMap<>(); this.clDataHashMap.put("java/lang/Object", object); this.clDataHashMap.put("[java/lang/Object", objectArray); - this.classLoader = classLoader==null ? + this.classLoader = classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader; this.clPatcher = clPatcher; } @@ -195,7 +195,9 @@ private ClData2Array(ClData clData) { @Override public ClData getSuperclass() { - return ClassDataProvider.this.getClassData("["+clData.superClass); + return ClassDataProvider.this.getClassData( + clData.superClass.endsWith("[java/lang/Object") ? + clData.superClass.substring(1) : "[" + clData.superClass); } @Override @@ -316,11 +318,11 @@ public void visit(int version, int access, String name, String signature, String }); } catch (Exception e) { if (debugClassResolution) { - System.out.println("DEBUG: Invalid input class -> "+name); + System.out.println("DEBUG: Invalid input class -> " + name); } clData.superClass = "java/lang/Object"; } - clDataHashMap.put(name,clData); + clDataHashMap.put(name, clData); } } } diff --git a/common/src/main/java/com/fox2code/foxloader/loader/transformer/ClientOnlyInventoryTransformer.java b/common/src/main/java/com/fox2code/foxloader/loader/transformer/ClientOnlyInventoryTransformer.java new file mode 100644 index 0000000..4c461e5 --- /dev/null +++ b/common/src/main/java/com/fox2code/foxloader/loader/transformer/ClientOnlyInventoryTransformer.java @@ -0,0 +1,142 @@ +package com.fox2code.foxloader.loader.transformer; + +import org.objectweb.asm.tree.*; + +public class ClientOnlyInventoryTransformer implements PreClassTransformer { + private static final String PLAYER_CONTROLLER_MP = "net.minecraft.src.client.player.PlayerControllerMP"; + private static final String CLIENT_NETWORK_HANDLER = "net.minecraft.src.client.packets.NetClientHandler"; + private static final String GUI_CONTAINER_CREATIVE = "net.minecraft.src.client.gui.GuiContainerCreative"; + private static final String GUI_CONTAINER = "net.minecraft.src.client.gui.GuiContainer"; + + private static final String ASM_INVENTORY_BASIC = + "net/minecraft/src/client/inventory/InventoryBasic"; + private static final String ASM_INVENTORY_BASIC_CLIENT_ONLY = + "com/fox2code/foxloader/client/gui/InventoryBasicClientOnly"; + + @Override + public void transform(ClassNode classNode, String className) { + switch (className) { + case PLAYER_CONTROLLER_MP: + patchPlayerControllerMP(classNode); + return; + case CLIENT_NETWORK_HANDLER: + patchNetClientHandler(classNode); + return; + case GUI_CONTAINER: + patchGuiContainer(classNode); + return; + case GUI_CONTAINER_CREATIVE: + patchGuiContainerCreative(classNode); + } + } + + private void patchPlayerControllerMP(ClassNode classNode) { + MethodNode sendClickSlot = TransformerUtils + .getMethod(classNode, "clickSlot"); + InsnList earlyInject = new InsnList(); + LabelNode labelNode = new LabelNode(); + earlyInject.insert(new VarInsnNode(ILOAD, 1)); + earlyInject.insert(new InsnNode(ICONST_M1)); + earlyInject.insert(new JumpInsnNode(IF_ICMPNE, labelNode)); + earlyInject.insert(new VarInsnNode(ALOAD, 0)); + earlyInject.insert(new VarInsnNode(ILOAD, 1)); + earlyInject.insert(new VarInsnNode(ILOAD, 2)); + earlyInject.insert(new VarInsnNode(ILOAD, 3)); + earlyInject.insert(new VarInsnNode(ILOAD, 4)); + earlyInject.insert(new VarInsnNode(ALOAD, 5)); + earlyInject.insert(new MethodInsnNode(INVOKESPECIAL, + "net/minecraft/src/client/player/PlayerController", "clickSlot", + "(IIIILnet/minecraft/src/game/entity/player/EntityPlayer;)Lnet/minecraft/src/game/item/ItemStack;")); + earlyInject.insert(new InsnNode(ARETURN)); + earlyInject.insert(labelNode); + sendClickSlot.instructions.insert(earlyInject); + } + + private void patchNetClientHandler(ClassNode classNode) { + for (MethodNode methodNode : classNode.methods) { + InsnList insnList = methodNode.instructions; + for (AbstractInsnNode abstractInsnNode : insnList) { + if (abstractInsnNode.getOpcode() == GETFIELD && + ((FieldInsnNode)abstractInsnNode).name.equals("currentContainer")) { + insnList.insertBefore(abstractInsnNode, new MethodInsnNode(INVOKESTATIC, classNode.name, "getNetworkContainer", + "(Lnet/minecraft/src/game/entity/player/EntityPlayer;)Lnet/minecraft/src/client/gui/Container;", false)); + insnList.remove(abstractInsnNode); + } + } + } + + + final MethodNode getNetworkContainer = new MethodNode(ACC_PUBLIC | ACC_STATIC, "getNetworkContainer", + "(Lnet/minecraft/src/game/entity/player/EntityPlayer;)Lnet/minecraft/src/client/gui/Container;", + null, null); + getNetworkContainer.instructions.add(new VarInsnNode(ALOAD, 0)); + getNetworkContainer.instructions.add(new FieldInsnNode(GETFIELD, + "net/minecraft/src/game/entity/player/EntityPlayer", + "currentContainer", "Lnet/minecraft/src/client/gui/Container;")); + getNetworkContainer.instructions.add(new MethodInsnNode(INVOKESTATIC, + "com/fox2code/foxloader/client/gui/ContainerWrapped", "getNetworkContainer", + "(Lnet/minecraft/src/client/gui/Container;)Lnet/minecraft/src/client/gui/Container;", false)); + getNetworkContainer.instructions.add(new VarInsnNode(ASTORE, 1)); + getNetworkContainer.instructions.add(new VarInsnNode(ALOAD, 1)); + LabelNode noFallback = new LabelNode(); + getNetworkContainer.instructions.add(new JumpInsnNode(IFNONNULL, noFallback)); + getNetworkContainer.instructions.add(new VarInsnNode(ALOAD, 0)); + getNetworkContainer.instructions.add(new FieldInsnNode(GETFIELD, + "net/minecraft/src/game/entity/player/EntityPlayer", + "playerContainer", "Lnet/minecraft/src/client/gui/Container;")); + getNetworkContainer.instructions.add(new VarInsnNode(ASTORE, 1)); + getNetworkContainer.instructions.add(noFallback); + getNetworkContainer.instructions.add(new VarInsnNode(ALOAD, 1)); + getNetworkContainer.instructions.add(new InsnNode(ARETURN)); + classNode.methods.add(getNetworkContainer); + } + + private void patchGuiContainer(ClassNode classNode) { + MethodNode sendClickSlot = TransformerUtils + .getMethod(classNode, "sendClickSlot"); + sendClickSlot.access = ACC_PUBLIC; + InsnList instructions = sendClickSlot.instructions; + FieldInsnNode windowId; + for (AbstractInsnNode abstractInsnNode : instructions) { + if (abstractInsnNode.getOpcode() == GETFIELD && + (windowId = (FieldInsnNode) abstractInsnNode) + .name.equals("windowId")) { + InsnList instructionsBuffer = new InsnList(); + LabelNode notClientOnly = new LabelNode(); + instructionsBuffer.add(new VarInsnNode(ALOAD, 1)); + instructionsBuffer.add(new JumpInsnNode(IFNULL, notClientOnly)); + instructionsBuffer.add(new VarInsnNode(ALOAD, 1)); + instructionsBuffer.add(new FieldInsnNode(GETFIELD, + "net/minecraft/src/client/gui/Slot", "inventory", + "Lnet/minecraft/src/client/inventory/IInventory;")); + instructionsBuffer.add(new TypeInsnNode(INSTANCEOF, + "com/fox2code/foxloader/client/gui/InventoryClientOnly")); + instructionsBuffer.add(new JumpInsnNode(IFEQ, notClientOnly)); + instructionsBuffer.add(new InsnNode(ICONST_M1)); + LabelNode clientOnly = new LabelNode(); + instructionsBuffer.add(new JumpInsnNode(GOTO, clientOnly)); + instructionsBuffer.add(notClientOnly); + instructions.insertBefore(windowId.getPrevious() + .getPrevious(), instructionsBuffer); + instructions.insert(windowId, clientOnly); + return; + } + } + } + + private void patchGuiContainerCreative(ClassNode classNode) { + TransformerUtils.getMethod(classNode, "sendClickSlot").access = ACC_PUBLIC; + MethodNode clinit = TransformerUtils.getMethod(classNode, ""); + for (AbstractInsnNode abstractInsnNode : clinit.instructions) { + if (abstractInsnNode.getOpcode() == NEW) { + TypeInsnNode typeInsnNode = (TypeInsnNode) abstractInsnNode; + if (ASM_INVENTORY_BASIC.equals(typeInsnNode.desc)) + typeInsnNode.desc = ASM_INVENTORY_BASIC_CLIENT_ONLY; + } else if (abstractInsnNode.getOpcode() == INVOKESPECIAL) { + MethodInsnNode methodInsnNode = (MethodInsnNode) abstractInsnNode; + if (ASM_INVENTORY_BASIC.equals(methodInsnNode.owner)) + methodInsnNode.owner = ASM_INVENTORY_BASIC_CLIENT_ONLY; + } + } + } +} diff --git a/common/src/main/java/com/fox2code/foxloader/loader/transformer/DevelopmentSourceTransformer.java b/common/src/main/java/com/fox2code/foxloader/loader/transformer/DevelopmentSourceTransformer.java index a309567..7d35e88 100644 --- a/common/src/main/java/com/fox2code/foxloader/loader/transformer/DevelopmentSourceTransformer.java +++ b/common/src/main/java/com/fox2code/foxloader/loader/transformer/DevelopmentSourceTransformer.java @@ -89,7 +89,7 @@ public void unpick(InsnList insnList, AbstractInsnNode constant, String value) { new Flag(GL11.GL_EVAL_BIT, "GL_EVAL_BIT"), new Flag(GL11.GL_LIST_BIT, "GL_LIST_BIT"), new Flag(GL11.GL_TEXTURE_BIT, "GL_TEXTURE_BIT"), - new Flag(GL11.GL_HINT_BIT, "GL_HINT_BIT")); + new Flag(GL11.GL_SCISSOR_BIT, "GL_SCISSOR_BIT")); ConstantUnpick glZeroOne = new IntStaticConstantUnpick("org/lwjgl/opengl/GL11") { @Override public String unpick(int value) { @@ -169,6 +169,7 @@ public String unpick(int value) { // LWJGL/Input Unpicks ConstantUnpick key = GeneratedConstantUnpicks.keyboardConstantUnpick; staticConstantUnpicks.put("org/lwjgl/input/Keyboard.isKeyDown(I)Z", key); + staticConstantUnpicks.put("org/lwjgl/input/Keyboard.getKeyName(I)Ljava/lang/String;", key); returnStaticConstantUnpicks.put("org/lwjgl/input/Keyboard.getEventKey()I", key); // Minecraft specific LWJGL/Input Unpicks virtualConstantUnpicks.put("net/minecraft/src/client/KeyBinding.(Ljava/lang/String;I)V", key); diff --git a/common/src/main/java/com/fox2code/foxloader/registry/GameRegistry.java b/common/src/main/java/com/fox2code/foxloader/registry/GameRegistry.java index ebb11a3..5d380fe 100644 --- a/common/src/main/java/com/fox2code/foxloader/registry/GameRegistry.java +++ b/common/src/main/java/com/fox2code/foxloader/registry/GameRegistry.java @@ -1,5 +1,6 @@ package com.fox2code.foxloader.registry; +import com.fox2code.foxloader.loader.ModContainer; import com.fox2code.foxloader.loader.ModLoader; import com.fox2code.foxloader.loader.lua.LuaInterop; @@ -165,12 +166,23 @@ public static int convertItemIdToBlockId(int itemId) { itemId > 255 ? itemId < 1000 ? -1 : itemId - 744 : itemId; } + public static String validateAndFixRegistryName(String name) { + if (name.indexOf(':') == -1 && !ModLoader.areAllModsLoaded()) { + ModContainer modContainer = ModContainer.getActiveModContainer(); + if (modContainer != null) { + name = modContainer.id + ":" + name; + } + } + validateRegistryName(name); + return name; + } + public static void validateRegistryName(String name) { if (name.indexOf(':') == -1) { throw new IllegalArgumentException("Please add your mod id in the registry name, ex \"modid:item\")"); } - if (name.indexOf('\0') != -1) { - throw new IllegalArgumentException("Null bytes are not supported in registry identifiers"); + if (name.indexOf('\0') != -1 || name.indexOf(' ') != -1) { + throw new IllegalArgumentException("Null bytes and spaces are not supported in registry identifiers"); } } diff --git a/final/src/main/java/com/fox2code/foxloader/installer/Main.java b/final/src/main/java/com/fox2code/foxloader/installer/Main.java index c10129b..230748c 100644 --- a/final/src/main/java/com/fox2code/foxloader/installer/Main.java +++ b/final/src/main/java/com/fox2code/foxloader/installer/Main.java @@ -16,8 +16,8 @@ public class Main { // We need -XX:+IgnoreUnrecognizedVMOptions cause some of the optimization arg we us are not available on some JVMs static final String optJvmArgs = "-XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions " + "-XX:+UseFastAccessorMethods -XX:+AggressiveOpts -XX:+UseCompressedOops -XX:+UseBiasedLocking " + - "-XX:+OptimizeStringConcat -XX:MaxGCPauseMillis=25 -XX:-UseGCOverheadLimit -XX:+UseLargePages " + - "-XX:+UseStringCache -XX:+UseCompressedStrings -Dfile.encoding=UTF-8"; + "-XX:+OptimizeStringConcat -XX:-UseGCOverheadLimit -XX:+UseLargePages -XX:+UseStringCache " + + "-XX:+UseCompressedStrings -XX:+UseNUMA -XX:+UseCodeCacheFlushing -d64 -Dfile.encoding=UTF-8"; static final String optJvmArgsWithMem = optJvmArgs + " -Xmn512M -Xms512M -Xmx2G"; static final File currentInstallerFile = SourceUtil.getSourceFile(Main.class); public static void main(String[] args) throws ReflectiveOperationException, MalformedURLException { diff --git a/gradle.properties b/gradle.properties index bb83a97..e1f6d11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,8 +3,8 @@ org.gradle.parallel=true org.gradle.jvmargs=-Xmx1024m -XX:-UseGCOverheadLimit -Dfile.encoding=UTF-8 # FoxLoader properties -foxloader.version=1.2.11 -foxloader.lastReIndevTransformerChanges=1.2.4 +foxloader.version=1.2.12 +foxloader.lastReIndevTransformerChanges=1.2.12 # ReIndev properties reindev.clientUrl=https://cdn.fox2code.com/files/reindev_2.8.1_04.jar diff --git a/server/src/main/java/com/fox2code/foxloader/registry/GameRegistryServer.java b/server/src/main/java/com/fox2code/foxloader/registry/GameRegistryServer.java index 8f2557b..6726170 100644 --- a/server/src/main/java/com/fox2code/foxloader/registry/GameRegistryServer.java +++ b/server/src/main/java/com/fox2code/foxloader/registry/GameRegistryServer.java @@ -125,7 +125,7 @@ public int generateNewItemId(String name, int fallbackId) { @Override public RegisteredBlock registerNewBlock(String name, BlockBuilder blockBuilder, int fallbackId) { - validateRegistryName(name); + name = validateAndFixRegistryName(name); if (blockBuilder == null) blockBuilder = DEFAULT_BLOCK_BUILDER; String secondaryExt = blockBuilder.builtInBlockType.secRegistryExt; Block mainBlock = this.registerNewBlock0(name, blockBuilder, fallbackId, true); @@ -228,7 +228,7 @@ public Block registerNewBlock0(String name, BlockBuilder blockBuilder, int fallb @Override public RegisteredItem registerNewItem(String name, ItemBuilder itemBuilder, int fallbackId) { - validateRegistryName(name); + name = validateAndFixRegistryName(name); return this.registerNewItem0(name, itemBuilder, null, null, this.generateNewItemId(name, fallbackId), true); } diff --git a/server/src/main/java/com/fox2code/foxloader/server/mixins/MixinNetLoginHandler.java b/server/src/main/java/com/fox2code/foxloader/server/mixins/MixinNetLoginHandler.java index 6f4d60d..8801e37 100644 --- a/server/src/main/java/com/fox2code/foxloader/server/mixins/MixinNetLoginHandler.java +++ b/server/src/main/java/com/fox2code/foxloader/server/mixins/MixinNetLoginHandler.java @@ -4,63 +4,23 @@ import com.fox2code.foxloader.loader.ServerModLoader; import com.fox2code.foxloader.network.NetworkPlayer; import com.fox2code.foxloader.registry.GameRegistryServer; -import com.fox2code.foxloader.server.network.LoginState; import com.fox2code.foxloader.server.network.NetworkPlayerImpl; -import net.minecraft.server.MinecraftServer; import net.minecraft.src.game.entity.player.EntityPlayerMP; import net.minecraft.src.server.packets.NetLoginHandler; -import net.minecraft.src.server.packets.Packet1Login; -import net.minecraft.src.server.packets.Packet254ServerPing; import net.minecraft.src.server.packets.Packet2Handshake; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.net.Socket; - @Mixin(value = NetLoginHandler.class, priority = 0) public abstract class MixinNetLoginHandler { - @Shadow private Packet1Login packet1login; - - /** - * Used to improve legacy login security, and mitigate DoS attacks. - */ - @Unique private LoginState state; @Unique private boolean isModded; - @Shadow public abstract void kickUser(String var1); - @Shadow public abstract void doLogin(Packet1Login var1); - - @Inject(at = @At("RETURN"), method = "") - public void onInit(MinecraftServer var1, Socket var2, String var3, CallbackInfo ci) { - this.state = LoginState.PRE_HANDSHAKE; - } - - @Inject(at = @At("RETURN"), method = "tryLogin") - public void onTryLogin(CallbackInfo ci) { - if (this.packet1login != null) { - this.doLogin(this.packet1login); - this.packet1login = null; - } - } - - @Inject(at = @At("HEAD"), method = "kickUser") - public void onKick(String var1, CallbackInfo ci) { - this.state = LoginState.KICKED; - } - - @Inject(at = @At("HEAD"), method = "handleHandshake", cancellable = true) + @Inject(at = @At("HEAD"), method = "handleHandshake") public void onHandshake(Packet2Handshake var1, CallbackInfo ci) { - if (this.state != LoginState.PRE_HANDSHAKE) { - this.kickUser("Invalid login packet order!"); - ci.cancel(); - return; - } - this.state = LoginState.HANDSHAKE; if (var1.username.endsWith(ModLoader.FOX_LOADER_HEADER)) { var1.username = var1.username.substring( 0, var1.username.length() - @@ -69,16 +29,6 @@ public void onHandshake(Packet2Handshake var1, CallbackInfo ci) { } } - @Inject(at = @At("HEAD"), method = "handleLogin", cancellable = true) - public void onLogin(Packet1Login var1, CallbackInfo ci) { - if (this.state != LoginState.HANDSHAKE) { - kickUser("Invalid login packet order!"); - ci.cancel(); - return; - } - this.state = LoginState.LOGIN_IN; - } - @Redirect(method = "doLogin", at = @At(value = "INVOKE", target = "Lnet/minecraft/src/game/entity/player/EntityPlayerMP;func_20057_k()V")) public void func_20057_kRedirect(EntityPlayerMP instance) { @@ -88,16 +38,6 @@ public void func_20057_kRedirect(EntityPlayerMP instance) { } ServerModLoader.notifyNetworkPlayerJoined((NetworkPlayer) instance); - instance.func_20057_k(); } - - @Inject(at = @At("HEAD"), method = "handleServerPing", cancellable = true) - public void onServerPing(Packet254ServerPing packet254serverping, CallbackInfo ci) { - if (this.state != LoginState.KICKED) { - this.state = LoginState.KICKED; - } else { - ci.cancel(); - } - } } diff --git a/server/src/main/java/com/fox2code/foxloader/server/network/LoginState.java b/server/src/main/java/com/fox2code/foxloader/server/network/LoginState.java deleted file mode 100644 index 13f34c8..0000000 --- a/server/src/main/java/com/fox2code/foxloader/server/network/LoginState.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.fox2code.foxloader.server.network; - -public enum LoginState { - PRE_HANDSHAKE, HANDSHAKE, LOGIN_IN, KICKED -} diff --git a/server/src/main/java/com/fox2code/foxloader/spark/FoxLoaderServerSparkPlugin.java b/server/src/main/java/com/fox2code/foxloader/spark/FoxLoaderServerSparkPlugin.java index 9a7a502..5a51d2b 100644 --- a/server/src/main/java/com/fox2code/foxloader/spark/FoxLoaderServerSparkPlugin.java +++ b/server/src/main/java/com/fox2code/foxloader/spark/FoxLoaderServerSparkPlugin.java @@ -8,7 +8,7 @@ import java.util.stream.Stream; -public class FoxLoaderServerSparkPlugin extends FoxLoaderSparkPlugin { +public class FoxLoaderServerSparkPlugin extends FoxLoaderSparkPlugin implements ServerMod { public FoxLoaderServerSparkPlugin() { super(PlatformInfo.Type.SERVER); }