Skip to content

Commit c378385

Browse files
committed
Add custom natives support, go back to G1GC and disable tiered compilation for startup lag reduction
1 parent 72a9271 commit c378385

File tree

3 files changed

+124
-23
lines changed

3 files changed

+124
-23
lines changed

src/main/java/pojlib/API.java

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import pojlib.account.MinecraftAccount;
1515
import pojlib.util.FileUtil;
16+
import pojlib.util.GsonUtils;
1617
import pojlib.util.JREUtils;
1718
import pojlib.util.Logger;
1819
import pojlib.util.download.DownloadManager;
@@ -24,6 +25,13 @@
2425
import java.io.IOException;
2526
import java.net.HttpURLConnection;
2627
import java.net.URL;
28+
import java.nio.file.FileVisitResult;
29+
import java.nio.file.FileVisitor;
30+
import java.nio.file.Files;
31+
import java.nio.file.Path;
32+
import java.nio.file.Paths;
33+
import java.nio.file.attribute.BasicFileAttributes;
34+
import java.util.ArrayList;
2735

2836
/**
2937
* This class is the only class used by the launcher to communicate and talk to pojlib. This keeps pojlib and launcher separate.
@@ -314,4 +322,91 @@ public static boolean hasConnection(Context activity) {
314322
return false;
315323
}
316324
}
325+
326+
public static void mirrorNativesInFolder(Context activity, MinecraftInstances instances, MinecraftInstances.Instance instance, String path) {
327+
try {
328+
Files.createDirectories(activity.getDataDir().toPath().resolve(instance.instanceName));
329+
removeNatives(activity, instances, instance);
330+
331+
Files.walkFileTree(Paths.get(path), new FileVisitor<Path>() {
332+
@Override
333+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
334+
return FileVisitResult.CONTINUE;
335+
}
336+
337+
@Override
338+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
339+
installNative(activity, instances, instance, file.toString());
340+
return FileVisitResult.CONTINUE;
341+
}
342+
343+
@Override
344+
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
345+
return FileVisitResult.CONTINUE;
346+
}
347+
348+
@Override
349+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
350+
Files.delete(dir);
351+
return FileVisitResult.CONTINUE;
352+
}
353+
});
354+
} catch (IOException e) {
355+
Logger.getInstance().appendToLog("ERROR! Failed to bulk install natives from path: " + path);
356+
}
357+
}
358+
359+
public static void installNative(Context activity, MinecraftInstances instances, MinecraftInstances.Instance instance, String nativePath) {
360+
try {
361+
Files.createDirectories(activity.getDataDir().toPath().resolve(instance.instanceName));
362+
String[] splitPath = nativePath.split("/");
363+
String name = splitPath[splitPath.length - 1];
364+
Path out = activity.getDataDir().toPath().resolve(instance.instanceName).resolve(name);
365+
366+
Files.copy(Paths.get(nativePath), out);
367+
if(instance.extraNatives == null || instance.extraNatives.isEmpty()) {
368+
instance.extraNatives = out.toString();
369+
} else {
370+
instance.extraNatives += File.pathSeparator + out.toString();
371+
}
372+
373+
GsonUtils.objectToJsonFile(Constants.USER_HOME + "/instances.json", instances);
374+
} catch (IOException e) {
375+
Logger.getInstance().appendToLog("ERROR! Failed to install native from path: " + nativePath);
376+
}
377+
}
378+
379+
public static void removeNatives(Context activity, MinecraftInstances instances, MinecraftInstances.Instance instance) {
380+
try {
381+
Path out = activity.getDataDir().toPath().resolve(instance.instanceName);
382+
Files.walkFileTree(out, new FileVisitor<Path>() {
383+
@Override
384+
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
385+
return FileVisitResult.CONTINUE;
386+
}
387+
388+
@Override
389+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
390+
Files.delete(file);
391+
return FileVisitResult.CONTINUE;
392+
}
393+
394+
@Override
395+
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
396+
return FileVisitResult.CONTINUE;
397+
}
398+
399+
@Override
400+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
401+
Files.delete(dir);
402+
return FileVisitResult.CONTINUE;
403+
}
404+
});
405+
instance.extraNatives = "";
406+
407+
GsonUtils.objectToJsonFile(Constants.USER_HOME + "/instances.json", instances);
408+
} catch (IOException e) {
409+
Logger.getInstance().appendToLog("ERROR! Failed to delete natives by folder");
410+
}
411+
}
317412
}

src/main/java/pojlib/util/JREUtils.java

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ public class JREUtils {
3636
private JREUtils() {}
3737

3838
public static String LD_LIBRARY_PATH;
39-
public static Map<String, String> jreReleaseList;
40-
public static String instanceHome;
4139
public static String jvmLibraryPath;
4240
private static String sNativeLibDir;
4341
private static String runtimeDir;
@@ -62,21 +60,6 @@ public static String findInLdLibPath(String libName) {
6260
return libName;
6361
}
6462

65-
public static ArrayList<File> locateLibs(File path) {
66-
ArrayList<File> returnValue = new ArrayList<>();
67-
File[] list = path.listFiles();
68-
if(list != null) {
69-
for(File f : list) {
70-
if(f.isFile() && f.getName().endsWith(".so")) {
71-
returnValue.add(f);
72-
}else if(f.isDirectory()) {
73-
returnValue.addAll(locateLibs(f));
74-
}
75-
}
76-
}
77-
return returnValue;
78-
}
79-
8063
public static boolean initJavaRuntime() {
8164
dlopen(findInLdLibPath("server/libjvm.so"));
8265
dlopen(findInLdLibPath("libverify.so"));
@@ -98,6 +81,24 @@ public static boolean initJavaRuntime() {
9881
return true;
9982
}
10083

84+
public static boolean initializeExtraNatives(MinecraftInstances.Instance instance) {
85+
if(instance.extraNatives == null) {
86+
return false;
87+
}
88+
89+
for(String nativeLib : instance.extraNatives.split(File.pathSeparator)) {
90+
dlopen(nativeLib);
91+
}
92+
93+
String dlerr = dlerror();
94+
if(dlerr.contains(runtimeDir)) {
95+
Logger.getInstance().appendToLog("ERROR! Could not dlopen extra natives! " + dlerr);
96+
return false;
97+
}
98+
99+
return true;
100+
}
101+
101102
public static void redirectAndPrintJRELog() {
102103
Log.v("jrelog","Log starts here");
103104
JREUtils.logToLogger(Logger.getInstance());
@@ -140,11 +141,11 @@ public void run() {
140141
Log.i("jrelog-logcat","Logcat thread started");
141142
}
142143

143-
public static void relocateLibPath(final Context ctx) {
144+
public static void relocateLibPath(final Context ctx, MinecraftInstances.Instance instance) {
144145
sNativeLibDir = ctx.getApplicationInfo().nativeLibraryDir;
145146

146147
LD_LIBRARY_PATH = ctx.getFilesDir() + "/runtimes/JRE/bin:" + ctx.getFilesDir() + "/runtimes/JRE/lib:" +
147-
"/system/lib64:/vendor/lib64:/vendor/lib64/hw:" +
148+
"/system/lib64:/vendor/lib64:/vendor/lib64/hw:" + ctx.getDataDir().toPath().resolve(instance.instanceName) + ":" +
148149
sNativeLibDir;
149150
}
150151

@@ -192,7 +193,7 @@ public static void setJavaEnvironment(Activity activity, MinecraftInstances.Inst
192193
// Called before game launch to ensure all files are present and correct
193194
public static boolean prelaunchCheck(Activity activity, MinecraftInstances.Instance instance) throws Throwable {
194195
runtimeDir = activity.getFilesDir() + "/runtimes/JRE";
195-
JREUtils.relocateLibPath(activity);
196+
JREUtils.relocateLibPath(activity, instance);
196197
setJavaEnvironment(activity, instance);
197198

198199
UnityPlayerActivity.installLWJGL(activity);
@@ -215,7 +216,7 @@ public static int launchJavaVM(final Activity activity, final List<String> JVMAr
215216

216217
//Add automatically generated args
217218
if (API.customRAMValue) {
218-
Logger.getInstance().appendToLog("QuestCraft: Setting JVM memory to " + API.memoryValue + "MB (Custom)");
219+
Logger.getInstance().appendToLog("etting JVM memory to " + API.memoryValue + "MB (Custom)");
219220
userArgs.add("-Xms" + API.memoryValue + "M");
220221
userArgs.add("-Xmx" + API.memoryValue + "M");
221222
} else {
@@ -225,18 +226,22 @@ public static int launchJavaVM(final Activity activity, final List<String> JVMAr
225226
long availMem = (ami.availMem-ami.threshold)/(1024*1024);
226227
long allocatedRam = Math.max(availMem, 1536);
227228

228-
Logger.getInstance().appendToLog("QuestCraft: Setting JVM memory to " + allocatedRam + "MB");
229+
Logger.getInstance().appendToLog("Setting JVM memory to " + allocatedRam + "MB");
229230

230231
userArgs.add("-Xms" + 1024 + "M");
231232
userArgs.add("-Xmx" + allocatedRam + "M");
232233
}
233234

235+
if(!initializeExtraNatives(instance)) {
236+
Logger.getInstance().appendToLog("Some libraries did not dlopen properly. This can be safely ignored in most cases.");
237+
}
234238

235239
// Garbage collection
236-
userArgs.add("-XX:+UseShenandoahGC");
240+
userArgs.add("-XX:+UseG1GC");
237241
userArgs.add("-XX:+UnlockDiagnosticVMOptions");
238242

239243
userArgs.add("-XX:+UnlockExperimentalVMOptions");
244+
userArgs.add("-XX:-TieredCompilation");
240245

241246
// Android sig fix
242247
userArgs.add("-XX:+UseSignalChaining");

src/main/java/pojlib/util/json/MinecraftInstances.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public static class Instance {
7575
public String assetIndex;
7676
public String assetsDir;
7777
public String mainClass;
78+
public String extraNatives;
7879
public ProjectInfo[] extProjects;
7980
public boolean defaultMods;
8081

0 commit comments

Comments
 (0)