Skip to content

Commit fdfa22c

Browse files
committed
Initial
1 parent 5b00207 commit fdfa22c

19 files changed

Lines changed: 1070 additions & 3 deletions
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Auto Assign
2+
on:
3+
pull_request_target:
4+
5+
jobs:
6+
run:
7+
runs-on: ubuntu-latest
8+
permissions:
9+
contents: read
10+
issues: write
11+
pull-requests: write
12+
discussions: write
13+
steps:
14+
- uses: wow-actions/auto-assign@v3
15+
with:
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17+
reviewers: RealMangoRage, PaintNinja
18+
assignees: PaintNinja, RealMangoRage
19+
skipKeywords: wip, draft
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Build MangoBotGradle
2+
on:
3+
push:
4+
branches: [ "master" ]
5+
paths-ignore:
6+
- 'README.md'
7+
- 'settings.gradle'
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
build:
14+
uses: MinecraftForge/SharedActions/.github/workflows/gradle.yml@v0
15+
with:
16+
java: 21
17+
gradle_tasks: :publish
18+
artifact_name: "MangoBotLaunchTarget"
19+
author_icon_url: "https://avatars.githubusercontent.com/u/147930550"
20+
secrets:
21+
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
22+
MAVEN_USER: ${{ secrets.USERNAME }} # Reference the secret
23+
MAVEN_PASSWORD: ${{ secrets.PASSWORD }} # Reference the secret

.idea/gradle.xml

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
rootProject.name = 'MangoBotLaunchTarget'
1+
rootProject.name = 'mangobotlaunchtarget'
22

src/main/java/module-info.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module org.mangorage.mangobotlaunchtarget {
2+
requires org.mangorage.bootstrap;
3+
4+
exports org.mangorage.mangobotlaunch.launch;
5+
6+
provides org.mangorage.mangobotlaunch.launch.MangoBotLaunchTarget with org.mangorage.mangobotlaunch.launch.MangoBotLaunchTarget;
7+
provides org.mangorage.mangobotlaunch.launch.MangoBotDependencyLocator with org.mangorage.mangobotlaunch.launch.MangoBotDependencyLocator;
8+
9+
uses org.mangorage.bootstrap.api.launch.ILaunchTarget;
10+
uses org.mangorage.bootstrap.api.dependency.IDependencyLocator;
11+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.mangorage.mangobotlaunch;
2+
3+
import org.mangorage.bootstrap.api.dependency.IDependency;
4+
import org.mangorage.bootstrap.api.util.GsonUtil;
5+
import org.mangorage.mangobotlaunch.util.Dependencies;
6+
7+
import java.io.FileNotFoundException;
8+
import java.io.IOException;
9+
import java.io.InputStream;
10+
import java.nio.charset.StandardCharsets;
11+
import java.nio.file.DirectoryStream;
12+
import java.nio.file.Files;
13+
import java.nio.file.Path;
14+
import java.util.ArrayList;
15+
import java.util.List;
16+
import java.util.jar.JarEntry;
17+
import java.util.jar.JarFile;
18+
19+
public final class DependencyHandler {
20+
21+
public static List<IDependency> scanPackages(Path packagesPath, Path librariesPath) throws IOException {
22+
23+
final List<IDependency> results = new ArrayList<>();
24+
25+
try (DirectoryStream<Path> stream = Files.newDirectoryStream(packagesPath)) {
26+
for (Path entry : stream) {
27+
if (Files.isRegularFile(entry)) {
28+
final Dependencies dependenciesList = GsonUtil.get(
29+
Dependencies.class,
30+
readFileFromJar(entry, "installer-data/dependencies.json")
31+
);
32+
33+
dependenciesList.dependencies().forEach(dependency -> {
34+
final var result = JarHandler.resolveModuleName(
35+
librariesPath.resolve(dependency.output())
36+
);
37+
results.add(result);
38+
});
39+
}
40+
}
41+
}
42+
43+
return results;
44+
}
45+
46+
47+
public static String readFileFromJar(Path jarPath, String entryPath) throws IOException {
48+
try (JarFile jar = new JarFile(jarPath.toFile())) {
49+
JarEntry entry = jar.getJarEntry(entryPath);
50+
51+
if (entry == null) {
52+
throw new FileNotFoundException("Entry not found in jar: " + entryPath);
53+
}
54+
55+
try (InputStream in = jar.getInputStream(entry)) {
56+
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
57+
}
58+
}
59+
}
60+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package org.mangorage.mangobotlaunch;
2+
3+
import org.mangorage.bootstrap.api.dependency.ModuleNameOrigin;
4+
import org.mangorage.mangobotlaunch.util.Result;
5+
6+
import java.io.IOException;
7+
import java.io.UncheckedIOException;
8+
import java.lang.module.ModuleFinder;
9+
import java.nio.file.Path;
10+
import java.util.jar.JarFile;
11+
import java.util.jar.Manifest;
12+
13+
public final class JarHandler {
14+
15+
public static Result resolveModuleName(Path jarPath) {
16+
try (JarFile jarFile = new JarFile(jarPath.toFile())) {
17+
18+
String moduleName = null;
19+
20+
try {
21+
moduleName = ModuleFinder.of(jarPath)
22+
.findAll()
23+
.iterator()
24+
.next()
25+
.descriptor()
26+
.name();
27+
} catch (Exception ignore) {}
28+
29+
// 1. Proper JPMS module
30+
if (jarFile.getEntry("module-info.class") != null) {
31+
return new Result(
32+
ModuleFinder.of(jarPath)
33+
.findAll()
34+
.iterator()
35+
.next()
36+
.descriptor()
37+
.name(),
38+
ModuleNameOrigin.MODULE_INFO,
39+
jarPath
40+
);
41+
} else if (jarFile.isMultiRelease() && moduleName != null) {
42+
return new Result(moduleName, ModuleNameOrigin.MULTI_RELEASE, jarPath);
43+
}
44+
45+
// 2. Check MANIFEST.MF for Automatic-Module-Name
46+
Manifest manifest = jarFile.getManifest();
47+
48+
if (manifest != null) {
49+
String autoName = manifest.getMainAttributes()
50+
.getValue("Automatic-Module-Name");
51+
52+
if (autoName != null && !autoName.isBlank()) {
53+
return new Result(
54+
autoName,
55+
ModuleNameOrigin.MANIFEST,
56+
jarPath
57+
);
58+
}
59+
60+
try {
61+
final var found = ModuleFinder.of(jarPath).findAll();
62+
if (found != null) {
63+
final var foundModule = found.stream().findAny();
64+
if (foundModule.isPresent())
65+
System.out.println(foundModule.get());
66+
return new Result(
67+
foundModule.get().descriptor().name(),
68+
ModuleNameOrigin.MODULE_FINDER,
69+
jarPath
70+
);
71+
}
72+
} catch (Exception ignore) {
73+
ignore.printStackTrace();
74+
}
75+
76+
77+
String symbolicName = manifest.getMainAttributes()
78+
.getValue("Bundle-SymbolicName");
79+
80+
if (symbolicName != null) {
81+
return new Result(
82+
symbolicName,
83+
ModuleNameOrigin.MANIFEST_BUNDLE_SYMBOLIC_NAME,
84+
jarPath
85+
);
86+
}
87+
88+
}
89+
90+
// 3. Fallback: filename heuristic (aka desperation mode)
91+
String filename = jarPath.getFileName().toString();
92+
93+
String cleanedName = filename
94+
.replaceAll("-[\\d\\.]+.*\\.jar$", "") // Remove version and extension
95+
.replaceAll("\\.jar$", "") // Remove extension if no version
96+
.replace('-', '.'); // Convert hyphens to dots
97+
98+
return new Result(
99+
cleanedName,
100+
ModuleNameOrigin.GUESSED,
101+
jarPath
102+
);
103+
104+
} catch (IOException e) {
105+
throw new UncheckedIOException("Failed to read JAR: " + jarPath, e);
106+
}
107+
}
108+
109+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.mangorage.mangobotlaunch.launch;
2+
3+
import org.mangorage.bootstrap.api.transformer.IClassTransformer;
4+
import org.mangorage.bootstrap.api.transformer.TransformResult;
5+
import org.mangorage.bootstrap.api.transformer.TransformerFlag;
6+
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.concurrent.ConcurrentHashMap;
10+
import java.util.concurrent.CopyOnWriteArrayList;
11+
import java.util.concurrent.atomic.AtomicReference;
12+
13+
public final class ClassTransformers {
14+
private final Map<String, Class<?>> classes = new ConcurrentHashMap<>();
15+
private final List<IClassTransformer> transformers = new CopyOnWriteArrayList<>(); // Transformer's
16+
private final ClassLoader loader;
17+
18+
ClassTransformers(ClassLoader loader) {
19+
this.loader = loader;
20+
}
21+
22+
void add(String name, Class<?> clz) {
23+
classes.put(name, clz);
24+
}
25+
26+
void add(IClassTransformer transformer) {
27+
transformers.add(transformer);
28+
}
29+
30+
boolean isEmpty() {
31+
return transformers.isEmpty();
32+
}
33+
34+
byte[] transform(String name, byte[] classData) {;
35+
36+
AtomicReference<TransformResult> result = new AtomicReference<>(TransformerFlag.NO_REWRITE.of(classData));
37+
AtomicReference<IClassTransformer> _transformer = new AtomicReference<>();
38+
39+
for (IClassTransformer transformer : transformers) {
40+
result.set(transformer.transform(name, classData));
41+
if (result.get().flag() != TransformerFlag.NO_REWRITE) {
42+
_transformer.set(transformer);
43+
break;
44+
}
45+
}
46+
47+
if (result.get().flag() != TransformerFlag.NO_REWRITE && _transformer.get() != null) {
48+
System.out.println("%s Transformed %s".formatted(_transformer.get().getName(), name));
49+
return result.get().classData();
50+
}
51+
52+
return null;
53+
}
54+
55+
boolean containsClass(String name) {
56+
return classes.containsKey(name);
57+
}
58+
59+
Class<?> getClazz(String string) {
60+
return classes.get(string);
61+
}
62+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package org.mangorage.mangobotlaunch.launch;
2+
3+
import java.io.IOException;
4+
import java.lang.module.ModuleReader;
5+
import java.lang.module.ModuleReference;
6+
import java.net.URI;
7+
import java.security.CodeSigner;
8+
import java.security.CodeSource;
9+
import java.util.ArrayList;
10+
import java.util.List;
11+
import java.util.Optional;
12+
import java.util.stream.Stream;
13+
14+
public final class LoadedModule implements ModuleReader {
15+
private final List<LoadedModule> children = new ArrayList<>();
16+
17+
private final ModuleReference moduleReference;
18+
private final ModuleReader moduleReader;
19+
private final CodeSource codeSource;
20+
21+
LoadedModule(ModuleReference moduleReference) throws IOException {
22+
this.moduleReference = moduleReference;
23+
this.moduleReader = moduleReference.open();
24+
this.codeSource = new CodeSource(moduleReference.location().get().toURL(), (CodeSigner[]) null);
25+
}
26+
27+
ModuleReference getModuleReference() {
28+
return moduleReference;
29+
}
30+
31+
ModuleReader getModuleReader() {
32+
return moduleReader;
33+
}
34+
35+
CodeSource getCodeSource() {
36+
return codeSource;
37+
}
38+
39+
void addChild(LoadedModule module) {
40+
this.children.add(module);
41+
}
42+
43+
String name() {
44+
return getModuleReference().descriptor().name();
45+
}
46+
47+
@Override
48+
public Optional<URI> find(String name) throws IOException {
49+
final var optional = getModuleReader().find(name);
50+
if (optional.isPresent()) return optional;
51+
52+
for (LoadedModule child : children) {
53+
final var optionalChild = child.getModuleReader().find(name);
54+
if (optionalChild.isPresent())
55+
return optionalChild;
56+
}
57+
58+
return Optional.empty();
59+
}
60+
61+
@Override
62+
public Stream<String> list() throws IOException {
63+
return Stream.empty();
64+
}
65+
66+
@Override
67+
public void close() throws IOException {
68+
69+
}
70+
}

0 commit comments

Comments
 (0)