Skip to content

Commit 977d000

Browse files
committed
Merge remote-tracking branch 'origin/1.20-fabric' into 1.20.4-fabric
# Conflicts: # gradle.properties
2 parents 30eb907 + 7ce30b9 commit 977d000

File tree

63 files changed

+738
-440
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+738
-440
lines changed

CHANGELOG.md

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
### What's New:
22

3-
[`gui/item_frame_tooltips`] && [`gui/name_tooltips`]:
3+
[`gui/smooth_tooltips`]:
44

5-
* Fixed tooltip alignment with Iceberg installed. (Legendary Tooltips)
5+
* New Module!
6+
* Makes tooltips slowly flow towards the cursor.
7+
* Compatibility can be hit & miss, so experimental, for now.
8+
9+
[`mechanics/dragon_fight`]:
10+
11+
* Fixed the `ConcurrentModificationException` crash.
12+
* Moved data to a new format. **All data has been reset.**
13+
14+
[`mechanics/trading_goat_horn`]:
15+
16+
* Moved data to a new format. **All data has been reset.**
617

718
[`general`]:
819

9-
* Misc fixes.
20+
* Updated Chinese translation. Courtesy of [Rad586](https://github.com/Rad586).
21+
* Startup should be a bit faster now.
22+
* Andromeda used to scan every module's package for classes `Main`, `Merged`, `client.Client` and `server.Server`.
23+
* Now, module entrypoints are defined and registered during module construction.
24+
* Other minor changes.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2023 melontini
3+
Copyright (c) 2024 melontini
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
## <img src="https://github.com/melontini/andromeda/assets/104443436/f8724c6c-f15b-49ca-9f42-b7ae01d1e64a" width="75" height="75"> Andromeda
22

33
[![Modrinth](https://img.shields.io/modrinth/dt/TseYlb0f?logo=modrinth&color=mint)](https://modrinth.com/mod/andromeda)
4-
[![CodeFactor](https://www.codefactor.io/repository/github/melontini/andromeda/badge)](https://www.codefactor.io/repository/github/melontini/andromeda)
5-
![GitHub](https://img.shields.io/github/license/melontini/andromeda)
4+
[![CodeFactor](https://www.codefactor.io/repository/github/constellation-mc/andromeda/badge)](https://www.codefactor.io/repository/github/melontini/andromeda)
5+
![GitHub](https://img.shields.io/github/license/constellation-mc/andromeda)
66

77
### A galaxy is a collection of things and systems. So is this mod.
88

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ minecraft_version=1.20.4
88
yarn_mappings=1.20.4+build.3
99
loader_version=0.15.7
1010
# Mod Properties
11-
mod_version=1.7.1-1.20.4
11+
mod_version=1.8.0-1.20.4
1212
maven_group=me.melontini
1313
archives_base_name=andromeda
1414
# Dependencies

src/main/java/me/melontini/andromeda/base/Bootstrap.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package me.melontini.andromeda.base;
22

33
import lombok.CustomLog;
4+
import me.melontini.andromeda.base.events.Bus;
5+
import me.melontini.andromeda.base.events.InitEvent;
46
import me.melontini.andromeda.base.util.annotations.ModuleInfo;
57
import me.melontini.andromeda.common.Andromeda;
68
import me.melontini.andromeda.common.client.AndromedaClient;
@@ -43,6 +45,14 @@
4345
@CustomLog
4446
public class Bootstrap {
4547

48+
private static void runInit(String init, Module<?> module) {
49+
run(() -> {
50+
Bus<InitEvent> event = module.getOrCreateBus(init + "_init_event", null);
51+
if (event == null) return;
52+
event.invoker().collect().forEach(module::initClass);
53+
}, (b) -> b.message("Failed to execute %s!".formatted(init)).add("module", module.meta().id()));
54+
}
55+
4656
@Environment(EnvType.CLIENT)
4757
public static void onClient() {
4858
Status.update();
@@ -51,7 +61,7 @@ public static void onClient() {
5161

5262
for (Module<?> module : ModuleManager.get().loaded()) {
5363
if (module.meta().environment().isServer()) continue;
54-
run(() -> module.initClasses("client.Client"), (b) -> b.message("Failed to execute Module.onClient!").add("module", module.meta().id()));
64+
runInit("client", module);
5565
}
5666
run(AndromedaClient::init, b -> b.message("Failed to initialize AndromedaClient!"));
5767
}
@@ -64,7 +74,7 @@ public static void onServer() {
6474

6575
for (Module<?> module : ModuleManager.get().loaded()) {
6676
if (module.meta().environment().isClient()) continue;
67-
run(() -> module.initClasses("server.Server"), (b) -> b.message("Failed to execute Module.onServer!").add("module", module.meta().id()));
77+
runInit("server", module);
6878
}
6979
}
7080

@@ -73,7 +83,7 @@ private static void onMerged() {
7383
MixinEnvironment.getCurrentEnvironment().audit();
7484

7585
for (Module<?> module : ModuleManager.get().loaded()) {
76-
run(() -> module.initClasses("Merged"), (b) -> b.message("Failed to execute Module.onMerged!").add("module", module.meta().id()));
86+
runInit("merged", module);
7787
}
7888
}
7989

@@ -90,7 +100,7 @@ public static void onMain() {
90100
}
91101

92102
for (Module<?> module : ModuleManager.get().loaded()) {
93-
run(() -> module.initClasses("Main"), (b) -> b.message("Failed to execute Module!").add("module", module.meta().id()));
103+
runInit("main", module);
94104
}
95105

96106
run(Andromeda::init, b -> b.message("Failed to initialize Andromeda!"));
@@ -143,7 +153,7 @@ public static void onPreLaunch() {
143153
m.print();
144154
//Scan for mixins.
145155
m.loaded().forEach(module -> getModuleClassPath().addUrl(module.getClass().getProtectionDomain().getCodeSource().getLocation()));
146-
run(() -> MixinProcessor.addMixins(m), (b) -> b.message("Failed to inject dynamic mixin configs!").message(MixinProcessor.NOTICE));
156+
run(() -> m.getMixinProcessor().addMixins(), (b) -> b.message("Failed to inject dynamic mixin configs!").message(MixinProcessor.NOTICE));
147157
Support.share("andromeda:module_manager", m);
148158

149159
Status.update();

src/main/java/me/melontini/andromeda/base/MixinProcessor.java

Lines changed: 40 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,24 @@
44
import lombok.CustomLog;
55
import me.melontini.andromeda.base.events.Bus;
66
import me.melontini.andromeda.base.events.MixinConfigEvent;
7-
import me.melontini.andromeda.base.util.annotations.SpecialEnvironment;
7+
import me.melontini.andromeda.base.util.ModulePlugin;
8+
import me.melontini.andromeda.util.CommonValues;
89
import me.melontini.andromeda.util.exceptions.AndromedaException;
9-
import me.melontini.andromeda.util.mixin.AndromedaMixins;
1010
import me.melontini.dark_matter.api.base.reflect.wrappers.GenericField;
1111
import me.melontini.dark_matter.api.base.reflect.wrappers.GenericMethod;
12-
import me.melontini.dark_matter.api.base.util.mixin.ExtendablePlugin;
13-
import me.melontini.dark_matter.api.base.util.mixin.IPluginPlugin;
14-
import org.objectweb.asm.Label;
15-
import org.objectweb.asm.Opcodes;
16-
import org.objectweb.asm.Type;
17-
import org.objectweb.asm.tree.AnnotationNode;
18-
import org.objectweb.asm.tree.ClassNode;
19-
import org.objectweb.asm.tree.InsnList;
20-
import org.objectweb.asm.tree.MethodNode;
12+
import org.jetbrains.annotations.ApiStatus;
2113
import org.spongepowered.asm.mixin.FabricUtil;
2214
import org.spongepowered.asm.mixin.Mixins;
23-
import org.spongepowered.asm.mixin.Unique;
24-
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
25-
import org.spongepowered.asm.mixin.transformer.meta.MixinMerged;
2615
import org.spongepowered.asm.service.IMixinService;
2716
import org.spongepowered.asm.service.MixinService;
28-
import org.spongepowered.asm.util.Annotations;
2917

3018
import java.io.ByteArrayInputStream;
3119
import java.io.IOException;
3220
import java.io.InputStream;
3321
import java.lang.reflect.Proxy;
34-
import java.util.List;
35-
import java.util.Set;
22+
import java.util.HashMap;
23+
import java.util.Map;
24+
import java.util.Optional;
3625

3726
/**
3827
* The MixinProcessor is responsible for injecting dynamic mixin configs.
@@ -43,21 +32,35 @@
4332
public class MixinProcessor {
4433

4534
public static final String NOTICE = "## Mixin configs are internal mod components and are not the same as user configs! ##";
35+
public static final String JAVA_VERSION = "JAVA_17";
36+
public static final String MIXIN_VERSION = "0.8.5";
37+
4638
private static final ThreadLocal<InputStream> CONFIG = ThreadLocal.withInitial(() -> null);
47-
private static boolean done = false;
39+
private boolean done = false;
40+
private final ModuleManager manager;
41+
private final Map<String, Module<?>> mixinConfigs = new HashMap<>();
42+
43+
public MixinProcessor(ModuleManager manager) {
44+
this.manager = manager;
45+
}
4846

49-
public static void addMixins(ModuleManager manager) {
47+
@ApiStatus.Internal
48+
public Optional<Module<?>> fromConfig(String name) {
49+
return Optional.ofNullable(mixinConfigs.get(name));
50+
}
51+
52+
public void addMixins() {
5053
if (done) return;
5154
IMixinService service = MixinService.getService();
52-
MixinProcessor.injectService(service);
53-
manager.loaded().forEach((module) -> {
55+
this.injectService(service);
56+
this.manager.loaded().forEach((module) -> {
5457
JsonObject config = createConfig(module);
5558

5659
String cfg = "andromeda_dynamic$$" + module.meta().dotted() + ".mixins.json";
5760
try (ByteArrayInputStream bais = new ByteArrayInputStream(config.toString().getBytes())) {
58-
CONFIG.set(bais);
61+
CONFIG.set(bais);//Is there a safer way to do this?
5962
Mixins.addConfiguration(cfg);
60-
manager.mixinConfigs.put(cfg, module);
63+
this.mixinConfigs.put(cfg, module);
6164
} catch (IOException e) {
6265
throw AndromedaException.builder()
6366
.message("Couldn't inject mixin config for module '%s'".formatted(module.meta().id())).message(NOTICE)
@@ -66,38 +69,39 @@ public static void addMixins(ModuleManager manager) {
6669
CONFIG.remove();
6770
}
6871
});
69-
MixinProcessor.dejectService(service);
72+
this.dejectService(service);
7073
done = true;
7174

72-
Mixins.getConfigs().forEach(config1 -> {
73-
if (manager.mixinConfigs.containsKey(config1.getName())) {
74-
config1.getConfig().decorate(FabricUtil.KEY_MOD_ID, "andromeda");
75+
Mixins.getConfigs().forEach(config -> {
76+
if (this.mixinConfigs.containsKey(config.getName())) {
77+
config.getConfig().decorate(FabricUtil.KEY_MOD_ID, CommonValues.MODID);
7578
}
7679
});
7780
}
7881

79-
public static JsonObject createConfig(Module<?> module) {
82+
public JsonObject createConfig(Module<?> module) {
8083
JsonObject object = new JsonObject();
8184
object.addProperty("required", true);
82-
object.addProperty("minVersion", "0.8");
85+
object.addProperty("minVersion", MIXIN_VERSION);
8386
object.addProperty("package", module.getClass().getPackageName() + ".mixin");
84-
object.addProperty("compatibilityLevel", "JAVA_17");
85-
object.addProperty("plugin", Plugin.class.getName());
87+
object.addProperty("compatibilityLevel", JAVA_VERSION);
88+
object.addProperty("plugin", ModulePlugin.class.getName());
8689
object.addProperty("refmap", "andromeda-refmap.json");
8790
JsonObject injectors = new JsonObject();
8891
injectors.addProperty("defaultRequire", 1);
92+
injectors.addProperty("maxShiftBy", 3);
8993
object.add("injectors", injectors);
9094

91-
Bus<MixinConfigEvent> bus = module.getOrCreateBus(MixinConfigEvent.class, null);
95+
Bus<MixinConfigEvent> bus = module.getOrCreateBus("mixin_config_event", null);
9296
if (bus != null) bus.invoker().accept(object);
9397

9498
return object;
9599
}
96100

97-
private static final GenericMethod<?, MixinService> GET_INSTANCE = GenericMethod.of(MixinService.class, "getInstance");
98-
private static final GenericField<MixinService, IMixinService> SERVICE = GenericField.of(MixinService.class, "service");
101+
private final GenericMethod<?, MixinService> GET_INSTANCE = GenericMethod.of(MixinService.class, "getInstance");
102+
private final GenericField<MixinService, IMixinService> SERVICE = GenericField.of(MixinService.class, "service");
99103

100-
public static void injectService(IMixinService currentService) {
104+
public void injectService(IMixinService currentService) {
101105
IMixinService service = (IMixinService) Proxy.newProxyInstance(MixinProcessor.class.getClassLoader(), new Class[]{IMixinService.class}, (proxy, method, args) -> {
102106
if (method.getName().equals("getResourceAsStream")) {
103107
if (args[0] instanceof String s) {
@@ -113,74 +117,8 @@ public static void injectService(IMixinService currentService) {
113117
SERVICE.accessible(true).set(serviceProxy, service);
114118
}
115119

116-
public static void dejectService(IMixinService realService) {
120+
public void dejectService(IMixinService realService) {
117121
MixinService serviceProxy = GET_INSTANCE.accessible(true).invoke(null);
118122
SERVICE.accessible(true).set(serviceProxy, realService);
119123
}
120-
121-
@SuppressWarnings("UnstableApiUsage")
122-
public static class Plugin extends ExtendablePlugin {
123-
124-
private static final String MIXIN_ENVIRONMENT_ANNOTATION = "L" + SpecialEnvironment.class.getName().replace(".", "/") + ";";
125-
126-
private String mixinPackage;
127-
128-
@Override
129-
protected void collectPlugins(Set<IPluginPlugin> plugins) {
130-
plugins.add(DefaultPlugins.constructDummyPlugin());
131-
}
132-
133-
protected void onPluginLoad(String mixinPackage) {
134-
this.mixinPackage = mixinPackage;
135-
}
136-
137-
protected void getMixins(List<String> mixins) {
138-
mixins.addAll(AndromedaMixins.discoverInPackage(this.mixinPackage));
139-
}
140-
141-
@Override
142-
protected void afterApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
143-
if (targetClass.visibleAnnotations != null && !targetClass.visibleAnnotations.isEmpty()) {//strip our annotation from the class
144-
targetClass.visibleAnnotations.removeIf(node -> MIXIN_ENVIRONMENT_ANNOTATION.equals(node.desc));
145-
}
146-
147-
for (MethodNode method : targetClass.methods) {
148-
AnnotationNode unique = Annotations.getVisible(method, Unique.class);
149-
AnnotationNode mixinMerged = Annotations.getVisible(method, MixinMerged.class);
150-
if (unique == null && mixinMerged != null) {
151-
String mixin = Annotations.getValue(mixinMerged, "mixin");
152-
if (mixin.startsWith(this.mixinPackage)) {
153-
wrapNodeWithErrorHandling(method, ModuleManager.get().moduleFromConfig(mixinInfo.getConfig().getName()).orElseThrow().meta().id());
154-
}
155-
}
156-
}
157-
}
158-
159-
private void wrapNodeWithErrorHandling(MethodNode handlerNode, String module) {
160-
Label start = new Label(), end = new Label(), handler = new Label(), handlerEnd = new Label();
161-
162-
String throwable = Type.getInternalName(Throwable.class);
163-
handlerNode.visitTryCatchBlock(start, end, handler, throwable);
164-
165-
InsnList old = handlerNode.instructions;
166-
handlerNode.instructions = new InsnList();
167-
handlerNode.visitLabel(start);
168-
handlerNode.instructions.add(old);
169-
170-
handlerNode.visitLabel(end);
171-
handlerNode.visitJumpInsn(Opcodes.GOTO, handlerEnd);
172-
173-
handlerNode.visitLabel(handler);
174-
handlerNode.visitVarInsn(Opcodes.ASTORE, handlerNode.maxLocals);
175-
176-
handlerNode.visitVarInsn(Opcodes.ALOAD, handlerNode.maxLocals);
177-
handlerNode.visitLdcInsn(module);
178-
handlerNode.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(AndromedaException.class), "moduleException", "(" + Type.getDescriptor(Throwable.class) + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(AndromedaException.class), false);
179-
180-
handlerNode.visitInsn(Opcodes.ATHROW);
181-
handlerNode.visitLabel(handlerEnd);
182-
183-
handlerNode.visitLocalVariable("exc", "L" + throwable + ";", null, start, handler, handlerNode.maxLocals);
184-
}
185-
}
186124
}

0 commit comments

Comments
 (0)