Skip to content

Commit daa11e9

Browse files
committed
proper package name and workflows
1 parent fb1662a commit daa11e9

10 files changed

Lines changed: 267 additions & 572 deletions

File tree

.github/workflows/build.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
steps:
2+
- name: Checkout repository
3+
uses: actions/checkout@v4
4+
5+
- name: Set up JDK 21
6+
uses: actions/setup-java@v4
7+
with:
8+
java-version: '21'
9+
distribution: 'temurin'
10+
cache: 'gradle'
11+
12+
- name: Grant execute permission to gradlew
13+
run: chmod +x gradlew
14+
15+
- name: Build with Gradle
16+
run: ./gradlew build --no-daemon
17+
18+
- name: Find the primary build artifact (JAR/WAR)
19+
id: find_artifact
20+
run: |
21+
ARTIFACT_PATH=$(find build/libs/ -type f -name "*.jar" -o -name "*.war" | head -n 1)
22+
echo "artifact_path=$ARTIFACT_PATH" >> $GITHUB_OUTPUT
23+
24+
- name: Upload artifact to GitHub Release
25+
if: steps.find_artifact.outputs.artifact_path != ''
26+
uses: softprops/action-gh-release@v2
27+
with:
28+
files: ${{ steps.find_artifact.outputs.artifact_path }}
29+
env:
30+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

build.gradle

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ group = 'met.freehij.loader'
77
version = '1.0.0-SNAPSHOT'
88

99
repositories {
10-
maven {
11-
url "https://libraries.minecraft.net"
12-
}
1310
mavenCentral()
1411
}
1512

@@ -21,7 +18,7 @@ dependencies {
2118
jar {
2219
manifest {
2320
attributes(
24-
'Premain-Class': 'met.freehij.loader.Loader',
21+
'Premain-Class': 'io.github.freehij.loader.Loader',
2522
'Can-Redefine-Classes': true,
2623
'Can-Retransform-Classes': true
2724
)

src/main/java/met/freehij/injections/KnotClassPathFixer.java renamed to src/main/java/io/github/freehij/injections/KnotClassPathFixer.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
package met.freehij.injections;
1+
package io.github.freehij.injections;
22

3-
import met.freehij.loader.Loader;
4-
import met.freehij.loader.annotation.EditClass;
5-
import met.freehij.loader.annotation.Inject;
6-
import met.freehij.loader.util.InjectionHelper;
3+
import io.github.freehij.loader.Loader;
4+
import io.github.freehij.loader.annotation.EditClass;
5+
import io.github.freehij.loader.annotation.Inject;
6+
import io.github.freehij.loader.util.InjectionHelper;
77

88
import java.net.URL;
99
import java.nio.file.Path;

src/main/java/met/freehij/loader/Loader.java renamed to src/main/java/io/github/freehij/loader/Loader.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
package met.freehij.loader;
1+
package io.github.freehij.loader;
22

3-
import met.freehij.loader.annotation.Inject;
4-
import met.freehij.loader.annotation.EditClass;
5-
import met.freehij.loader.constant.At;
3+
import io.github.freehij.loader.annotation.Inject;
4+
import io.github.freehij.loader.annotation.EditClass;
5+
import io.github.freehij.loader.constant.At;
66
import org.objectweb.asm.*;
77

88
import java.io.*;
@@ -27,7 +27,7 @@ public class Loader {
2727
private static final List<URL> modUrls = new ArrayList<>();
2828

2929
public static void premain(String args, Instrumentation inst) {
30-
processInjectionClass("met/freehij/injections/KnotClassPathFixer",
30+
processInjectionClass("io/github/freehij/injections/KnotClassPathFixer",
3131
Thread.currentThread().getContextClassLoader());
3232
loadMods();
3333
System.out.println(Arrays.toString(mods.toArray()));
@@ -231,7 +231,7 @@ private void injectHelper() {
231231
static void generateHelperCall(MethodVisitor mv, int access, String desc, InjectionPoint injection) {
232232
boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
233233

234-
mv.visitTypeInsn(Opcodes.NEW, "met/freehij/loader/util/InjectionHelper");
234+
mv.visitTypeInsn(Opcodes.NEW, "io/github/freehij/loader/util/InjectionHelper");
235235
mv.visitInsn(Opcodes.DUP);
236236
if (isStatic) {
237237
mv.visitInsn(Opcodes.ACONST_NULL);
@@ -250,7 +250,7 @@ static void generateHelperCall(MethodVisitor mv, int access, String desc, Inject
250250
localIndex += args[i].getSize();
251251
}
252252
mv.visitMethodInsn(Opcodes.INVOKESPECIAL,
253-
"met/freehij/loader/util/InjectionHelper",
253+
"io/github/freehij/loader/util/InjectionHelper",
254254
"<init>",
255255
"(Ljava/lang/Object;[Ljava/lang/Object;)V",
256256
false);
@@ -260,20 +260,20 @@ static void generateHelperCall(MethodVisitor mv, int access, String desc, Inject
260260
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
261261
injection.handlerClass,
262262
injection.handlerMethod,
263-
"(Lmet/freehij/loader/util/InjectionHelper;)V",
263+
"(Lio/github/freehij/loader/util/InjectionHelper;)V",
264264
false);
265265
Label continueLabel = new Label();
266266
mv.visitVarInsn(Opcodes.ALOAD, 100);
267267
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
268-
"met/freehij/loader/util/InjectionHelper", "isCancelled", "()Z", false);
268+
"io/github/freehij/loader/util/InjectionHelper", "isCancelled", "()Z", false);
269269
mv.visitJumpInsn(Opcodes.IFEQ, continueLabel);
270270
Type returnType = Type.getReturnType(desc);
271271
if (returnType == Type.VOID_TYPE) {
272272
mv.visitInsn(Opcodes.RETURN);
273273
} else {
274274
mv.visitVarInsn(Opcodes.ALOAD, 100);
275275
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
276-
"met/freehij/loader/util/InjectionHelper", "getReturnValue", "()Ljava/lang/Object;", false);
276+
"io/github/freehij/loader/util/InjectionHelper", "getReturnValue", "()Ljava/lang/Object;", false);
277277
unbox(mv, returnType);
278278
mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
279279
}

src/main/java/met/freehij/loader/annotation/EditClass.java renamed to src/main/java/io/github/freehij/loader/annotation/EditClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package met.freehij.loader.annotation;
1+
package io.github.freehij.loader.annotation;
22

33
import java.lang.annotation.ElementType;
44
import java.lang.annotation.Retention;

src/main/java/met/freehij/loader/annotation/Inject.java renamed to src/main/java/io/github/freehij/loader/annotation/Inject.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
package met.freehij.loader.annotation;
1+
package io.github.freehij.loader.annotation;
22

3-
import met.freehij.loader.constant.At;
3+
import io.github.freehij.loader.constant.At;
44

55
import java.lang.annotation.ElementType;
66
import java.lang.annotation.Retention;

src/main/java/met/freehij/loader/constant/At.java renamed to src/main/java/io/github/freehij/loader/constant/At.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package met.freehij.loader.constant;
1+
package io.github.freehij.loader.constant;
22

33
public enum At {
44
HEAD,

src/main/java/met/freehij/loader/util/InjectionHelper.java renamed to src/main/java/io/github/freehij/loader/util/InjectionHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package met.freehij.loader.util;
1+
package io.github.freehij.loader.util;
22

33
public class InjectionHelper {
44
private final Object instance;
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package io.github.freehij.loader.util;
2+
3+
import java.lang.reflect.*;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
public class Reflector {
8+
private final Class<?> clazz;
9+
private final Object object;
10+
11+
public Reflector(Class<?> clazz, Object object) {
12+
this.clazz = clazz;
13+
this.object = object;
14+
}
15+
16+
public Object get() {
17+
return object;
18+
}
19+
20+
public int getInt() {
21+
return (int) object;
22+
}
23+
24+
public long getLong() {
25+
return (long) object;
26+
}
27+
28+
public float getFloat() {
29+
return (float) object;
30+
}
31+
32+
public double getDouble() {
33+
return (double) object;
34+
}
35+
36+
public byte getByte() {
37+
return (byte) object;
38+
}
39+
40+
public char getChar() {
41+
return (char) object;
42+
}
43+
44+
public short getShort() {
45+
return (short) object;
46+
}
47+
48+
public boolean getBoolean() {
49+
return (boolean) object;
50+
}
51+
52+
public String getString() {
53+
return (String) object;
54+
}
55+
56+
public Class<?> getActualClass() {
57+
return clazz;
58+
}
59+
60+
public Reflector getField(String fieldName) {
61+
//if this.object is null get a static variable else from an instanced class
62+
//returns Reflector with field value
63+
//throws Exception if field is not static and no object instance is presented
64+
//throws RuntimeException when other errors occur
65+
try {
66+
Field field = this.clazz.getDeclaredField(fieldName);
67+
field.setAccessible(true);
68+
69+
Object value;
70+
if (this.object == null) {
71+
if (!Modifier.isStatic(field.getModifiers())) {
72+
throw new Exception("Not a static field: " + fieldName);
73+
}
74+
value = field.get(null);
75+
} else {
76+
value = field.get(this.object);
77+
}
78+
79+
return new Reflector(field.getType(), value);
80+
} catch (Exception e) {
81+
throw new RuntimeException("Failed to get field: " + fieldName, e);
82+
}
83+
}
84+
85+
public void setField(String fieldName, Object value) {
86+
//if this.object is null set a static variable else in an instanced class
87+
//throws Exception if field is not static and no object instance is presented
88+
//throws RuntimeException when other errors occur
89+
try {
90+
Field field = clazz.getDeclaredField(fieldName);
91+
field.setAccessible(true);
92+
93+
if (object == null) {
94+
if (!Modifier.isStatic(field.getModifiers())) {
95+
throw new Exception("Not a static field: " + fieldName);
96+
}
97+
field.set(null, value);
98+
} else {
99+
field.set(object, value);
100+
}
101+
} catch (Exception e) {
102+
throw new RuntimeException("Failed to set field: " + fieldName, e);
103+
}
104+
}
105+
106+
public Reflector invoke(String methodName, String descriptor, Object... args) {
107+
//calculate the paramTypes and call invokeRaw
108+
return this.invokeRaw(methodName, parseDescriptor(descriptor), args);
109+
}
110+
111+
public Reflector invokeRaw(String methodName, Class<?>[] paramTypes, Object... args) {
112+
//should call the method using paramTypes and args
113+
//if this.object is null call method as static else call from instanced class
114+
//returns Reflector with methods return
115+
//throws Exception if method is not static and no object instance is presented
116+
//throws RuntimeException when other errors occur
117+
try {
118+
Method method = clazz.getDeclaredMethod(methodName, paramTypes);
119+
method.setAccessible(true);
120+
121+
Object result;
122+
if (object == null) {
123+
if (!Modifier.isStatic(method.getModifiers())) {
124+
throw new Exception("Not a static method: " + methodName);
125+
}
126+
result = method.invoke(null, args);
127+
} else {
128+
result = method.invoke(object, args);
129+
}
130+
131+
return new Reflector(method.getReturnType(), result);
132+
} catch (Exception e) {
133+
throw new RuntimeException("Failed to invoke method: " + methodName, e);
134+
}
135+
}
136+
137+
public Reflector newInstance(String descriptor, Object... args) {
138+
//should calculate the paramTypes and call newInstanceRaw
139+
return newInstanceRaw(parseDescriptor(descriptor), args);
140+
}
141+
142+
public Reflector newInstanceRaw(Class<?>[] paramTypes, Object... args) {
143+
//create new instance of this.clazz
144+
//return Reflector with newly created class instance
145+
//throws RuntimeException when errors occur
146+
try {
147+
Constructor<?> constructor = clazz.getDeclaredConstructor(paramTypes);
148+
constructor.setAccessible(true);
149+
Object instance = constructor.newInstance(args);
150+
return new Reflector(clazz, instance);
151+
} catch (Exception e) {
152+
throw new RuntimeException("Failed to create new instance", e);
153+
}
154+
}
155+
156+
static Class<?>[] parseDescriptor(String descriptor) {
157+
List<Class<?>> classes = new ArrayList<>();
158+
boolean isArray = false;
159+
for (int i = 0; i < descriptor.length(); i++) {
160+
switch (descriptor.charAt(i)) {
161+
case '[':
162+
isArray = true;
163+
break;
164+
case 'Z':
165+
classes.add(isArray ? boolean[].class : boolean.class);
166+
isArray = false;
167+
break;
168+
case 'B':
169+
classes.add(isArray ? byte[].class : byte.class);
170+
isArray = false;
171+
break;
172+
case 'C':
173+
classes.add(isArray ? char[].class : char.class);
174+
isArray = false;
175+
break;
176+
case 'S':
177+
classes.add(isArray ? short[].class : short.class);
178+
isArray = false;
179+
break;
180+
case 'I':
181+
classes.add(isArray ? int[].class : int.class);
182+
isArray = false;
183+
break;
184+
case 'J':
185+
classes.add(isArray ? long[].class : long.class);
186+
isArray = false;
187+
break;
188+
case 'F':
189+
classes.add(isArray ? float[].class : float.class);
190+
isArray = false;
191+
break;
192+
case 'D':
193+
classes.add(isArray ? double[].class : double.class);
194+
isArray = false;
195+
break;
196+
case 'L':
197+
StringBuilder className = new StringBuilder();
198+
while (i + 1 < descriptor.length() && descriptor.charAt(i + 1) != ';') {
199+
className.append(descriptor.charAt(i + 1));
200+
i++;
201+
}
202+
String clsName = className.toString().replace("/", ".");
203+
try {
204+
classes.add(isArray ? Array.newInstance(Class.forName(clsName), 0).getClass() : Class.forName(clsName));
205+
} catch (ClassNotFoundException e) {
206+
throw new RuntimeException("Failed to load class: " + clsName, e);
207+
}
208+
isArray = false;
209+
break;
210+
case ')':
211+
return classes.toArray(new Class<?>[0]);
212+
}
213+
}
214+
return classes.toArray(new Class<?>[0]);
215+
}
216+
}

0 commit comments

Comments
 (0)