diff --git a/build.gradle.kts b/build.gradle.kts index b6ecb48..24989b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,24 +28,11 @@ toolkitLoomHelper { // Adds the tweak class if we are building legacy version of forge as per the documentation (https://docs.polyfrost.org) if (mcData.isLegacyForge) { - useTweaker("org.polyfrost.crashpatch.hooks.ModsCheckerPlugin", GameSide.CLIENT) + useTweaker("org.polyfrost.oneconfig.internal.legacy.OneConfigTweaker", GameSide.CLIENT) useForgeMixin(modData.id) // Configures the mixins if we are building for forge, useful for when we are dealing with cross-platform projects. } } -loom { - if (mcData.isLegacyForge) { - runConfigs { - "client" { - programArgs("--tweakClass", "org.polyfrost.oneconfig.internal.legacy.OneConfigTweaker") - programArgs("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker") - property("mixin.debug.export", "true") - //property("fml.coreMods.load", "") - } - } - } -} - // Configures the output directory for when building from the `src/resources` directory. sourceSets { main { diff --git a/settings.gradle.kts b/settings.gradle.kts index 67ecde2..70cb3f4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,7 +22,7 @@ pluginManagement { plugins { kotlin("jvm") version("2.0.0") - id("dev.deftu.gradle.multiversion-root") version("2.11.1") + id("dev.deftu.gradle.multiversion-root") version("2.11.2") } } diff --git a/src/main/java/org/polyfrost/crashpatch/hooks/ModsCheckerPlugin.java b/src/main/java/org/polyfrost/crashpatch/hooks/ModsCheckerPlugin.java deleted file mode 100644 index 0e6d6f5..0000000 --- a/src/main/java/org/polyfrost/crashpatch/hooks/ModsCheckerPlugin.java +++ /dev/null @@ -1,369 +0,0 @@ -package org.polyfrost.crashpatch.hooks; - -import com.google.common.collect.Lists; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.stream.MalformedJsonException; -import net.minecraft.launchwrapper.ITweaker; -import net.minecraft.launchwrapper.Launch; -import net.minecraft.launchwrapper.LaunchClassLoader; -import net.minecraftforge.fml.common.versioning.DefaultArtifactVersion; -import net.minecraftforge.fml.relauncher.CoreModManager; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.spongepowered.asm.launch.MixinBootstrap; -import org.spongepowered.asm.launch.MixinTweaker; - -import javax.swing.*; -import java.awt.*; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.security.CodeSource; -import java.util.List; -import java.util.*; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -public class ModsCheckerPlugin implements ITweaker { //todo - private static final JsonParser PARSER = new JsonParser(); - public static final HashMap> modsMap = new HashMap<>(); //modid : file, version, name - - @Override - public void acceptOptions(List args, File gameDir, File assetsDir, String profile) { - - } - - @Override - public void injectIntoClassLoader(LaunchClassLoader classLoader) { - try { - File modsFolder = new File(getMcDir(), "mods"); - File[] modFolder = modsFolder.listFiles((dir, name) -> name.endsWith(".jar")); - HashMap>> dupeMap = new HashMap<>(); - if (modFolder != null) { - for (File file : modFolder) { - try { - try (ZipFile mod = new ZipFile(file)) { - ZipEntry entry = mod.getEntry("mcmod.info"); - if (entry != null) { - try (InputStream inputStream = mod.getInputStream(entry)) { - byte[] availableBytes = new byte[inputStream.available()]; - inputStream.read(availableBytes, 0, inputStream.available()); - JsonObject modInfo = PARSER.parse(new String(availableBytes)).getAsJsonArray().get(0).getAsJsonObject(); - if (!modInfo.has("modid") || !modInfo.has("version")) { - continue; - } - - String modid = modInfo.get("modid").getAsString(); - if (modsMap.containsKey(modid)) { - if (dupeMap.containsKey(modid)) { - dupeMap.get(modid).add(new Triple<>(file, modInfo.get("version").getAsString(), modInfo.has("name") ? modInfo.get("name").getAsString() : modid)); - } else { - dupeMap.put(modid, Lists.newArrayList(modsMap.get(modid), new Triple<>(file, modInfo.get("version").getAsString(), modInfo.has("name") ? modInfo.get("name").getAsString() : modid))); - } - } else { - modsMap.put(modid, new Triple<>(file, modInfo.get("version").getAsString(), modInfo.has("name") ? modInfo.get("name").getAsString() : modid)); - } - } - } - } - } catch (MalformedJsonException | IllegalStateException ignored) { - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - Iterator>> iterator = dupeMap.values().iterator(); - - boolean isSkyClient = new File(getMcDir(), "W-OVERFLOW/CrashPatch/SKYCLIENT").exists() || containsAnyKey(ModsCheckerPlugin.modsMap, "skyclientcosmetics", "scc", "skyclientaddons", "skyblockclientupdater", "skyclientupdater", "skyclientcore"); - while (iterator.hasNext()) { - try { - ArrayList> next = iterator.next(); - List> blank = next.stream().sorted((a, b) -> { - if (a != null && b != null) { - try { - int value = new DefaultArtifactVersion(substringBeforeAny(a.second, "-beta", "-alpha", "-pre", "+beta", "+alpha", "+pre")).compareTo(new DefaultArtifactVersion(substringBeforeAny(b.second, "-beta", "-alpha", "-pre", "+beta", "+alpha", "+pre"))); - return -value; - } catch (Exception e) { - e.printStackTrace(); - return Long.compare(a.first.lastModified(), b.first.lastModified()) * -1; - } - } - return 0; - }).collect(Collectors.toList()); - next.clear(); - next.addAll(blank); - ListIterator> otherIterator = next.listIterator(); - int index = 0; - while (otherIterator.hasNext()) { - Triple remove = otherIterator.next(); - ++index; - if (index != 1) { - if (tryDeleting(remove.first)) { - otherIterator.remove(); - } else { - doThatPopupThing(modsFolder, "Duplicate mods have been detected! These mods are...\n" + - getStringOf(dupeMap.values()) + "\nPlease removes these mods from your mod folder, which is opened." + (isSkyClient ? " GO TO https://inv.wtf/skyclient FOR MORE INFORMATION." : "")); - } - } - } - if (next.size() <= 1) { - iterator.remove(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - - if (!dupeMap.isEmpty()) { - doThatPopupThing(modsFolder, "Duplicate mods have been detected! These mods are...\n" + - getStringOf(dupeMap.values()) + "\nPlease removes these mods from your mod folder, which is opened." + (isSkyClient ? " GO TO https://inv.wtf/skyclient FOR MORE INFORMATION." : "")); - } - } catch (Exception e) { - e.printStackTrace(); - } - - //todo terrible - - //CodeSource codeSource = this.getClass().getProtectionDomain().getCodeSource(); - //if (codeSource != null) { - // URL location = codeSource.getLocation(); - // try { - // File file = new File(location.toURI()); - // if (file.isFile()) { - // CoreModManager.getIgnoredMods().remove(file.getName()); - // CoreModManager.getReparseableCoremods().add(file.getName()); - // try { - // try { - // List tweakClasses = (List) Launch.blackboard.get("TweakClasses"); // tweak classes before other mod trolling - // if (tweakClasses.contains("org.spongepowered.asm.launch.MixinTweaker")) { // if there's already a mixin tweaker, we'll just load it like "usual" - // new MixinTweaker(); // also we might not need to make a new mixin tweawker all the time but im just making sure - // } else if (!Launch.blackboard.containsKey("mixin.initialised")) { // if there isnt, we do our own trolling - // List tweaks = (List) Launch.blackboard.get("Tweaks"); - // tweaks.add(new MixinTweaker()); - // } - // } catch (Exception ignored) { - // // if it fails i *think* we can just ignore it - // } - // try { - // MixinBootstrap.getPlatform().addContainer(location.toURI()); - // } catch (Exception ignore) { - // // fuck you essential - // try { - // Class containerClass = Class.forName("org.spongepowered.asm.launch.platform.container.IContainerHandle"); - // Class urlContainerClass = Class.forName("org.spongepowered.asm.launch.platform.container.ContainerHandleURI"); - // Object container = urlContainerClass.getConstructor(URI.class).newInstance(location.toURI()); - // MixinBootstrap.getPlatform().getClass().getDeclaredMethod("addContainer", containerClass).invoke(MixinBootstrap.getPlatform(), container); - // } catch (Exception e) { - // e.printStackTrace(); - // throw new RuntimeException("OneConfig's Mixin loading failed. Please contact https://polyfrost.cc/discord to resolve this issue!"); - // } - // } - // } catch (Exception ignored) { -// - // } - // } - // } catch (URISyntaxException ignored) {} - //} else { - // LogManager.getLogger().warn("No CodeSource, if this is not a development environment we might run into problems!"); - // LogManager.getLogger().warn(this.getClass().getProtectionDomain()); - //} -// - //super.injectIntoClassLoader(classLoader); - } - - @Override - public String getLaunchTarget() { - return null; - } - - @Override - public String[] getLaunchArguments() { - return new String[0]; - } - - private static void doThatPopupThing(File modsFolder, String message) { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - e.printStackTrace(); - } - - JFrame frame = new JFrame(); - frame.setUndecorated(true); - frame.setAlwaysOnTop(true); - frame.setLocationRelativeTo(null); - frame.setVisible(true); - - DesktopManager.open(modsFolder); - JOptionPane.showMessageDialog(frame, message, "Duplicate Mods Detected!", JOptionPane.ERROR_MESSAGE); - try { - Class exitClass = Class.forName("java.lang.Shutdown"); - Method exit = exitClass.getDeclaredMethod("exit", int.class); - exit.setAccessible(true); - exit.invoke(null, 0); - } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | - InvocationTargetException e) { - e.printStackTrace(); - } - } - - @SafeVarargs - private final boolean containsAnyKey(HashMap hashMap, A... any) { - for (A thing : any) { - if (hashMap.containsKey(thing)) return true; - } - return false; - } - - private String getStringOf(Collection>> dupes) { - StringBuilder builder = new StringBuilder(); - int index = 0; - for (ArrayList> list : dupes) { - ++index; - builder.append("\n"); - for (Triple triple : list) { - builder.append(" ").append(triple.first.getAbsolutePath()); - } - if (index != dupes.size()) builder.append("\nAND"); - } - return builder.toString().trim(); - } - - private String substringBeforeAny(String string, String... values) { - String returnString = string; - for (String value : values) { - if (returnString.contains(value)) { - returnString = StringUtils.substringBefore(returnString, value); - } - } - return returnString; - } - - private boolean tryDeleting(File file) { - if (!file.delete()) { - if (!file.delete()) { - if (!file.delete()) { - file.deleteOnExit(); - return false; - } - } - } - return true; - } - - public static class Triple { - public A first; - public B second; - public C third; - - public Triple(A a, B b, C c) { - first = a; - second = b; - third = c; - } - - @Override - public String toString() { - return "Triple{" + - "first=" + first + - ", second=" + second + - ", third=" + third + - '}'; - } - } - - /** - * Taken from UniversalCraft under LGPLv3 - * https://github.com/EssentialGG/UniversalCraft/blob/master/LICENSE - */ - private static class DesktopManager { - private static final boolean isLinux; - private static final boolean isXdg; - private static boolean isKde; - private static boolean isGnome; - private static final boolean isMac; - private static final boolean isWindows; - - static { - String osName; - try { - osName = System.getProperty("os.name"); - } catch (SecurityException ignored) { - osName = null; - } - isLinux = osName != null && (osName.startsWith("Linux") || osName.startsWith("LINUX")); - isMac = osName != null && osName.startsWith("Mac"); - isWindows = osName != null && osName.startsWith("Windows"); - if (isLinux) { - String xdg = System.getenv("XDG_SESSION_ID"); - isXdg = xdg != null && !xdg.isEmpty(); - String gdm = System.getenv("GDMSESSION"); - if (gdm != null) { - String lowercaseGDM = gdm.toLowerCase(Locale.ENGLISH); - isGnome = lowercaseGDM.contains("gnome"); - isKde = lowercaseGDM.contains("kde"); - } - } else { - isXdg = false; - isKde = false; - isGnome = false; - } - } - - - public static void open(File file) { - if (!openDesktop(file)) { - openSystemSpecific(file.getPath()); - } - } - - private static boolean openSystemSpecific(String file) { - return isLinux ? (isXdg ? runCommand("xdg-open \"" + file + '"') : (isKde ? runCommand("kde-open \"" + file + '"') : (isGnome ? runCommand("gnome-open \"" + file + '"') : runCommand("kde-open \"" + file + '"') || runCommand("gnome-open \"" + file + '"')))) : (isMac ? runCommand("open \"" + file + '"') : (isWindows && runCommand("explorer \"" + file + '"'))); - } - - private static boolean openDesktop(File file) { - boolean worked; - if (!Desktop.isDesktopSupported()) { - worked = false; - } else { - boolean worked2; - try { - if (!Desktop.getDesktop().isSupported(Desktop.Action.OPEN)) { - return false; - } - - Desktop.getDesktop().open(file); - worked2 = true; - } catch (Throwable var4) { - worked2 = false; - } - - worked = worked2; - } - - return worked; - } - - private static boolean runCommand(String command) { - try { - Process process = Runtime.getRuntime().exec(command); - return process != null && process.isAlive(); - } catch (IOException var5) { - return false; - } - } - } - - private static File getMcDir() { - return new File(System.getProperty("user.dir")); - } -} diff --git a/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java b/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java index 7cfd1aa..3c6f8af 100644 --- a/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java +++ b/src/main/java/org/polyfrost/crashpatch/mixin/MixinMinecraft.java @@ -32,6 +32,7 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL12; import org.lwjgl.opengl.GL14; +import org.polyfrost.crashpatch.CrashPatch; import org.polyfrost.crashpatch.config.CrashPatchConfig; import org.polyfrost.crashpatch.crashes.StateManager; import org.polyfrost.crashpatch.gui.CrashGuiRewrite; @@ -162,6 +163,10 @@ public void run(CallbackInfo ci) { while (running) { if (!hasCrashed || crashReporter == null) { try { + if (CrashPatch.INSTANCE.getTest()) { + throw new RuntimeException("Test crash"); + } + runGameLoop(); } catch (ReportedException e) { crashpatch$clientCrashCount++; diff --git a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt index f4b9eec..efe545d 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/CrashPatch.kt @@ -8,13 +8,13 @@ import org.polyfrost.oneconfig.api.commands.v1.factories.annotated.Command import org.polyfrost.crashpatch.config.CrashPatchConfig import org.polyfrost.crashpatch.crashes.CrashHelper import org.polyfrost.crashpatch.crashes.DeobfuscatingRewritePolicy -import org.polyfrost.crashpatch.hooks.ModsCheckerPlugin import net.minecraft.util.ChatComponentText import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.event.FMLInitializationEvent import net.minecraftforge.fml.common.event.FMLPreInitializationEvent import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger +import org.polyfrost.utils.v1.dsl.openUI import java.io.File @@ -24,7 +24,9 @@ object CrashPatch { const val NAME = "@MOD_NAME@" const val VERSION = "@MOD_VERSION@" val isSkyclient by lazy(LazyThreadSafetyMode.PUBLICATION) { File(mcDir, "OneConfig/CrashPatch/SKYCLIENT").exists() || File( - mcDir, "W-OVERFLOW/CrashPatch/SKYCLIENT").exists() || ModsCheckerPlugin.modsMap.keys.any { it == "skyclientcosmetics" || it == "scc" || it == "skyclientaddons" || it == "skyblockclientupdater" || it == "skyclientupdater" || it == "skyclientcore" } } + mcDir, "W-OVERFLOW/CrashPatch/SKYCLIENT").exists() } + + var test = false @Mod.EventHandler fun onPreInit(e: FMLPreInitializationEvent) { @@ -42,14 +44,14 @@ object CrashPatch { CommandManager.registerCommand(CrashPatchCommand()) CrashPatchConfig // uncomment to test init screen crashes - throw Throwable("java.lang.NoClassDefFoundError: xyz/matthewtgm/requisite/keybinds/KeyBind at lumien.custommainmenu.configuration.ConfigurationLoader.load(ConfigurationLoader.java:142) club.sk1er.bossbarcustomizer.BossbarMod.loadConfig cc.woverflow.hytils.handlers.chat.modules.modifiers.DefaultChatRestyler Failed to login: null The Hypixel Alpha server is currently closed! net.kdt.pojavlaunch macromodmodules") +// throw Throwable("java.lang.NoClassDefFoundError: xyz/matthewtgm/requisite/keybinds/KeyBind at lumien.custommainmenu.configuration.ConfigurationLoader.load(ConfigurationLoader.java:142) club.sk1er.bossbarcustomizer.BossbarMod.loadConfig cc.woverflow.hytils.handlers.chat.modules.modifiers.DefaultChatRestyler Failed to login: null The Hypixel Alpha server is currently closed! net.kdt.pojavlaunch macromodmodules") } @Command("crashpatch") class CrashPatchCommand { @Command fun main() { - //CrashPatchConfig.openGui() + CrashPatchConfig.openUI() } @Command @@ -61,6 +63,11 @@ object CrashPatch { UMinecraft.getMinecraft().thePlayer.addChatMessage(ChatComponentText("${ChatColor.RED}[CrashPatch] Failed to reload the JSON file!")) } } + + @Command + fun crash() { + test = true + } } } val logger: Logger = LogManager.getLogger(CrashPatch) diff --git a/src/main/kotlin/org/polyfrost/crashpatch/config/CrashPatchConfig.kt b/src/main/kotlin/org/polyfrost/crashpatch/config/CrashPatchConfig.kt index 13b3428..6df26d1 100644 --- a/src/main/kotlin/org/polyfrost/crashpatch/config/CrashPatchConfig.kt +++ b/src/main/kotlin/org/polyfrost/crashpatch/config/CrashPatchConfig.kt @@ -76,11 +76,11 @@ object CrashPatchConfig : Config("crashpatch.json", "/assets/crashpatch/crashpat title = "Polyfrost support", text = "Discord" ) - var supportDiscord = Runnable { browse(URI.create("https://polyfrost.cc/discord/")) } + fun supportDiscord() { browse(URI.create("https://polyfrost.cc/discord/")) } @Button( title = "Crash game", text = "Crash" ) - var crashGame = Runnable { throw Throwable("java.lang.NoClassDefFoundError: xyz/matthewtgm/requisite/keybinds/KeyBind at lumien.custommainmenu.configuration.ConfigurationLoader.load(ConfigurationLoader.java:142) club.sk1er.bossbarcustomizer.BossbarMod.loadConfig cc.woverflow.hytils.handlers.chat.modules.modifiers.DefaultChatRestyler Failed to login: null The Hypixel Alpha server is currently closed! net.kdt.pojavlaunch macromodmodules") } + fun crashGame() { throw Throwable("java.lang.NoClassDefFoundError: xyz/matthewtgm/requisite/keybinds/KeyBind at lumien.custommainmenu.configuration.ConfigurationLoader.load(ConfigurationLoader.java:142) club.sk1er.bossbarcustomizer.BossbarMod.loadConfig cc.woverflow.hytils.handlers.chat.modules.modifiers.DefaultChatRestyler Failed to login: null The Hypixel Alpha server is currently closed! net.kdt.pojavlaunch macromodmodules") } } \ No newline at end of file diff --git a/src/main/resources/mixin.crashpatch.json b/src/main/resources/mixins.crashpatch.json similarity index 100% rename from src/main/resources/mixin.crashpatch.json rename to src/main/resources/mixins.crashpatch.json diff --git a/src/main/resources/polyfrost/stage0.properties b/src/main/resources/polyfrost/stage0.properties new file mode 100644 index 0000000..ba1d57b --- /dev/null +++ b/src/main/resources/polyfrost/stage0.properties @@ -0,0 +1,3 @@ +oneconfig-stage1-class=org.polyfrost.oneconfig.loader.stage1.Stage1Loader +oneconfig-stage1-version=1.1.0-alpha.31 +oneconfig-maven-uri=https://repo.polyfrost.org/mirror/