Skip to content

Commit c03f221

Browse files
committed
deploader v2
1 parent cbef970 commit c03f221

File tree

8 files changed

+128
-27
lines changed

8 files changed

+128
-27
lines changed

src/main/java/com/falsepattern/lib/internal/Share.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
package com.falsepattern.lib.internal;
2424

25+
import com.falsepattern.lib.internal.asm.PreShare;
2526
import lombok.AccessLevel;
2627
import lombok.NoArgsConstructor;
2728
import lombok.val;
@@ -32,16 +33,7 @@
3233

3334
@NoArgsConstructor(access = AccessLevel.PRIVATE)
3435
public final class Share {
35-
public static final boolean DEV_ENV;
36-
37-
static {
38-
try {
39-
val bs = Launch.classLoader.getClassBytes("net.minecraft.world.World");
40-
DEV_ENV = bs != null;
41-
} catch (IOException e) {
42-
throw new RuntimeException(e);
43-
}
44-
}
36+
public static final boolean DEV_ENV = PreShare.devEnv();
4537

4638
public static boolean EARLY_INIT_DONE = false;
4739
}

src/main/java/com/falsepattern/lib/internal/asm/CoreLoadingPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class CoreLoadingPlugin implements IFMLLoadingPlugin {
5656
private static boolean obfuscated;
5757

5858
static {
59+
PreShare.initDevState(Launch.classLoader.findResource("net/minecraft/world/World.class") != null);
5960
LetsEncryptHelper.replaceSSLContext();
6061
FPLog.LOG.info("Removing skill issues...");
6162
try {
@@ -67,7 +68,7 @@ public class CoreLoadingPlugin implements IFMLLoadingPlugin {
6768
//Scan for dependencies now
6869
FPLog.LOG.info("Scanning for deps...");
6970
long start = System.nanoTime();
70-
DependencyLoaderImpl.executeDependencyLoading(true);
71+
DependencyLoaderImpl.executeDependencyLoading();
7172
long end = System.nanoTime();
7273
FPLog.LOG.info("Scanned in " + (end - start) / 1000000 + "ms");
7374
//Initializing the rest
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* This file is part of FalsePatternLib.
3+
*
4+
* Copyright (C) 2022-2025 FalsePattern
5+
* All Rights Reserved
6+
*
7+
* The above copyright notice and this permission notice shall be included
8+
* in all copies or substantial portions of the Software.
9+
*
10+
* FalsePatternLib is free software: you can redistribute it and/or modify
11+
* it under the terms of the GNU Lesser General Public License as published by
12+
* the Free Software Foundation, only version 3 of the License.
13+
*
14+
* FalsePatternLib is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* GNU Lesser General Public License for more details.
18+
*
19+
* You should have received a copy of the GNU Lesser General Public License
20+
* along with FalsePatternLib. If not, see <https://www.gnu.org/licenses/>.
21+
*/
22+
23+
package com.falsepattern.lib.internal.asm;
24+
25+
import lombok.Getter;
26+
27+
public class PreShare {
28+
private static volatile boolean devEnv = false;
29+
private static volatile boolean inited = false;
30+
public static synchronized void initDevState(boolean state) {
31+
if (inited) {
32+
return;
33+
}
34+
inited = true;
35+
devEnv = state;
36+
}
37+
38+
public static synchronized boolean devEnv() {
39+
return devEnv;
40+
}
41+
}

src/main/java/com/falsepattern/lib/internal/asm/RFBLoadingPlugin.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,31 @@
2525
import com.falsepattern.lib.internal.core.LowLevelCallMultiplexer;
2626
import com.falsepattern.lib.internal.impl.dependencies.DependencyLoaderImpl;
2727
import com.falsepattern.lib.internal.impl.dependencies.LetsEncryptHelper;
28+
import com.gtnewhorizons.retrofuturabootstrap.RfbApiImpl;
2829
import com.gtnewhorizons.retrofuturabootstrap.api.RfbPlugin;
30+
import lombok.val;
31+
32+
import java.net.URLClassLoader;
2933

3034
public class RFBLoadingPlugin implements RfbPlugin {
3135
static {
36+
val loader = RfbApiImpl.INSTANCE.launchClassLoader();
37+
try {
38+
val exc = loader.getClass()
39+
.getDeclaredMethod("addClassLoaderExclusion", String.class);
40+
exc.invoke(loader, "com.falsepattern.lib.dependencies.");
41+
exc.invoke(loader, "com.falsepattern.lib.internal.impl.dependencies.");
42+
exc.invoke(loader, "com.falsepattern.lib.internal.Internet");
43+
exc.invoke(loader, "com.falsepattern.lib.internal.Share");
44+
exc.invoke(loader, "com.falsepattern.lib.internal.asm.PreShare");
45+
exc.invoke(loader, "com.falsepattern.lib.internal.FPLog");
46+
exc.invoke(loader, "com.falsepattern.lib.internal.Tags");
47+
exc.invoke(loader, "com.falsepattern.lib.internal.config.EarlyConfig");
48+
exc.invoke(loader, "com.falsepattern.lib.internal.core.LowLevelCallMultiplexer");
49+
} catch (Exception ignored) {}
50+
PreShare.initDevState(((URLClassLoader)loader).findResource("net/minecraft/world/World.class") != null);
3251
LetsEncryptHelper.replaceSSLContext();
3352
LowLevelCallMultiplexer.rfbDetected();
34-
DependencyLoaderImpl.executeDependencyLoading(false);
53+
DependencyLoaderImpl.executeDependencyLoading();
3554
}
3655
}

src/main/java/com/falsepattern/lib/internal/core/LowLevelCallMultiplexer.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
import net.minecraft.launchwrapper.Launch;
3030

3131
import java.net.URL;
32+
import java.net.URLClassLoader;
3233
import java.nio.file.Path;
3334
import java.nio.file.Paths;
35+
import java.util.Arrays;
3436
import java.util.List;
3537

3638
@UtilityClass
@@ -64,21 +66,32 @@ public static List<URL> getClassPathSources() {
6466
}
6567
}
6668

69+
public static int javaMajorVersion() {
70+
if (rfbDetected) {
71+
return RFBLowLevel.javaMajorVersion();
72+
} else {
73+
return LaunchWrapperLowLevel.javaMajorVersion();
74+
}
75+
}
76+
6777
//Separate classes to avoid accidental classloading
6878

69-
@SuppressWarnings("resource")
7079
private static class RFBLowLevel {
7180
static void addURLToClassPath(URL url) {
72-
RfbApiImpl.INSTANCE.compatClassLoader().addURL(url);
81+
RfbApiImpl.INSTANCE.launchClassLoader().addURL(url);
7382
}
7483

7584
static List<URL> getClassPathSources() {
76-
return RfbApiImpl.INSTANCE.compatClassLoader().getSources();
85+
return Arrays.asList(((URLClassLoader)RfbApiImpl.INSTANCE.launchClassLoader()).getURLs());
7786
}
7887

7988
static @NotNull Path gameDir() {
8089
return RfbApiImpl.INSTANCE.gameDirectory();
8190
}
91+
92+
static int javaMajorVersion() {
93+
return RfbApiImpl.INSTANCE.javaMajorVersion();
94+
}
8295
}
8396

8497
private static class LaunchWrapperLowLevel {
@@ -93,5 +106,16 @@ static List<URL> getClassPathSources() {
93106
static @NotNull Path gameDir() {
94107
return Launch.minecraftHome == null ? Paths.get(".") : Launch.minecraftHome.toPath();
95108
}
109+
110+
static int javaMajorVersion() {
111+
String version = System.getProperty("java.version");
112+
if(version.startsWith("1.")) {
113+
version = version.substring(2, 3);
114+
} else {
115+
int dot = version.indexOf(".");
116+
if(dot != -1) { version = version.substring(0, dot); }
117+
}
118+
return Integer.parseInt(version);
119+
}
96120
}
97121
}

src/main/java/com/falsepattern/lib/internal/impl/dependencies/DepRoot.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
public class DepRoot {
3434
private String source;
3535
@Expose
36+
private Integer minJava;
37+
@Expose
38+
private Integer maxJava;
39+
@Expose
3640
private List<String> repositories;
3741
@Expose
3842
private Dependencies dependencies;

src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,12 @@ private static void checkedDelete(Path file) {
225225
}
226226
}
227227

228-
private static synchronized void addToClasspath(Path file) {
228+
private static synchronized void addToClasspath(URL file) {
229229
try {
230-
LowLevelCallMultiplexer.addURLToClassPath(file.toUri().toURL());
230+
LowLevelCallMultiplexer.addURLToClassPath(file);
231231
LOG.debug("Injected file {} into classpath!", file);
232232
} catch (Exception e) {
233-
throw new RuntimeException("Failed to add library to classpath: " + file.toAbsolutePath(), e);
233+
throw new RuntimeException("Failed to add library to classpath: " + file, e);
234234
}
235235
}
236236

@@ -407,13 +407,13 @@ private static Stream<Pair<ScopeSide, String>> sidedDependency(DependencySide si
407407
private static boolean initialScan = false;
408408
private static List<Pair<ScopeSide, DependencyLoadTask>> tasks;
409409

410-
public static void executeDependencyLoading(boolean sideAware) {
410+
public static void executeDependencyLoading() {
411411
if (!initialScan) {
412412
initialScan = true;
413413
scanDeps();
414414
}
415415

416-
executeArtifactLoading(sideAware);
416+
executeArtifactLoading();
417417
}
418418

419419
private static void scanDeps() {
@@ -450,6 +450,7 @@ private static void scanDeps() {
450450
} catch (IOException e) {
451451
LOG.error("Could not write dependency scanner cache", e);
452452
}
453+
val javaVersion = LowLevelCallMultiplexer.javaMajorVersion();
453454
val dependencySpecs = urls.stream().map((source) -> {
454455
//Convert source to GSON json
455456
try (val is = new BufferedInputStream(source.openStream())) {
@@ -468,6 +469,11 @@ private static void scanDeps() {
468469
val gson = builder.create();
469470
json.remove("identifier");
470471
val root = gson.fromJson(json, DepRoot.class);
472+
val minJ = root.minJava();
473+
val maxJ = root.maxJava();
474+
if (minJ != null && minJ > javaVersion || maxJ != null && maxJ < javaVersion) {
475+
return null;
476+
}
471477
root.source(source.toString());
472478
return root;
473479
} catch (Exception e) {
@@ -562,8 +568,8 @@ static ScopeSide current() {
562568
}
563569
}
564570

565-
private static void executeArtifactLoading(boolean sideAware) {
566-
val scopeSide = sideAware ? SideAwareAssistant.current() : new ScopeSide(DependencyScope.ALWAYS, DependencySide.COMMON);
571+
private static void executeArtifactLoading() {
572+
val scopeSide = SideAwareAssistant.current();
567573
val iter = tasks.iterator();
568574
val artifactMap = new HashMap<String, DependencyLoadTask>();
569575
while (iter.hasNext()) {
@@ -621,7 +627,6 @@ private static void executeArtifactLoading(boolean sideAware) {
621627
}
622628
jFrame.pack();
623629
jFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
624-
jFrame.setVisible(true);
625630
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
626631
jFrame.setLocation(dim.width/2-jFrame.getSize().width/2, dim.height/2-jFrame.getSize().height/2);
627632
} catch (Exception ignored) {
@@ -667,7 +672,14 @@ private static void executeArtifactLoading(boolean sideAware) {
667672
@NotNull
668673
private static Thread getVizThread(AtomicBoolean doViz, HashMap<DependencyLoadTask, JProgressBar> progresses, JFrame theFrame) {
669674
val vizThread = new Thread(() -> {
675+
int waitBeforeShowing = 100;
670676
while (doViz.get()) {
677+
if (waitBeforeShowing > 0) {
678+
waitBeforeShowing--;
679+
} else if (waitBeforeShowing == 0) {
680+
theFrame.setVisible(true);
681+
waitBeforeShowing = -1;
682+
}
671683
for (val progress : progresses.entrySet()) {
672684
val task = progress.getKey();
673685
val bar = progress.getValue();
@@ -825,11 +837,11 @@ private boolean tryLoadingExistingFile() {
825837
return false;
826838
}
827839
try {
828-
addToClasspath(file);
840+
addToClasspath(file.toUri().toURL());
829841
loadedLibraries.put(artifact, preferredVersion);
830842
LOG.debug("Library {} successfully loaded from disk!", artifactLogName);
831843
return true;
832-
} catch (RuntimeException e) {
844+
} catch (Exception e) {
833845
LOG.warn("Failed to load library {} from file! Re-downloading...", artifactLogName);
834846
checkedDelete(file);
835847
return false;
@@ -912,7 +924,7 @@ private boolean tryDownloadFromMaven(String repo) {
912924
}
913925
loadedLibraries.put(artifact, preferredVersion);
914926
loadedLibraryMods.put(artifact, loadingModId);
915-
addToClasspath(file);
927+
addToClasspath(file.toUri().toURL());
916928
return true;
917929
}
918930
}

src/main/resources/DEPENDENCIES.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
FalsePatternLib JSON dependency file example
2-
Version 1
2+
Version 2
33

44
An example JSON file that can be used to download dependencies using FalsePatternLib. This replaces the legacy
55
DependencyLoader api. This file needs to reside inside the META-INF directory.
66

77
```json
88
{
99
"identifier": "falsepatternlib_dependencies",
10+
"minJava": 8,
11+
"maxJava": 8,
1012
"repositories": [
1113
"https://example.com/"
1214
],
@@ -37,6 +39,12 @@ Explanation:
3739
- `identifier`: The identifier of the json file. This must always be `falsepatternlib_dependencies` for the library
3840
downloader
3941
to recognize it.
42+
- `minJava`: The lowest java major version to load dependencies from this file for (inclusive). Can be omitted, in which case
43+
it will load dependencies for any java versions below or equal maxJava.
44+
- `maxJava`: The highest java major version to load dependencies from this file for (inclusive). If omitted, it will load dependencies
45+
for any java versions above or equal minJava.
46+
- If both `minJava` and `maxJava` are unset, dependencies from the file will be loaded regardless of java version.
47+
- If you want to load dependencies for multiple different java ranges, use multiple dependency jsons.
4048
- `repositories`: A list of maven repositories to use when downloading dependencies. These are used in addition to the
4149
default maven repositories. This is just a list of strings, each string being a https repository url.
4250
Additionally, every jar with a dependencies json file inside of it is treated as a "jar in jar" maven repository.

0 commit comments

Comments
 (0)