Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean coremod and stop using COMPUTE_FRAMES which triggers unwanted class loading #21

Merged
merged 5 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 53 additions & 20 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//version: 1692122114
//version: 1696952014
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
Expand Down Expand Up @@ -89,6 +89,23 @@ def out = services.get(StyledTextOutputFactory).create('an-output')
def projectJavaVersion = JavaLanguageVersion.of(8)

boolean disableSpotless = project.hasProperty("disableSpotless") ? project.disableSpotless.toBoolean() : false
boolean disableCheckstyle = project.hasProperty("disableCheckstyle") ? project.disableCheckstyle.toBoolean() : false

final String CHECKSTYLE_CONFIG = """
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="TreeWalker">
<!-- Use CHECKSTYLE:OFF and CHECKSTYLE:ON comments to suppress checkstyle lints in a block -->
<module name="SuppressionCommentFilter"/>
<module name="AvoidStarImport">
<!-- Allow static wildcard imports for cases like Opcodes and LWJGL classes, these don't get created accidentally by the IDE -->
<property name="allowStaticMemberImports" value="true"/>
</module>
</module>
</module>
"""

checkPropertyExists("modName")
checkPropertyExists("modId")
Expand Down Expand Up @@ -140,6 +157,17 @@ if (!disableSpotless) {
apply from: Blowdryer.file('spotless.gradle')
}

if (!disableCheckstyle) {
apply plugin: 'checkstyle'
tasks.named("checkstylePatchedMc") { enabled = false }
tasks.named("checkstyleMcLauncher") { enabled = false }
tasks.named("checkstyleIdeVirtualMain") { enabled = false }
tasks.named("checkstyleInjectedTags") { enabled = false }
checkstyle {
config = resources.text.fromString(CHECKSTYLE_CONFIG)
}
}

String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
Expand Down Expand Up @@ -600,15 +628,10 @@ repositories {
}
maven {
name = "ic2"
url = "https://maven.ic2.player.to/"
metadataSources {
mavenPom()
artifact()
url = getURL("https://maven.ic2.player.to/", "https://maven2.ic2.player.to/")
content {
includeGroup "net.industrial-craft"
}
}
maven {
name = "ic2-mirror"
url = "https://maven2.ic2.player.to/"
metadataSources {
mavenPom()
artifact()
Expand Down Expand Up @@ -770,23 +793,14 @@ ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies"
}

dependencies {
def lwjgl3ifyVersion = '1.4.0'
def asmVersion = '9.4'
def lwjgl3ifyVersion = '1.5.1'
if (modId != 'lwjgl3ify') {
java17Dependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}")
}
if (modId != 'hodgepodge') {
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.2.26')
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.3.7')
}

java17PatchDependencies('net.minecraft:launchwrapper:1.17.2') {transitive = false}
java17PatchDependencies("org.ow2.asm:asm:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-commons:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-tree:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-analysis:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-util:${asmVersion}")
java17PatchDependencies('org.ow2.asm:asm-deprecated:7.1')
java17PatchDependencies("org.apache.commons:commons-lang3:3.12.0")
java17PatchDependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}:forgePatches") {transitive = false}
}

Expand Down Expand Up @@ -1576,6 +1590,25 @@ def getSecondaryArtifacts() {
return secondaryArtifacts
}

def getURL(String main, String fallback) {
return pingURL(main, 10000) ? main : fallback
}

// credit: https://stackoverflow.com/a/3584332
def pingURL(String url, int timeout) {
url = url.replaceFirst("^https", "http") // Otherwise an exception may be thrown on invalid SSL certificates.
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection()
connection.setConnectTimeout(timeout)
connection.setReadTimeout(timeout)
connection.setRequestMethod("HEAD")
int responseCode = connection.getResponseCode()
return 200 <= responseCode && responseCode <= 399
} catch (IOException ignored) {
return false
}
}

// For easier scripting of things that require variables defined earlier in the buildscript
if (file('addon.late.gradle.kts').exists()) {
apply from: 'addon.late.gradle.kts'
Expand Down
8 changes: 6 additions & 2 deletions src/main/java/alexiil/mods/load/LoadingFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public static void setSystemLAF() {
}
}

/** Launch the application. */
/**
* Launch the application.
*/
public static LoadingFrame openWindow() {
try {
LoadingFrame frame = new LoadingFrame();
Expand All @@ -94,7 +96,9 @@ public static Rectangle getWindowBounds(LoadingFrame frame) {
bounds.height);
}

/** Create the frame. */
/**
* Create the frame.
*/
public LoadingFrame() {
setTitle("Minecraft Loading");
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Expand Down
32 changes: 18 additions & 14 deletions src/main/java/alexiil/mods/load/MinecraftDisplayer.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package alexiil.mods.load;

import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_GREATER;
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;

import java.awt.*;
import java.io.*;
import static org.lwjgl.opengl.GL11.*;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -345,8 +349,8 @@ public static String[] readTipsFile(String file) throws IOException {
List<String> lines = new ArrayList<>();
try {
reader = new BufferedReader((new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))); // new
// BufferedReader(new
// FileReader(file));
// BufferedReader(new
// FileReader(file));
StringBuffer inputBuffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
Expand Down Expand Up @@ -671,11 +675,11 @@ public void open(Configuration cfg) {

try {
lbRGB[0] = (float) (Color.decode("#" + loadingBarsColor).getRed() & 255) / 255.0f; // Color.decode("#" +
// loadingBarsColor).getRed();
// loadingBarsColor).getRed();
lbRGB[1] = (float) (Color.decode("#" + loadingBarsColor).getGreen() & 255) / 255.0f; // Color.decode("#" +
// loadingBarsColor).getGreen();
// loadingBarsColor).getGreen();
lbRGB[2] = (float) (Color.decode("#" + loadingBarsColor).getBlue() & 255) / 255.0f; // Color.decode("#" +
// loadingBarsColor).getBlue();
// loadingBarsColor).getBlue();
// BetterLoadingScreen.log.debug("The color: " + String.valueOf(lbRGB[0]) + ";" + String.valueOf(lbRGB[1]) +
// ";" + String.valueOf(lbRGB[2]));
} catch (Exception e) {
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/alexiil/mods/load/ModLoadingListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
import com.google.common.eventbus.Subscribe;

import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.event.*;
import cpw.mods.fml.common.event.FMLConstructionEvent;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.relauncher.FMLLaunchHandler;

public class ModLoadingListener {
Expand All @@ -26,7 +30,9 @@ public enum State {

private String translatedName = null;
final String name;
/** If this state is only called once. This is false for all except for FINAL_LOADING */
/**
* If this state is only called once. This is false for all except for FINAL_LOADING
*/
final boolean isLoneState;
/**
* If this is true, then ModStage.getNext will skip this, but it will still be included in the percentage
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/alexiil/mods/load/Translation.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package alexiil.mods.load;

import java.io.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Enumeration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ public class BetterLoadingScreenTransformer implements IClassTransformer, Opcode

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
try {
if (transformedName.equals("net.minecraft.client.Minecraft")) return transformMinecraft(basicClass);
if (transformedName.equals("cpw.mods.fml.client.SplashProgress"))
return transformSplashProgress(basicClass);
if (name.equals("com.mumfrey.liteloader.client.api.ObjectFactoryClient"))
return transformObjectFactoryClient(basicClass);
} catch (Throwable t) {
BetterLoadingScreen.log.error("An issue occurred while transforming " + transformedName);
t.printStackTrace();
if (transformedName.equals("net.minecraft.client.Minecraft")) {
return transformMinecraft(basicClass);
}
if (transformedName.equals("cpw.mods.fml.client.SplashProgress")) {
return transformSplashProgress(basicClass);
}
if (name.equals("com.mumfrey.liteloader.client.api.ObjectFactoryClient")) {
return transformObjectFactoryClient(basicClass);
}
return basicClass;
}
Expand All @@ -35,7 +34,6 @@ private byte[] transformObjectFactoryClient(byte[] before) {
ClassNode classNode = new ClassNode();
ClassReader reader = new ClassReader(before);
reader.accept(classNode, 0);

for (MethodNode m : classNode.methods) {
if (m.name.equals("preBeginGame")) {
m.instructions.clear();
Expand All @@ -50,8 +48,7 @@ private byte[] transformObjectFactoryClient(byte[] before) {
m.instructions.add(new InsnNode(RETURN));
}
}

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
classNode.accept(cw);
return cw.toByteArray();
}
Expand All @@ -60,83 +57,73 @@ private byte[] transformSplashProgress(byte[] before) {
ClassNode classNode = new ClassNode();
ClassReader reader = new ClassReader(before);
reader.accept(classNode, 0);

for (MethodNode m : classNode.methods) {
if (m.name.equals("finish")) {
m.instructions.insert(
new MethodInsnNode(INVOKESTATIC, "alexiil/mods/load/ProgressDisplayer", "close", "()V", false));
}
}

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
ClassWriter cw = new ClassWriter(0);
classNode.accept(cw);
return cw.toByteArray();
}

private byte[] transformMinecraft(byte[] before) {
boolean hasFoundFMLClientHandler = false;
boolean hasFoundGL11 = false;
ClassNode classNode = new ClassNode();
ClassReader reader = new ClassReader(before);
reader.accept(classNode, 0);
int transformations = 0;

for (MethodNode m : classNode.methods) {
if (hasFoundGL11) break;
if (m.exceptions.size() == 1 && m.exceptions.get(0).equals("org/lwjgl/LWJGLException")) {
for (int i = 0; i < m.instructions.size(); i++) {
AbstractInsnNode node = m.instructions.get(i);
if (node instanceof MethodInsnNode) {
MethodInsnNode method = (MethodInsnNode) node;
if (method.owner.equals("org/lwjgl/opengl/GL11") && method.name.equals("glFlush")) {
hasFoundGL11 = true;
// This method throws an LWJGL exception, and calls GL11.glFlush(). This must be
// Minecraft.loadScreen()!
m.instructions.insertBefore(m.instructions.getFirst(), new InsnNode(RETURN));
// just return from the method, as if nothing happened
break;
}
if ((m.name.equals("aj") || m.name.equals("loadScreen")) && m.desc.equals("()V")) {
m.instructions.clear();
m.instructions.add(new InsnNode(RETURN));
m.exceptions.clear();
m.tryCatchBlocks.clear();
m.localVariables = null;
m.visitMaxs(0, 1);
transformations++;
break;
} else if ((m.name.equals("ag") || m.name.equals("startGame")) && m.desc.equals("()V")) {
for (AbstractInsnNode node : m.instructions.toArray()) {
if (node instanceof MethodInsnNode
&& ((MethodInsnNode) node).owner.equals("cpw/mods/fml/client/FMLClientHandler")
&& ((MethodInsnNode) node).name.equals("instance")) {
m.instructions.insertBefore(
node,
new MethodInsnNode(
INVOKESTATIC,
"alexiil/mods/load/ProgressDisplayer",
"minecraftDisplayFirstProgress",
"()V",
false));
transformations++;
break;
}
}
}
for (int i = 0; i < m.instructions.size(); i++) {
for (AbstractInsnNode node : m.instructions.toArray()) {
/*
* LiteLoader disabling -NOTE TO ANYONE FROM LITELOADER OR ANYONE ELSE: I am disabling liteloader's
* overlay simply because otherwise it switches between liteloader's bar and mine. I can safely assume
* that people won't want this, and as my progress bar is the entire mod, they can disable this
* behaviour by removing my mod (as all my mod does is just add a loading bar)
*/
AbstractInsnNode node = m.instructions.get(i);
if (node instanceof MethodInsnNode) {
MethodInsnNode method = (MethodInsnNode) node;
if (method.owner.equals("com/mumfrey/liteloader/client/gui/startup/LoadingBar")) {
m.instructions.remove(method);
continue;
}
}
// LiteLoader removing end

if (!hasFoundFMLClientHandler) {
if (node instanceof MethodInsnNode) {
MethodInsnNode method = (MethodInsnNode) node;
if (method.owner.equals("cpw/mods/fml/client/FMLClientHandler")
&& method.name.equals("instance")) {
MethodInsnNode newOne = new MethodInsnNode(
INVOKESTATIC,
"alexiil/mods/load/ProgressDisplayer",
"minecraftDisplayFirstProgress",
"()V",
false);
m.instructions.insertBefore(method, newOne);
hasFoundFMLClientHandler = true;
}
if (((MethodInsnNode) node).owner.equals("com/mumfrey/liteloader/client/gui/startup/LoadingBar")) {
m.instructions.remove(node);
}
}
}
}

ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
if (transformations != 2) {
throw new IllegalStateException("BetterLoadingScreen couldn't not transform Minecraft properly!");
}
ClassWriter cw = new ClassWriter(0);
classNode.accept(cw);
final byte[] byteArray = cw.toByteArray();
BetterLoadingScreen.log.debug("Transformed Minecraft");
return cw.toByteArray();
return byteArray;
}
}
Loading