mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-15 07:39:00 -04:00
Robust downloadString() cache
This commit is contained in:
parent
63dec3fb2a
commit
c0aec8178b
@ -85,9 +85,9 @@ public final class Tools {
|
||||
public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
public static final String URL_HOME = "https://pojavlauncherteam.github.io";
|
||||
|
||||
public static String NATIVE_LIB_DIR;
|
||||
public static String DIR_DATA; //Initialized later to get context
|
||||
public static File DIR_CACHE;
|
||||
public static String MULTIRT_HOME;
|
||||
public static String LOCAL_RENDERER = null;
|
||||
public static int DEVICE_ARCHITECTURE;
|
||||
@ -139,6 +139,7 @@ public final class Tools {
|
||||
* Any value (in)directly dependant on DIR_DATA should be set only here.
|
||||
*/
|
||||
public static void initContextConstants(Context ctx){
|
||||
DIR_CACHE = ctx.getCacheDir();
|
||||
DIR_DATA = ctx.getFilesDir().getParent();
|
||||
MULTIRT_HOME = DIR_DATA+"/runtimes";
|
||||
DIR_GAME_HOME = getPojavStorageRoot(ctx).getAbsolutePath();
|
||||
@ -897,7 +898,7 @@ public final class Tools {
|
||||
sExecutorService.execute(() -> {
|
||||
try {
|
||||
final String name = getFileName(activity, uri);
|
||||
final File modInstallerFile = new File(activity.getCacheDir(), name);
|
||||
final File modInstallerFile = new File(Tools.DIR_CACHE, name);
|
||||
FileOutputStream fos = new FileOutputStream(modInstallerFile);
|
||||
InputStream input = activity.getContentResolver().openInputStream(uri);
|
||||
IOUtils.copy(input, fos);
|
||||
|
@ -48,7 +48,7 @@ public class FabricInstallFragment extends Fragment implements AdapterView.OnIte
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
this.mDestinationDir = new File(context.getCacheDir(), "fabric-installer");
|
||||
this.mDestinationDir = new File(Tools.DIR_CACHE, "fabric-installer");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +42,7 @@ public class ForgeInstallFragment extends Fragment implements Runnable, View.OnC
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
this.mInflater = LayoutInflater.from(context);
|
||||
this.mDestinationFile = new File(context.getCacheDir(), "forge-installer.jar");
|
||||
this.mDestinationFile = new File(Tools.DIR_CACHE, "forge-installer.jar");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,21 +18,46 @@ public class FabricUtils {
|
||||
private static final String FABRIC_INSTALLER_METADATA_URL = "https://meta.fabricmc.net/v2/versions/installer";
|
||||
private static final String FABRIC_LOADER_METADATA_URL = "https://meta.fabricmc.net/v2/versions/loader";
|
||||
public static List<String> downloadLoaderVersionList(boolean onlyStable) throws IOException {
|
||||
String loaderMetadata = DownloadUtils.downloadString(FABRIC_LOADER_METADATA_URL);
|
||||
List<String> loaderList = new ArrayList<>();
|
||||
if(enumerateMetadata(loaderMetadata, (object)->{
|
||||
if(onlyStable && !object.getBoolean("stable")) return false;
|
||||
loaderList.add(object.getString("version"));
|
||||
return false;
|
||||
}) == null) return null;
|
||||
return loaderList;
|
||||
try {
|
||||
return DownloadUtils.downloadStringCached(FABRIC_LOADER_METADATA_URL,
|
||||
"fabric_loader_versions", (input)->{
|
||||
final List<String> loaderList = new ArrayList<>();
|
||||
try {
|
||||
enumerateMetadata(input, (object) -> {
|
||||
if (onlyStable && !object.getBoolean("stable")) return false;
|
||||
loaderList.add(object.getString("version"));
|
||||
return false;
|
||||
});
|
||||
}catch (JSONException e) {
|
||||
throw new DownloadUtils.ParseException(e);
|
||||
}
|
||||
return loaderList;
|
||||
});
|
||||
}catch (DownloadUtils.ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getInstallerUrlAndVersion() throws IOException{
|
||||
String installerMetadata = DownloadUtils.downloadString(FABRIC_INSTALLER_METADATA_URL);
|
||||
JSONObject selectedMetadata = enumerateMetadata(installerMetadata, (object)-> object.getBoolean("stable"));
|
||||
if(selectedMetadata == null) return null;
|
||||
return new String[] {selectedMetadata.optString("url"), selectedMetadata.optString("version")};
|
||||
try {
|
||||
return DownloadUtils.downloadStringCached(FABRIC_INSTALLER_METADATA_URL,
|
||||
"fabric_installer_versions", input -> {
|
||||
try {
|
||||
JSONObject selectedMetadata = enumerateMetadata(installerMetadata, (object) ->
|
||||
object.getBoolean("stable"));
|
||||
if (selectedMetadata == null) return null;
|
||||
return new String[]{selectedMetadata.getString("url"),
|
||||
selectedMetadata.getString("version")};
|
||||
} catch (JSONException e) {
|
||||
throw new DownloadUtils.ParseException(e);
|
||||
}
|
||||
});
|
||||
}catch (DownloadUtils.ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void addAutoInstallArgs(Intent intent, File modInstalllerJar,
|
||||
@ -46,8 +71,7 @@ public class FabricUtils {
|
||||
|
||||
}
|
||||
|
||||
private static JSONObject enumerateMetadata(String inputMetadata, FabricMetaReader metaReader) {
|
||||
try {
|
||||
private static JSONObject enumerateMetadata(String inputMetadata, FabricMetaReader metaReader) throws JSONException{
|
||||
JSONArray fullMetadata = new JSONArray(inputMetadata);
|
||||
JSONObject metadataObject = null;
|
||||
for(int i = 0; i < fullMetadata.length(); i++) {
|
||||
@ -55,9 +79,5 @@ public class FabricUtils {
|
||||
if(metaReader.processMetadata(metadataObject)) return metadataObject;
|
||||
}
|
||||
return metadataObject;
|
||||
}catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,17 +21,32 @@ public class ForgeUtils {
|
||||
private static final String FORGE_METADATA_URL = "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml";
|
||||
private static final String FORGE_INSTALLER_URL = "https://maven.minecraftforge.net/net/minecraftforge/forge/%1$s/forge-%1$s-installer.jar";
|
||||
public static List<String> downloadForgeVersions() throws IOException {
|
||||
String forgeMetadata = DownloadUtils.downloadString(FORGE_METADATA_URL);
|
||||
SAXParser saxParser;
|
||||
try {
|
||||
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
|
||||
SAXParser parser = parserFactory.newSAXParser();
|
||||
ForgeVersionListHandler handler = new ForgeVersionListHandler();
|
||||
parser.parse(new InputSource(new StringReader(forgeMetadata)), handler);
|
||||
return handler.getVersions();
|
||||
saxParser = parserFactory.newSAXParser();
|
||||
}catch (SAXException | ParserConfigurationException e) {
|
||||
e.printStackTrace();
|
||||
// if we cant make a parser we might as well not even try to parse anything
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return DownloadUtils.downloadStringCached(FORGE_METADATA_URL, "forge_versions", input -> {
|
||||
try {
|
||||
ForgeVersionListHandler handler = new ForgeVersionListHandler();
|
||||
saxParser.parse(new InputSource(new StringReader(input)), handler);
|
||||
return handler.getVersions();
|
||||
// IOException is present here StringReader throws it only if the parser called close()
|
||||
// sooner than needed, which is a parser issue and not an I/O one
|
||||
}catch (SAXException | IOException e) {
|
||||
throw new DownloadUtils.ParseException(e);
|
||||
}
|
||||
});
|
||||
}catch (DownloadUtils.ParseException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
public static String getInstallerUrl(String version) {
|
||||
return String.format(FORGE_INSTALLER_URL, version);
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.kdt.pojavlaunch.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
@ -115,6 +117,46 @@ public class DownloadUtils {
|
||||
conn.disconnect();
|
||||
}
|
||||
|
||||
public static <T> T downloadStringCached(String url, String cacheName, ParseCallback<T> parseCallback) throws IOException, ParseException{
|
||||
File cacheDestination = new File(Tools.DIR_CACHE, "string_cache/"+cacheName);
|
||||
File cacheDestinationDir = cacheDestination.getParentFile();
|
||||
if(cacheDestinationDir != null &&
|
||||
!cacheDestinationDir.exists() &&
|
||||
!cacheDestinationDir.mkdirs()) throw new IOException("Failed to create the cache directory");
|
||||
if(cacheDestination.isFile() &&
|
||||
cacheDestination.canRead() &&
|
||||
System.currentTimeMillis() < (cacheDestination.lastModified() + 86400000)) {
|
||||
try {
|
||||
String cachedString = Tools.read(new FileInputStream(cacheDestination));
|
||||
return parseCallback.process(cachedString);
|
||||
}catch(IOException e) {
|
||||
Log.i("DownloadUtils", "Failed to read the cached file", e);
|
||||
}catch (ParseException e) {
|
||||
Log.i("DownloadUtils", "Failed to parse the cached file", e);
|
||||
}
|
||||
}
|
||||
String urlContent = DownloadUtils.downloadString(url);
|
||||
// if we download the file and fail parsing it, we will yeet outta there
|
||||
// and not cache the unparseable sting. We will return this after trying to save the downloaded
|
||||
// string into cache
|
||||
T parseResult = parseCallback.process(urlContent);
|
||||
|
||||
boolean tryWriteCache = false;
|
||||
if(cacheDestination.exists()) {
|
||||
tryWriteCache = cacheDestination.canWrite();
|
||||
} else {
|
||||
// if it is null, then cacheDestination is the file system root. Very bad.
|
||||
// but let's shield ourselves and just never try to cache the file if that happens
|
||||
if(cacheDestinationDir != null && !cacheDestinationDir.isFile()) tryWriteCache = cacheDestinationDir.canWrite();
|
||||
}
|
||||
if(tryWriteCache) try {
|
||||
Tools.write(cacheDestination.getAbsolutePath(), urlContent);
|
||||
}catch(IOException e) {
|
||||
Log.i("DownloadUtils", "Failed to cache the string", e);
|
||||
}
|
||||
return parseResult;
|
||||
}
|
||||
|
||||
public static void downloadFileMonitoredWithHeaders(String urlInput,File outputFile, @Nullable byte[] buffer,
|
||||
Tools.DownloaderFeedback monitor, String userAgent, String cookies) throws IOException {
|
||||
if (!outputFile.exists()) {
|
||||
@ -141,5 +183,13 @@ public class DownloadUtils {
|
||||
conn.disconnect();
|
||||
}
|
||||
|
||||
public interface ParseCallback<T> {
|
||||
T process(String input) throws ParseException;
|
||||
}
|
||||
public static class ParseException extends Exception {
|
||||
public ParseException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ public class JREUtils {
|
||||
envMap.put("POJAV_NATIVEDIR", NATIVE_LIB_DIR);
|
||||
envMap.put("JAVA_HOME", jreHome);
|
||||
envMap.put("HOME", Tools.DIR_GAME_HOME);
|
||||
envMap.put("TMPDIR", activity.getCacheDir().getAbsolutePath());
|
||||
envMap.put("TMPDIR", Tools.DIR_CACHE.getAbsolutePath());
|
||||
envMap.put("LIBGL_MIPMAP", "3");
|
||||
|
||||
// On certain GLES drivers, overloading default functions shader hack fails, so disable it
|
||||
@ -191,7 +191,7 @@ public class JREUtils {
|
||||
|
||||
envMap.put("FORCE_VSYNC", String.valueOf(LauncherPreferences.PREF_FORCE_VSYNC));
|
||||
|
||||
envMap.put("MESA_GLSL_CACHE_DIR", activity.getCacheDir().getAbsolutePath());
|
||||
envMap.put("MESA_GLSL_CACHE_DIR", Tools.DIR_CACHE.getAbsolutePath());
|
||||
if (LOCAL_RENDERER != null) {
|
||||
envMap.put("MESA_GL_VERSION_OVERRIDE", LOCAL_RENDERER.equals("opengles3_virgl")?"4.3":"4.6");
|
||||
envMap.put("MESA_GLSL_VERSION_OVERRIDE", LOCAL_RENDERER.equals("opengles3_virgl")?"430":"460");
|
||||
@ -200,7 +200,7 @@ public class JREUtils {
|
||||
envMap.put("allow_higher_compat_version", "true");
|
||||
envMap.put("allow_glsl_extension_directive_midshader", "true");
|
||||
envMap.put("MESA_LOADER_DRIVER_OVERRIDE", "zink");
|
||||
envMap.put("VTEST_SOCKET_NAME", activity.getCacheDir().getAbsolutePath() + "/.virgl_test");
|
||||
envMap.put("VTEST_SOCKET_NAME", new File(Tools.DIR_CACHE, ".virgl_test").getAbsolutePath());
|
||||
|
||||
envMap.put("LD_LIBRARY_PATH", LD_LIBRARY_PATH);
|
||||
envMap.put("PATH", jreHome + "/bin:" + Os.getenv("PATH"));
|
||||
@ -328,7 +328,7 @@ public class JREUtils {
|
||||
|
||||
ArrayList<String> overridableArguments = new ArrayList<>(Arrays.asList(
|
||||
"-Djava.home=" + runtimeHome,
|
||||
"-Djava.io.tmpdir=" + ctx.getCacheDir().getAbsolutePath(),
|
||||
"-Djava.io.tmpdir=" + Tools.DIR_CACHE.getAbsolutePath(),
|
||||
"-Duser.home=" + Tools.DIR_GAME_HOME,
|
||||
"-Duser.language=" + System.getProperty("user.language"),
|
||||
"-Dos.name=Linux",
|
||||
|
Loading…
x
Reference in New Issue
Block a user