[WIP] Disallow removal if there's only one runtime left, start adding MultiRT to Per-Version Config

This commit is contained in:
ArtDev 2021-07-15 10:48:06 +03:00
parent e93e83ceed
commit c57fe8300f
9 changed files with 220 additions and 29 deletions

View File

@ -22,6 +22,7 @@ public class JMinecraftVersionList {
public Map<String, MinecraftClientInfo> downloads;
public String id;
public String inheritsFrom;
public JavaVersionInfo javaVersion;
public DependentLibrary[] libraries;
public String mainClass;
public String minecraftArguments;
@ -33,7 +34,10 @@ public class JMinecraftVersionList {
public String url;
public String sha1;
}
public static class JavaVersionInfo {
public String component;
public int majorVersion;
}
// Since 1.13
public static class Arguments {
public Object[] game;

View File

@ -22,6 +22,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
public class MultiRTUtils {
public static HashMap<String,Runtime> cache = new HashMap<>();
@ -33,6 +34,18 @@ public class MultiRTUtils {
public String versionString;
public String arch;
public int javaVersion;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Runtime runtime = (Runtime) o;
return name.equals(runtime.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
public static interface ProgressReporterThingy {
void reportStringProgress(int resid, Object ... stuff);
@ -50,6 +63,21 @@ public class MultiRTUtils {
return ret;
}
public static String getNearestJREName(int majorVersion) {
List<Runtime> runtimes = getRuntimes();
int diff_factor = Integer.MAX_VALUE;
String result = null;
for(Runtime r : runtimes) {
if(r.javaVersion >= majorVersion) { // lower - not useful
int currentFactor = r.javaVersion - majorVersion;
if(diff_factor > currentFactor) {
result = r.name;
diff_factor = currentFactor;
}
}
}
return result;
}
public static void installRuntimeNamed(InputStream runtimeInputStream, String name, ProgressReporterThingy thingy) throws IOException {
File dest = new File(runtimeFolder,"/"+name);
File tmp = new File(dest,"temporary");
@ -138,7 +166,7 @@ public class MultiRTUtils {
Tools.DIR_HOME_JRE = dest.getAbsolutePath();
JREUtils.relocateLibPath(ctx);
}
private static Runtime read(String name) {
public static Runtime read(String name) {
if(cache.containsKey(name)) return cache.get(name);
Runtime retur;
File release = new File(runtimeFolder,"/"+name+"/release");

View File

@ -11,6 +11,7 @@ import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
import net.kdt.pojavlaunch.R;
@ -40,6 +41,11 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
public boolean isDefaultRuntime(MultiRTUtils.Runtime rt) {
return LauncherPreferences.PREF_DEFAULT_RUNTIME.equals(rt.name);
}
public void setDefault(MultiRTUtils.Runtime rt){
LauncherPreferences.PREF_DEFAULT_RUNTIME = rt.name;
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
@Override
public int getItemCount() {
return MultiRTUtils.getRuntimes().size();
@ -85,6 +91,15 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
public void onClick(View v) {
if(v.getId() == R.id.multirt_view_removebtn) {
if (currentRuntime != null) {
if(MultiRTUtils.getRuntimes().size() < 2) {
AlertDialog.Builder bldr = new AlertDialog.Builder(ctx);
bldr.setTitle(R.string.global_error);
bldr.setMessage(R.string.multirt_config_removeerror_last);
bldr.setPositiveButton(android.R.string.ok,(adapter, which)->adapter.dismiss());
bldr.show();
return;
}
final ProgressDialog barrier = new ProgressDialog(ctx);
barrier.setMessage(ctx.getString(R.string.global_waiting));
barrier.setProgressStyle(ProgressDialog.STYLE_SPINNER);
@ -97,8 +112,9 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
Tools.showError(itemView.getContext(), e);
}
v.post(() -> {
if(isDefaultRuntime(currentRuntime)) setDefault(MultiRTUtils.getRuntimes().get(0));
barrier.dismiss();
RTRecyclerViewAdapter.this.notifyItemRemoved(currentPosition);
RTRecyclerViewAdapter.this.notifyDataSetChanged();
dialog.dialog.show();
});
});
@ -106,11 +122,11 @@ public class RTRecyclerViewAdapter extends RecyclerView.Adapter<RTRecyclerViewAd
}
}else if(v.getId() == R.id.multirt_view_setdefaultbtn) {
if(currentRuntime != null) {
LauncherPreferences.PREF_DEFAULT_RUNTIME = currentRuntime.name;
LauncherPreferences.DEFAULT_PREF.edit().putString("defaultRuntime",LauncherPreferences.PREF_DEFAULT_RUNTIME).apply();
setDefault(currentRuntime);
RTRecyclerViewAdapter.this.notifyDataSetChanged();
}
}
}
}
}

View File

@ -0,0 +1,103 @@
package net.kdt.pojavlaunch.multirt;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.R;
import java.util.List;
public class RTSpinnerAdapter implements SpinnerAdapter {
final Context ctx;
List<MultiRTUtils.Runtime> runtimes;
public RTSpinnerAdapter(@NonNull Context context, List<MultiRTUtils.Runtime> runtimes) {
this.runtimes = runtimes;
MultiRTUtils.Runtime runtime = new MultiRTUtils.Runtime("<Default>");
runtime.versionString = "";
this.runtimes.add(runtime);
ctx = context;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return runtimes.size();
}
@Override
public Object getItem(int position) {
return runtimes.get(position);
}
@Override
public long getItemId(int position) {
return runtimes.get(position).name.hashCode();
}
@Override
public boolean hasStableIds() {
return true;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView!=null?
convertView:
LayoutInflater.from(ctx).inflate(R.layout.multirt_recyclable_view,parent,false);
MultiRTUtils.Runtime rt = runtimes.get(position);
final TextView javaVersionView = v.findViewById(R.id.multirt_view_java_version);
final TextView fullJavaVersionView = v.findViewById(R.id.multirt_view_java_version_full);
v.findViewById(R.id.multirt_view_removebtn).setVisibility(View.GONE);
v.findViewById(R.id.multirt_view_setdefaultbtn).setVisibility(View.GONE);
if(rt.versionString != null) {
javaVersionView.setText(ctx.getString(R.string.multirt_java_ver, rt.name, rt.javaVersion));
fullJavaVersionView.setText(rt.versionString);
}else{
javaVersionView.setText(rt.name);
fullJavaVersionView.setText(R.string.multirt_runtime_corrupt);
}
return v;
}
@Override
public int getItemViewType(int position) {
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return runtimes.isEmpty();
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return getView(position,convertView,parent);
}
}

View File

@ -10,9 +10,12 @@ import java.io.*;
import java.util.*;
import java.util.concurrent.*;
import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import org.apache.commons.io.*;
import java.util.concurrent.atomic.AtomicBoolean;
@ -84,6 +87,21 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
}
verInfo = Tools.getVersionInfo(mActivity,p1[0]);
//Now we have the reliable information to check if our runtime settings are good enough
if(verInfo.javaVersion != null) { //1.17+
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(p1[0]);
MultiRTUtils.Runtime r = cfg.selectedRuntime != null?MultiRTUtils.read(cfg.selectedRuntime):MultiRTUtils.read(LauncherPreferences.PREF_DEFAULT_RUNTIME);
if(r.javaVersion < verInfo.javaVersion.majorVersion) {
String appropriateRuntime = MultiRTUtils.getNearestJREName(verInfo.javaVersion.majorVersion);
if(appropriateRuntime != null) {
cfg.selectedRuntime = appropriateRuntime;
PerVersionConfig.update();
}else{
return new Exception("Unable to find a compatible Java Runtime for this version");
}
} //if else, we are satisfied
}
try {
assets = downloadIndex(verInfo.assets, new File(Tools.ASSETS_PATH, "indexes/" + verInfo.assets + ".json"));
} catch (IOException e) {

View File

@ -13,6 +13,8 @@ import android.widget.AdapterView.*;
import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.PerVersionConfig;
@ -74,41 +76,48 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
public boolean onLongClick(View view) {
AlertDialog.Builder builder = new AlertDialog.Builder(view.getContext());
final View v = LayoutInflater.from(view.getContext()).inflate(R.layout.pvc_popup,null);
final List<MultiRTUtils.Runtime> runtimes = MultiRTUtils.getRuntimes();
final Spinner javaVMSpinner = ((Spinner)v.findViewById(R.id.pvc_javaVm));
final EditText customDirText = ((EditText)v.findViewById(R.id.pvc_customDir));
final EditText jvmArgsEditText = ((EditText)v.findViewById(R.id.pvc_jvmArgs));
javaVMSpinner.setAdapter(new RTSpinnerAdapter(RefreshVersionListTask.this.mActivity,runtimes));
try {
PerVersionConfig.update();
}catch (IOException e) {
e.printStackTrace();
}
PerVersionConfig.VersionConfig conf = PerVersionConfig.configMap.get(mActivity.mProfile.selectedVersion);
int index = runtimes.indexOf(new MultiRTUtils.Runtime("<Default>"));
if(conf != null) {
((EditText)v.findViewById(R.id.pvc_customDir)).setText(conf.gamePath);
((EditText)v.findViewById(R.id.pvc_jvmArgs)).setText(conf.jvmArgs);
customDirText.setText(conf.gamePath);
jvmArgsEditText.setText(conf.jvmArgs);
if(conf.selectedRuntime != null) {
int nindex = runtimes.indexOf(new MultiRTUtils.Runtime(conf.selectedRuntime));
if(nindex != -1) index = nindex;
}
}
javaVMSpinner.setSelection(index);
builder.setView(v);
builder.setTitle("Per-version settings");
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
PerVersionConfig.VersionConfig conf = PerVersionConfig.configMap.get(mActivity.mProfile.selectedVersion);
if(conf == null) {
conf = new PerVersionConfig.VersionConfig();
}
conf.jvmArgs = ((EditText)v.findViewById(R.id.pvc_jvmArgs)).getText().toString();
conf.gamePath = ((EditText)v.findViewById(R.id.pvc_customDir)).getText().toString();
PerVersionConfig.configMap.put(mActivity.mProfile.selectedVersion,conf);
try {
PerVersionConfig.update();
}catch (IOException e) {
e.printStackTrace();
}
builder.setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> dialogInterface.dismiss());
builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
PerVersionConfig.VersionConfig conf1 = PerVersionConfig.configMap.get(mActivity.mProfile.selectedVersion);
if(conf1 == null) {
conf1 = new PerVersionConfig.VersionConfig();
}
});
conf1.jvmArgs = jvmArgsEditText.getText().toString();
conf1.gamePath = customDirText.getText().toString();
String runtime = ((MultiRTUtils.Runtime)javaVMSpinner.getSelectedItem()).name;;
if(!runtime.equals("<Default>")) conf1.selectedRuntime = runtime;
else conf1.selectedRuntime = null;
PerVersionConfig.configMap.put(mActivity.mProfile.selectedVersion, conf1);
try {
PerVersionConfig.update();
}catch (IOException e) {
e.printStackTrace();
}
});
builder.show();
return true;
}

View File

@ -27,5 +27,6 @@ public class PerVersionConfig {
public static class VersionConfig {
public String jvmArgs;
public String gamePath;
public String selectedRuntime;
}
}

View File

@ -33,4 +33,15 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pvc_jvmArgs" />
<Spinner
android:id="@+id/pvc_javaVm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pvc_customDir" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -221,4 +221,5 @@
<string name="multirt_progress_caching">Caching...</string>
<string name="multirt_config_setdefault">Set default</string>
<string name="multirt_config_setdefault_already">Default</string>
<string name="multirt_config_removeerror_last">You must have at least one Java Runtime installed</string>
</resources>