Skip to content

Commit c440524

Browse files
committed
i was too lazy to sort these changes
1 parent 8290e04 commit c440524

File tree

15 files changed

+391
-243
lines changed

15 files changed

+391
-243
lines changed

dependencies.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ dependencies {
66
transitive = false
77
}
88
compileOnly("com.falsepattern:json:0.4.1")
9+
compileOnly("org.tukaani:xz:1.9")
910
annotationProcessor("org.projectlombok:lombok:1.18.22")
1011
}
File renamed without changes.
File renamed without changes.
File renamed without changes.

repositories.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
repositories {
22
maven {
33
name = "sponge"
4-
url = "https://sponge.falsepattern.com/"
4+
url = "https://mvn.falsepattern.com/sponge"
55
}
66
maven {
7-
name = "mavenpattern"
8-
url = "https://maven.falsepattern.com/"
7+
name = "mvnpattern"
8+
url = "https://mvn.falsepattern.com/releases/"
99
}
1010
}

src/main/java/com/falsepattern/lib/dependencies/SemanticVersion.java

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
package com.falsepattern.lib.dependencies;
2222

2323
import com.falsepattern.lib.StableAPI;
24-
import lombok.Builder;
2524
import lombok.Getter;
2625
import lombok.NonNull;
2726
import lombok.val;
@@ -30,23 +29,17 @@
3029

3130
@StableAPI(since = "0.6.0")
3231
public class SemanticVersion extends Version {
33-
@Getter
32+
@Getter(onMethod_ = @StableAPI.Expose)
3433
private final int majorVersion;
35-
@Getter
34+
@Getter(onMethod_ = @StableAPI.Expose)
3635
private final int minorVersion;
37-
@Getter
36+
@Getter(onMethod_ = @StableAPI.Expose)
3837
private final int patchVersion;
39-
@Getter
38+
@Getter(onMethod_ = @StableAPI.Expose)
4039
private final String preRelease;
41-
@Getter
40+
@Getter(onMethod_ = @StableAPI.Expose)
4241
private final String build;
4342

44-
@StableAPI.Expose
45-
public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease) {
46-
this(majorVersion, minorVersion, patchVersion, preRelease, null);
47-
}
48-
49-
@Builder
5043
@StableAPI.Expose
5144
public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease, String build) {
5245
this.majorVersion = majorVersion;
@@ -58,11 +51,31 @@ public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, Str
5851
this.build = "".equals(build) ? null : build;
5952
}
6053

54+
@StableAPI.Expose
55+
public SemanticVersion(int majorVersion, int minorVersion, int patchVersion, String preRelease) {
56+
this(majorVersion, minorVersion, patchVersion, preRelease, null);
57+
}
58+
6159
@StableAPI.Expose
6260
public SemanticVersion(int majorVersion, int minorVersion, int patchVersion) {
6361
this(majorVersion, minorVersion, patchVersion, null, null);
6462
}
6563

64+
@StableAPI.Expose(since = "0.10.0")
65+
public SemanticVersion(int majorVersion, int minorVersion) {
66+
this(majorVersion, minorVersion, -1, null, null);
67+
}
68+
69+
@StableAPI.Expose(since = "0.10.0")
70+
public SemanticVersion(int majorVersion) {
71+
this(majorVersion, -1, -1, null, null);
72+
}
73+
74+
@StableAPI.Expose
75+
public static SemanticVersionBuilder builder() {
76+
return new SemanticVersionBuilder();
77+
}
78+
6679
@Override
6780
public int compareTo(@NonNull Version o) {
6881
if (o instanceof ComplexVersion) {
@@ -98,7 +111,62 @@ public int compareTo(@NonNull Version o) {
98111

99112
@Override
100113
public String toString() {
101-
return majorVersion + "." + minorVersion + "." + patchVersion + (preRelease == null ? "" : "-" + preRelease) +
114+
return majorVersion + (minorVersion < 0 ? "" : "." + minorVersion) + (patchVersion < 0 ? "" : "." + patchVersion) + (preRelease == null ? "" : "-" + preRelease) +
102115
(build == null ? "" : "+" + build);
103116
}
117+
118+
@StableAPI(since = "0.10.0")
119+
public static class SemanticVersionBuilder {
120+
private int majorVersion;
121+
private int minorVersion = -1;
122+
private int patchVersion = -1;
123+
private String preRelease;
124+
private String build;
125+
126+
@StableAPI.Internal
127+
SemanticVersionBuilder() {
128+
}
129+
130+
@StableAPI.Expose
131+
public SemanticVersionBuilder majorVersion(int majorVersion) {
132+
this.majorVersion = majorVersion;
133+
return this;
134+
}
135+
136+
@StableAPI.Expose
137+
public SemanticVersionBuilder minorVersion(int minorVersion) {
138+
this.minorVersion = minorVersion;
139+
return this;
140+
}
141+
142+
@StableAPI.Expose
143+
public SemanticVersionBuilder patchVersion(int patchVersion) {
144+
this.patchVersion = patchVersion;
145+
return this;
146+
}
147+
148+
@StableAPI.Expose
149+
public SemanticVersionBuilder preRelease(String preRelease) {
150+
this.preRelease = preRelease;
151+
return this;
152+
}
153+
154+
@StableAPI.Expose
155+
public SemanticVersionBuilder build(String build) {
156+
this.build = build;
157+
return this;
158+
}
159+
160+
@StableAPI.Expose
161+
public SemanticVersion build() {
162+
return new SemanticVersion(majorVersion, minorVersion, patchVersion, preRelease, build);
163+
}
164+
165+
@Override
166+
public String toString() {
167+
return "SemanticVersion.SemanticVersionBuilder(majorVersion=" + this.majorVersion + ", minorVersion=" +
168+
this.minorVersion + ", patchVersion=" + this.patchVersion + ", preRelease=" + this.preRelease +
169+
", build=" + this.build + ")";
170+
}
171+
}
104172
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.falsepattern.lib.internal.impl.mixin;
2+
3+
import com.falsepattern.lib.mixin.MinecraftURLClassPath;
4+
import lombok.val;
5+
6+
import net.minecraft.launchwrapper.LaunchClassLoader;
7+
import cpw.mods.fml.common.Loader;
8+
import cpw.mods.fml.common.ModClassLoader;
9+
10+
import java.io.File;
11+
import java.lang.reflect.Method;
12+
import java.net.URL;
13+
14+
public final class UCPImpl {
15+
private static final Object ucp;
16+
private static final Method addURL;
17+
private static final boolean GRIMOIRE;
18+
19+
static {
20+
boolean grimoire = false;
21+
String[] knownGrimoireClassNames =
22+
new String[]{"io.github.crucible.grimoire.Grimoire", "io.github.crucible.grimoire.common.GrimoireCore"};
23+
for (val className : knownGrimoireClassNames) {
24+
try {
25+
Class.forName(className, false, MinecraftURLClassPath.class.getClassLoader());
26+
grimoire = true;
27+
break;
28+
} catch (ClassNotFoundException ignored) {
29+
}
30+
}
31+
GRIMOIRE = grimoire;
32+
if (!GRIMOIRE) {
33+
try {
34+
val modClassLoaderField = Loader.class.getDeclaredField("modClassLoader");
35+
modClassLoaderField.setAccessible(true);
36+
37+
val loaderInstanceField = Loader.class.getDeclaredField("instance");
38+
loaderInstanceField.setAccessible(true);
39+
40+
val mainClassLoaderField = ModClassLoader.class.getDeclaredField("mainClassLoader");
41+
mainClassLoaderField.setAccessible(true);
42+
43+
val ucpField = LaunchClassLoader.class.getSuperclass().getDeclaredField("ucp");
44+
ucpField.setAccessible(true);
45+
46+
Object loader = loaderInstanceField.get(null);
47+
val modClassLoader = (ModClassLoader) modClassLoaderField.get(loader);
48+
val mainClassLoader = (LaunchClassLoader) mainClassLoaderField.get(modClassLoader);
49+
ucp = ucpField.get(mainClassLoader);
50+
addURL = ucp.getClass().getDeclaredMethod("addURL", URL.class);
51+
} catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
52+
throw new RuntimeException(e.getMessage());
53+
}
54+
} else {
55+
ucp = null;
56+
addURL = null;
57+
System.err.println("Grimoire detected, disabling jar loading utility");
58+
}
59+
}
60+
61+
public static void addJar(File pathToJar) throws Exception {
62+
if (!GRIMOIRE) {
63+
addURL.invoke(ucp, pathToJar.toURI().toURL());
64+
}
65+
}
66+
}
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
package com.falsepattern.lib.internal.impl.updates;
2+
3+
import com.falsepattern.json.node.JsonNode;
4+
import com.falsepattern.lib.dependencies.DependencyLoader;
5+
import com.falsepattern.lib.dependencies.Library;
6+
import com.falsepattern.lib.dependencies.SemanticVersion;
7+
import com.falsepattern.lib.internal.Internet;
8+
import com.falsepattern.lib.internal.Tags;
9+
import com.falsepattern.lib.internal.config.LibraryConfig;
10+
import com.falsepattern.lib.text.FormattedText;
11+
import com.falsepattern.lib.updates.ModUpdateInfo;
12+
import com.falsepattern.lib.updates.UpdateCheckException;
13+
import lombok.val;
14+
15+
import net.minecraft.client.resources.I18n;
16+
import net.minecraft.event.ClickEvent;
17+
import net.minecraft.util.IChatComponent;
18+
19+
import cpw.mods.fml.common.Loader;
20+
21+
import java.net.MalformedURLException;
22+
import java.net.URL;
23+
import java.util.ArrayList;
24+
import java.util.Collections;
25+
import java.util.List;
26+
import java.util.concurrent.CompletableFuture;
27+
import java.util.concurrent.CompletionException;
28+
import java.util.concurrent.atomic.AtomicBoolean;
29+
30+
public final class UpdateCheckerImpl {
31+
private static final AtomicBoolean jsonLibraryLoaded = new AtomicBoolean(false);
32+
33+
public static List<IChatComponent> updateListToChatMessages(String initiator, List<ModUpdateInfo> updates) {
34+
if (updates == null || updates.size() == 0) {
35+
return null;
36+
}
37+
val updateText = new ArrayList<IChatComponent>(
38+
FormattedText.parse(I18n.format("falsepatternlib.chat.updatesavailable", initiator)).toChatText());
39+
val mods = Loader.instance().getIndexedModList();
40+
for (val update : updates) {
41+
val mod = mods.get(update.modID);
42+
updateText.addAll(
43+
FormattedText.parse(I18n.format("falsepatternlib.chat.modname", mod.getName())).toChatText());
44+
updateText.addAll(
45+
FormattedText.parse(I18n.format("falsepatternlib.chat.currentversion", update.currentVersion))
46+
.toChatText());
47+
updateText.addAll(
48+
FormattedText.parse(I18n.format("falsepatternlib.chat.latestversion", update.latestVersion))
49+
.toChatText());
50+
if (!update.updateURL.isEmpty()) {
51+
val pre = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurlpre")).toChatText();
52+
val link = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurl")).toChatText();
53+
val post = FormattedText.parse(I18n.format("falsepatternlib.chat.updateurlpost")).toChatText();
54+
pre.get(pre.size() - 1).appendSibling(link.get(0));
55+
link.get(link.size() - 1).appendSibling(post.get(0));
56+
for (val l : link) {
57+
l.getChatStyle().setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, update.updateURL));
58+
}
59+
link.remove(0);
60+
post.remove(0);
61+
updateText.addAll(pre);
62+
updateText.addAll(link);
63+
updateText.addAll(post);
64+
}
65+
}
66+
return updateText;
67+
}
68+
69+
public static CompletableFuture<List<ModUpdateInfo>> fetchUpdatesAsync(String url) {
70+
return CompletableFuture.supplyAsync(() -> {
71+
if (!LibraryConfig.ENABLE_UPDATE_CHECKER) {
72+
throw new CompletionException(new UpdateCheckException("Update checker is disabled in config!"));
73+
}
74+
URL URL;
75+
try {
76+
URL = new URL(url);
77+
} catch (MalformedURLException e) {
78+
throw new CompletionException(new UpdateCheckException("Invalid URL: " + url, e));
79+
}
80+
if (!jsonLibraryLoaded.get()) {
81+
try {
82+
DependencyLoader.addMavenRepo("https://maven.falsepattern.com/");
83+
DependencyLoader.loadLibraries(Library.builder()
84+
.loadingModId(Tags.MODID)
85+
.groupId("com.falsepattern")
86+
.artifactId("json")
87+
.minVersion(new SemanticVersion(0, 4, 0))
88+
.maxVersion(new SemanticVersion(0, Integer.MAX_VALUE, Integer.MAX_VALUE))
89+
.preferredVersion(new SemanticVersion(0, 4, 1))
90+
.build());
91+
} catch (Exception e) {
92+
throw new CompletionException(
93+
new UpdateCheckException("Failed to load json library for update checker!", e));
94+
}
95+
jsonLibraryLoaded.set(true);
96+
}
97+
val result = new ArrayList<ModUpdateInfo>();
98+
JsonNode parsed;
99+
try {
100+
parsed = JsonNode.parse(Internet.download(URL).thenApply(String::new).join());
101+
} catch (CompletionException e) {
102+
throw new CompletionException(new UpdateCheckException("Failed to download update checker JSON file!",
103+
e.getCause() == null ? e : e.getCause()));
104+
}
105+
List<JsonNode> modList;
106+
if (parsed.isList()) {
107+
modList = parsed.getJavaList();
108+
} else {
109+
modList = Collections.singletonList(parsed);
110+
}
111+
val installedMods = Loader.instance().getIndexedModList();
112+
for (val node : modList) {
113+
if (!node.isObject()) {
114+
continue;
115+
}
116+
if (!node.containsKey("modid")) {
117+
continue;
118+
}
119+
if (!node.containsKey("latestVersion")) {
120+
continue;
121+
}
122+
val modid = node.getString("modid");
123+
if (!installedMods.containsKey(modid)) {
124+
continue;
125+
}
126+
val mod = installedMods.get(modid);
127+
val latestVersionsNode = node.get("latestVersion");
128+
List<String> latestVersions;
129+
if (latestVersionsNode.isString()) {
130+
latestVersions = Collections.singletonList(latestVersionsNode.stringValue());
131+
} else if (latestVersionsNode.isList()) {
132+
latestVersions = new ArrayList<>();
133+
for (val version : latestVersionsNode.getJavaList()) {
134+
if (!version.isString()) {
135+
continue;
136+
}
137+
latestVersions.add(version.stringValue());
138+
}
139+
} else {
140+
continue;
141+
}
142+
val currentVersion = mod.getVersion();
143+
if (latestVersions.contains(currentVersion)) {
144+
continue;
145+
}
146+
val updateURL =
147+
node.containsKey("updateURL") && node.get("updateURL").isString() ? node.getString("updateURL")
148+
: "";
149+
result.add(new ModUpdateInfo(modid, currentVersion, latestVersions.get(0), updateURL));
150+
}
151+
return result;
152+
});
153+
}
154+
155+
public static List<ModUpdateInfo> fetchUpdates(String url) throws UpdateCheckException {
156+
try {
157+
return fetchUpdatesAsync(url).join();
158+
} catch (CompletionException e) {
159+
try {
160+
throw e.getCause();
161+
} catch (UpdateCheckException e1) {
162+
throw e1;
163+
} catch (Throwable e1) {
164+
throw new UpdateCheckException("Failed to check for updates!", e1);
165+
}
166+
}
167+
}
168+
}

0 commit comments

Comments
 (0)