Merge branch 'profiles-2-electric-boogaloo' into merge-profiles

This commit is contained in:
ArtDev 2022-03-17 17:48:58 +03:00 committed by GitHub
commit cf726684c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 955 additions and 147 deletions

View File

@ -12,14 +12,22 @@ import android.widget.*;
import androidx.annotation.Nullable;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import net.kdt.pojavlaunch.extra.ExtraCore;
import net.kdt.pojavlaunch.extra.ExtraListener;
import net.kdt.pojavlaunch.fragments.*;
import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.tasks.*;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.PopupMenu;
import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.apache.commons.io.IOUtils;
@ -33,7 +41,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
public JMinecraftVersionList mVersionList;
public MinecraftDownloaderTask mTask;
public MinecraftAccount mProfile;
public String[] mAvailableVersions;
//public String[] mAvailableVersions;
public boolean mIsAssetsProcessing = false;
protected boolean canBack = false;
@ -99,7 +107,11 @@ public abstract class BaseLauncherActivity extends BaseActivity {
} else if (canBack) {
v.setEnabled(false);
mTask = new MinecraftDownloaderTask(this);
// TODO: better check!!!
if(LauncherPreferences.PREF_ENABLE_PROFILES) {
LauncherProfiles.update();
if (LauncherProfiles.mainProfileJson != null && LauncherProfiles.mainProfileJson.profiles != null && LauncherProfiles.mainProfileJson.profiles.containsKey(mProfile.selectedProfile + "")) {
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(mProfile.selectedProfile + "");
if (prof != null && prof.lastVersionId != null) {
if (mProfile.accessToken.equals("0")) {
File verJsonFile = new File(Tools.DIR_HOME_VERSION,
mProfile.selectedVersion + "/" + mProfile.selectedVersion + ".json");
@ -112,13 +124,30 @@ public abstract class BaseLauncherActivity extends BaseActivity {
.setPositiveButton(android.R.string.ok, null)
.show();
}
} else {
}
mTask.execute(getVersionId(prof.lastVersionId));
}
}
}else{
mTask.execute(mProfile.selectedVersion);
}
}
}
public static String getVersionId(String input) {
Map<String,String> lReleaseMaps = (Map<String,String>)ExtraCore.getValue("release_table");
if(lReleaseMaps == null || lReleaseMaps.isEmpty()) return input;
switch(input) {
case "latest-release":
return lReleaseMaps.get("release");
case "latest-snapshot":
return lReleaseMaps.get("snapshot");
default:
return input;
}
}
@Override
public void onBackPressed() {
if (canBack) {
@ -133,10 +162,98 @@ public abstract class BaseLauncherActivity extends BaseActivity {
Tools.updateWindowSize(this);
System.out.println("call to onPostResume; E");
}
public void setupVersionSelector() {
final androidx.appcompat.widget.PopupMenu popup = new PopupMenu(this, mVersionSelector);
popup.getMenuInflater().inflate(R.menu.menu_versionopt, popup.getMenu());
PerVersionConfigDialog dialog = new PerVersionConfigDialog(this);
this.mVersionSelector.setOnLongClickListener((v)->dialog.openConfig(this.mProfile.selectedVersion));
this.mVersionSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
{
mProfile.selectedVersion = p1.getItemAtPosition(p3).toString();
PojavProfile.setCurrentProfile(BaseLauncherActivity.this, mProfile);
if (PojavProfile.isFileType(BaseLauncherActivity.this)) {
try {
PojavProfile.setCurrentProfile(BaseLauncherActivity.this, mProfile.save());
} catch (IOException e) {
Tools.showError(BaseLauncherActivity.this, e);
}
}
}
@Override
public void onNothingSelected(AdapterView<?> p1)
{
// TODO: Implement this method
}
});
popup.setOnMenuItemClickListener(item -> true);
}
ExtraListener<ArrayList<String>> versionListener;
@Override
protected void onPause() {
super.onPause();
if((!LauncherPreferences.PREF_ENABLE_PROFILES) && versionListener != null) ExtraCore.removeExtraListenerFromValue("lac_version_list",versionListener);
}
public static void updateVersionSpinner(Context ctx, ArrayList<String> value, Spinner mVersionSelector, String defaultSelection) {
if(value != null && value.size() > 0) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(ctx, android.R.layout.simple_spinner_item, value);
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
mVersionSelector.setAdapter(adapter);
mVersionSelector.setSelection(RefreshVersionListTask.selectAt(value, defaultSelection));
} else {
mVersionSelector.setSelection(RefreshVersionListTask.selectAt(PojavLauncherActivity.basicVersionList, defaultSelection));
}
}
@Override
protected void onResume(){
super.onResume();
new RefreshVersionListTask(this).execute();
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
ArrayList<String> vlst = (ArrayList<String>) ExtraCore.getValue("lac_version_list");
if(vlst != null) {
setupVersionSelector();
updateVersionSpinner(this, vlst, mVersionSelector, mProfile.selectedVersion);
}
versionListener = (key, value) -> {
if(value != null) {
setupVersionSelector();
updateVersionSpinner(this, value, mVersionSelector, mProfile.selectedVersion);
}
return false;
};
ExtraCore.addExtraListener("lac_version_list",versionListener);
}
if(listRefreshListener != null) {
LauncherPreferences.DEFAULT_PREF.unregisterOnSharedPreferenceChangeListener(listRefreshListener);
}
listRefreshListener = (sharedPreferences, key) -> {
if(key.startsWith("vertype_")) {
System.out.println("Verlist update needed!");
LauncherPreferences.PREF_VERTYPE_RELEASE = sharedPreferences.getBoolean("vertype_release",true);
LauncherPreferences.PREF_VERTYPE_SNAPSHOT = sharedPreferences.getBoolean("vertype_snapshot",false);
LauncherPreferences.PREF_VERTYPE_OLDALPHA = sharedPreferences.getBoolean("vertype_oldalpha",false);
LauncherPreferences.PREF_VERTYPE_OLDBETA = sharedPreferences.getBoolean("vertype_oldbeta",false);
new RefreshVersionListTask(this).execute();
}
};
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener);
if(profileEnableListener != null) {
LauncherPreferences.DEFAULT_PREF.unregisterOnSharedPreferenceChangeListener(profileEnableListener);
}
profileEnableListener = ((sharedPreferences, key) -> {
if(key.equals("enable_profiles")) {
LauncherPreferences.PREF_ENABLE_PROFILES = sharedPreferences.getBoolean("enable_profiles",false);
this.recreate();
profileEnableListener = null;
}
});
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(profileEnableListener);
System.out.println("call to onResume");
final int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
final View decorView = getWindow().getDecorView();
@ -145,20 +262,10 @@ public abstract class BaseLauncherActivity extends BaseActivity {
}
SharedPreferences.OnSharedPreferenceChangeListener listRefreshListener = null;
SharedPreferences.OnSharedPreferenceChangeListener profileEnableListener = null;
@Override
protected void onResumeFragments() {
super.onResumeFragments();
if(listRefreshListener == null) {
final BaseLauncherActivity thiz = this;
listRefreshListener = (sharedPreferences, key) -> {
if(key.startsWith("vertype_")) {
System.out.println("Verlist update needed!");
new RefreshVersionListTask(thiz).execute();
}
};
}
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener);
new RefreshVersionListTask(this).execute();
System.out.println("call to onResumeFragments");
mRuntimeConfigDialog = new MultiRTConfigDialog();
mRuntimeConfigDialog.prepare(this);

View File

@ -27,8 +27,12 @@ import net.kdt.pojavlaunch.customcontrols.*;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.profiles.ProfileAdapter;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.lwjgl.glfw.*;
public class BaseMainActivity extends BaseActivity {
@ -45,7 +49,7 @@ public class BaseMainActivity extends BaseActivity {
private static Touchpad touchpad;
private LoggerView loggerView;
private MinecraftAccount mProfile;
MinecraftAccount mProfile;
private DrawerLayout drawerLayout;
private NavigationView navDrawer;
@ -55,11 +59,10 @@ public class BaseMainActivity extends BaseActivity {
protected volatile JMinecraftVersionList.Version mVersionInfo;
private PerVersionConfig.VersionConfig config;
//private PerVersionConfig.VersionConfig config;
protected void initLayout(int resId) {
setContentView(resId);
try {
Logger.getInstance().reset();
// FIXME: is it safe fot multi thread?
@ -68,12 +71,11 @@ public class BaseMainActivity extends BaseActivity {
loggerView = findViewById(R.id.mainLoggerView);
mProfile = PojavProfile.getCurrentProfileContent(this);
mVersionInfo = Tools.getVersionInfo(null,mProfile.selectedVersion);
setTitle("Minecraft " + mProfile.selectedVersion);
PerVersionConfig.update();
config = PerVersionConfig.configMap.get(mProfile.selectedVersion);
String runtime = LauncherPreferences.PREF_DEFAULT_RUNTIME;
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
mVersionInfo = Tools.getVersionInfo(null, mProfile.selectedVersion);
PerVersionConfig.update();
PerVersionConfig.VersionConfig config = PerVersionConfig.configMap.get(mProfile.selectedVersion);
if(config != null) {
if(config.selectedRuntime != null) {
if(MultiRTUtils.forceReread(config.selectedRuntime).versionString != null) {
@ -84,6 +86,30 @@ public class BaseMainActivity extends BaseActivity {
Tools.LOCAL_RENDERER = config.renderer;
}
}
}else{
LauncherProfiles.update();
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(mProfile.selectedProfile);
if(prof == null) {
Toast.makeText(this,"Attempted to launch nonexistent profile",Toast.LENGTH_SHORT).show();
finish();
return;
}
mVersionInfo = Tools.getVersionInfo(null, BaseLauncherActivity.getVersionId(
prof.lastVersionId));
if(prof.javaDir != null && prof.javaDir.startsWith(Tools.LAUNCHERPROFILES_RTPREFIX)) {
String runtimeName = prof.javaDir.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length());
if(MultiRTUtils.forceReread(runtimeName).versionString != null) {
runtime = runtimeName;
}
}
if(prof.__P_renderer_name != null) {
Log.i("RdrDebug","__P_renderer="+prof.__P_renderer_name);
Tools.LOCAL_RENDERER = prof.__P_renderer_name;
}
}
setTitle("Minecraft " + mProfile.selectedVersion);
MultiRTUtils.setRuntimeNamed(this,runtime);
// Minecraft 1.13+
isInputStackCall = mVersionInfo.arguments != null;
@ -204,8 +230,15 @@ public class BaseMainActivity extends BaseActivity {
((mVersionInfo.inheritsFrom == null || mVersionInfo.inheritsFrom.equals(mVersionInfo.id)) ?
"" : " (" + mVersionInfo.inheritsFrom + ")"));
JREUtils.redirectAndPrintJRELog();
JREUtils.redirectAndPrintJRELog(this);
if(!LauncherPreferences.PREF_ENABLE_PROFILES){
Tools.launchMinecraft(this, mProfile, mProfile.selectedVersion);
}else{
LauncherProfiles.update();
Tools.launchMinecraft(this, mProfile, BaseLauncherActivity.getVersionId(
LauncherProfiles.mainProfileJson.profiles.get(mProfile.selectedProfile).lastVersionId));
}
}
private void checkJavaArgsIsLaunchable(String jreVersion) throws Throwable {

View File

@ -6,6 +6,7 @@ import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_HIDE_SIDEBAR;
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Typeface;
@ -36,10 +37,15 @@ import net.kdt.pojavlaunch.fragments.ConsoleFragment;
import net.kdt.pojavlaunch.fragments.CrashFragment;
import net.kdt.pojavlaunch.fragments.LauncherFragment;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.prefs.PerVersionConfigDialog;
import net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceFragment;
import net.kdt.pojavlaunch.profiles.ProfileAdapter;
import net.kdt.pojavlaunch.profiles.ProfileEditor;
import net.kdt.pojavlaunch.value.MinecraftAccount;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -81,6 +87,14 @@ public class PojavLauncherActivity extends BaseLauncherActivity
public PojavLauncherActivity() {
}
@Override
protected void onDestroy() {
ExtraCore.removeExtraListenerFromValue("back_preference", backPreferenceListener);
super.onDestroy();
ProfileAdapter.clearIconCache();
Log.i("LauncherActivity","Destroyed!");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -174,31 +188,56 @@ public class PojavLauncherActivity extends BaseLauncherActivity
});
// Setup the minecraft version list
List<String> versions = new ArrayList<>();
final File fVers = new File(Tools.DIR_HOME_VERSION);
try {
if (fVers.listFiles().length < 1) {
throw new Exception(getString(R.string.error_no_version));
}
for (File fVer : fVers.listFiles()) {
if (fVer.isDirectory())
versions.add(fVer.getName());
}
} catch (Exception e) {
versions.add(getString(R.string.global_error) + ":");
versions.add(e.getMessage());
} finally {
mAvailableVersions = versions.toArray(new String[0]);
}
setupBasicList(this);
//mAvailableVersions;
ArrayAdapter<String> adapterVer = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, mAvailableVersions);
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
ArrayAdapter<String> adapterVer = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, basicVersionList);
adapterVer.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
mVersionSelector.setAdapter(adapterVer);
}else{
ProfileAdapter pad = new ProfileAdapter(this);
ProfileEditor dialog = new ProfileEditor(this,(name, isNew, deleting)->{
LauncherProfiles.update();
if(isNew) {
mVersionSelector.setSelection(pad.resolveProfileIndex(name));
}
if(deleting) {
mVersionSelector.setSelection(0);
}
pad.notifyDataSetChanged();
});
mVersionSelector.setOnLongClickListener((v)->dialog.show(mProfile.selectedProfile));
mVersionSelector.setAdapter(pad);
mVersionSelector.setSelection(pad.resolveProfileIndex(mProfile.selectedProfile));
mVersionSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
{
String profileName = p1.getItemAtPosition(p3).toString();
if(profileName.equals(ProfileAdapter.CREATE_PROFILE_MAGIC)) {
dialog.show(profileName);
mVersionSelector.setSelection(0);
}else {
mProfile.selectedProfile = p1.getItemAtPosition(p3).toString();
PojavProfile.setCurrentProfile(PojavLauncherActivity.this, mProfile);
if (PojavProfile.isFileType(PojavLauncherActivity.this)) {
try {
PojavProfile.setCurrentProfile(PojavLauncherActivity.this, mProfile.save());
} catch (IOException e) {
Tools.showError(PojavLauncherActivity.this, e);
}
}
}
}
@Override
public void onNothingSelected(AdapterView<?> p1)
{
// TODO: Implement this method
}
});
}
//
statusIsLaunching(false);
@ -216,12 +255,33 @@ public class PojavLauncherActivity extends BaseLauncherActivity
});
changeLookAndFeel(PREF_HIDE_SIDEBAR);
}
private void selectTabPage(int pageIndex){
viewPager.setCurrentItem(pageIndex);
setTabActive(pageIndex);
}
public static String[] basicVersionList;
public static void setupBasicList(Context ctx) {
List<String> versions = new ArrayList<>();
final File fVers = new File(Tools.DIR_HOME_VERSION);
try {
if (fVers.listFiles().length < 1) {
throw new Exception(ctx.getString(R.string.error_no_version));
}
for (File fVer : fVers.listFiles()) {
if (fVer.isDirectory())
versions.add(fVer.getName());
}
} catch (Exception e) {
versions.add(ctx.getString(R.string.global_error) + ":");
versions.add(e.getMessage());
} finally {
basicVersionList = versions.toArray(new String[0]);
ExtraCore.setValue("lac_version_list",versions);
}
}
private void pickAccount() {
try {
mProfile = PojavProfile.getCurrentProfileContent(this);

View File

@ -23,6 +23,7 @@ import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils;
@ -50,6 +51,7 @@ public final class Tools {
public static String MULTIRT_HOME;
public static String LOCAL_RENDERER = null;
public static int DEVICE_ARCHITECTURE;
public static String LAUNCHERPROFILES_RTPREFIX = "pojav://";
// New since 3.3.1
public static String DIR_ACCOUNT_NEW;
@ -117,13 +119,25 @@ public final class Tools {
}
JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(null,versionName);
String gamedirPath = Tools.DIR_GAME_NEW;
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
PerVersionConfig.update();
PerVersionConfig.VersionConfig pvcConfig = PerVersionConfig.configMap.get(versionName);
String gamedirPath;
if(pvcConfig != null && pvcConfig.gamePath != null && !pvcConfig.gamePath.isEmpty()) gamedirPath = pvcConfig.gamePath;
else gamedirPath = Tools.DIR_GAME_NEW;
if(pvcConfig != null && pvcConfig.jvmArgs != null && !pvcConfig.jvmArgs.isEmpty()) LauncherPreferences.PREF_CUSTOM_JAVA_ARGS = pvcConfig.jvmArgs;
if (pvcConfig != null && pvcConfig.gamePath != null && !pvcConfig.gamePath.isEmpty())
gamedirPath = pvcConfig.gamePath;
if (pvcConfig != null && pvcConfig.jvmArgs != null && !pvcConfig.jvmArgs.isEmpty())
LauncherPreferences.PREF_CUSTOM_JAVA_ARGS = pvcConfig.jvmArgs;
}else{
if(activity instanceof BaseMainActivity) {
LauncherProfiles.update();
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(((BaseMainActivity)activity).mProfile.selectedProfile);
if(prof == null) throw new Exception("Launching empty Profile");
if(prof.gameDir != null && !prof.gameDir.isEmpty())
gamedirPath = prof.gameDir;
if(prof.javaArgs != null && !prof.javaArgs.isEmpty())
LauncherPreferences.PREF_CUSTOM_JAVA_ARGS = prof.javaArgs;
}
}
PojavLoginActivity.disableSplash(gamedirPath);
String[] launchArgs = getMinecraftArgs(profile, versionInfo, gamedirPath);

View File

@ -12,7 +12,7 @@ import static net.kdt.pojavlaunch.customcontrols.ControlDrawerData.Orientation.F
import androidx.annotation.Keep;
@Keep
@androidx.annotation.Keep
public class ControlDrawerData {
public ArrayList<ControlData> buttonProperties;

View File

@ -34,6 +34,7 @@ public class LauncherPreferences
public static int PREF_CONTROL_BOTTOM_OFFSET = 0;
public static int PREF_CONTROL_LEFT_OFFSET = 0;
public static boolean PREF_SUSTAINED_PERFORMANCE = false;
public static boolean PREF_ENABLE_PROFILES = true;
public static String PREF_GLES_SHRINK_HACK = "0";
public static boolean PREF_VBO_DISABLE_HACK = false;
public static boolean PREF_VIRTUAL_MOUSE_START = false;
@ -70,6 +71,7 @@ public class LauncherPreferences
PREF_SUSTAINED_PERFORMANCE = DEFAULT_PREF.getBoolean("sustainedPerformance", false);
PREF_GLES_SHRINK_HACK = DEFAULT_PREF.getString("gl4es_shrink_hack", "0");
PREF_VBO_DISABLE_HACK = DEFAULT_PREF.getBoolean("vbo_disable_hack", false);
PREF_ENABLE_PROFILES = DEFAULT_PREF.getBoolean("enable_profiles", false);
PREF_VIRTUAL_MOUSE_START = DEFAULT_PREF.getBoolean("mouse_start", false);
PREF_OPENGL_VERSION_HACK = DEFAULT_PREF.getBoolean("gles_version_hack", false);
PREF_ARC_CAPES = DEFAULT_PREF.getBoolean("arc_capes",false);

View File

@ -0,0 +1,150 @@
package net.kdt.pojavlaunch.profiles;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/*
* Adapter for listing launcher profiles in a Spinner
*/
public class ProfileAdapter extends BaseAdapter {
Map<String, MinecraftProfile> profiles;
ArrayList<DataSetObserver> observers = new ArrayList<>();
static final Map<String, Bitmap> iconCache = new HashMap<>();
static final String BASE64_PNG_HEADER = "data:image/png;base64,";
public static final String CREATE_PROFILE_MAGIC = "___extra____profile-create";
static final MinecraftProfile DUMMY = new MinecraftProfile();
static MinecraftProfile CREATE_PROFILE;
List<String> profileList;
public ProfileAdapter(Context ctx) {
LauncherProfiles.update();
profiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles);
if(CREATE_PROFILE == null) {
CREATE_PROFILE = new MinecraftProfile();
CREATE_PROFILE.name = "Create new profile";
CREATE_PROFILE.lastVersionId = "";
}
profileList = new ArrayList<>(Arrays.asList(profiles.keySet().toArray(new String[0])));
profileList.add(ProfileAdapter.CREATE_PROFILE_MAGIC);
profiles.put(CREATE_PROFILE_MAGIC, CREATE_PROFILE);
if(!iconCache.containsKey(null))
iconCache.put(null,BitmapFactory.decodeResource(ctx.getResources(),R.drawable.ic_menu_java));
}
/*
* Gets how much profiles are loaded in the adapter right now
* @returns loaded profile count
*/
@Override
public int getCount() {
return profileList.size();
}
public static void clearIconCache() {
for(String s : iconCache.keySet()) {
Bitmap bmp = iconCache.get(s);
if(bmp != null) {
bmp.recycle();
}
}
iconCache.clear();
}
/*
* Gets the profile at a given index
* @param position index to retreive
* @returns MinecraftProfile name or null
*/
@Override
public Object getItem(int position) {
//safe since the second check in the and statement will be skipped if the first one fails
if(position < profileList.size() && profiles.containsKey(profileList.get(position))) {
return profileList.get(position);
}else{
return null;
}
}
public int resolveProfileIndex(String name) {
return profileList.indexOf(name);
}
public void fireProfileEdit() {
notifyDataSetChanged();
}
/*
* Gets the item ID (crc64 hash of the profile name) for a given index
* @param position index to get the hash for
* @returns ID (crc64 of a profile name string) or -1 if the index is out of bounds
*/
@Override
public long getItemId(int position) {
return position;
}
@Override
public void notifyDataSetChanged() {
profiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles);
profileList = new ArrayList<>(Arrays.asList(profiles.keySet().toArray(new String[0])));
profileList.add(ProfileAdapter.CREATE_PROFILE_MAGIC);
profiles.put(CREATE_PROFILE_MAGIC, CREATE_PROFILE);
super.notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) v = LayoutInflater.from(parent.getContext()).inflate(R.layout.version_profile_layout,parent,false);
setViewProfile(v,profileList.get(position));
return v;
}
public void setViewProfile(View v, String nm) {
MinecraftProfile prof = profiles.get(nm);
if(prof == null) prof = DUMMY;
Bitmap cachedIcon = iconCache.get(nm);
ImageView iconView = v.findViewById(R.id.vprof_icon_view);
if(cachedIcon == null && prof.icon != null) {
if (prof.icon.startsWith(BASE64_PNG_HEADER)) {
byte[] pngBytes = Base64.decode(prof.icon.substring(BASE64_PNG_HEADER.length()), Base64.DEFAULT);
cachedIcon = BitmapFactory.decodeByteArray(pngBytes,0,pngBytes.length);
iconCache.put(nm,cachedIcon);
}else{
Log.i("IconParser","Unsupported icon: "+prof.icon);
cachedIcon = iconCache.get(null);
}
}
iconView.setImageBitmap(cachedIcon);
if(prof.name != null && !prof.name.isEmpty())
((TextView)v.findViewById(R.id.vprof_profile_name_view)).setText(prof.name);
else
((TextView)v.findViewById(R.id.vprof_profile_name_view)).setText(R.string.unnamed);
TextView tv = v.findViewById(R.id.vprof_version_id_view);
if(prof.lastVersionId != null) switch (prof.lastVersionId) {
case "latest-release":
tv.setText(R.string.profiles_latest_release);
case "latest-snapshot":
tv.setText(R.string.profiles_latest_snapshot);
default:
tv.setText(prof.lastVersionId);
} else tv.setText(android.R.string.unknownName);
}
}

View File

@ -0,0 +1,192 @@
package net.kdt.pojavlaunch.profiles;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import net.kdt.pojavlaunch.BaseLauncherActivity;
import net.kdt.pojavlaunch.PojavLauncherActivity;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.extra.ExtraCore;
import net.kdt.pojavlaunch.extra.ExtraListener;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class ProfileEditor implements ExtraListener<ArrayList<String>> {
View mainView;
TextView profileNameView;
ImageView profileIconView;
Spinner versionSpinner;
Spinner javaRuntimeSpinner;
Spinner rendererSpinner;
List<MultiRTUtils.Runtime> runtimes;
List<String> renderNames;
AlertDialog dialog;
Context context;
String selectedVersionId;
String editingProfile;
EditSaveCallback cb;
public static MinecraftProfile generateTemplate() {
MinecraftProfile TEMPLATE = new MinecraftProfile();
TEMPLATE.name = "New";
TEMPLATE.lastVersionId = "latest-release";
return TEMPLATE;
}
public ProfileEditor(Context _ctx, EditSaveCallback cb) {
context = _ctx;
this.cb = cb;
LayoutInflater infl = LayoutInflater.from(_ctx);
mainView = infl.inflate(R.layout.version_profile_editor,null);
AlertDialog.Builder bldr = new AlertDialog.Builder(_ctx);
bldr.setView(mainView);
profileNameView = mainView.findViewById(R.id.vprof_editior_profile_name);
versionSpinner = mainView.findViewById(R.id.vprof_editor_version_spinner);
javaRuntimeSpinner = mainView.findViewById(R.id.vprof_editor_spinner_runtime);
rendererSpinner = mainView.findViewById(R.id.vprof_editor_profile_renderer);
{
List<String> renderList = new ArrayList<>();
Collections.addAll(renderList, context.getResources().getStringArray(R.array.renderer));
renderList.add("Default");
renderNames = Arrays.asList(context.getResources().getStringArray(R.array.renderer_values));
rendererSpinner.setAdapter(new ArrayAdapter<>(context, android.R.layout.simple_spinner_dropdown_item,renderList));
}
profileIconView = mainView.findViewById(R.id.vprof_editor_icon);
bldr.setPositiveButton(R.string.global_save,this::save);
bldr.setNegativeButton(android.R.string.cancel,(dialog,which)->destroy(dialog));
bldr.setNeutralButton(R.string.global_delete,(dialogInterface, i) -> {
LauncherProfiles.mainProfileJson.profiles.remove(editingProfile);
this.cb.onSave(editingProfile,false, true);
});
bldr.setOnDismissListener(this::destroy);
dialog = bldr.create();
}
public boolean show(@NonNull String profile) {
MinecraftProfile prof;
if(!ProfileAdapter.CREATE_PROFILE_MAGIC.equals(profile)) {
prof = LauncherProfiles.mainProfileJson.profiles.get(profile);
if (prof == null) return true;
editingProfile = profile;
}else{
prof = generateTemplate();
String uuid = UUID.randomUUID().toString();
while(LauncherProfiles.mainProfileJson.profiles.containsKey(uuid)) {
uuid = UUID.randomUUID().toString();
}
editingProfile = uuid;
}
runtimes = MultiRTUtils.getRuntimes();
javaRuntimeSpinner.setAdapter(new RTSpinnerAdapter(context, runtimes));
int jvm_index = runtimes.indexOf(new MultiRTUtils.Runtime("<Default>"));
int rnd_index = rendererSpinner.getAdapter().getCount()-1;
if (prof.javaDir != null) {
String selectedRuntime = prof.javaDir.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length());
int nindex = runtimes.indexOf(new MultiRTUtils.Runtime(selectedRuntime));
if (nindex != -1) jvm_index = nindex;
}
if(prof.__P_renderer_name != null) {
int nindex = renderNames.indexOf(prof.__P_renderer_name);
if(nindex != -1) rnd_index = nindex;
}
javaRuntimeSpinner.setSelection(jvm_index);
rendererSpinner.setSelection(rnd_index);
ExtraCore.addExtraListener("lac_version_list",this);
profileNameView.setText(prof.name);
if(ProfileAdapter.iconCache.containsKey(profile)) {
Log.i("ProfileEditor","Icon resolved!");
profileIconView.setImageBitmap(ProfileAdapter.iconCache.get(profile));
}else {
Log.i("ProfileEditor","No resolved icon.");
Log.i("ProfileEditor", ProfileAdapter.iconCache.keySet().toString());
profileIconView.setImageBitmap(ProfileAdapter.iconCache.get(null));
}
if(prof.lastVersionId != null && !"latest-release".equals(prof.lastVersionId) && !"latest-snapshot".equals(prof.lastVersionId))
selectedVersionId = prof.lastVersionId;
else if(prof.lastVersionId != null) {
Map<String,String> releaseTable = (Map<String,String>)ExtraCore.getValue("release_table");
if(releaseTable != null) {
switch (prof.lastVersionId) {
case "latest-release":
selectedVersionId = releaseTable.get("release");
case "latest-snapshot":
selectedVersionId = releaseTable.get("snapshot");
}
}else{
selectedVersionId = null;
}
}
else{
if(PojavLauncherActivity.basicVersionList.length > 0) {
selectedVersionId = PojavLauncherActivity.basicVersionList[0];
}
}
ArrayList<String> versions = (ArrayList<String>) ExtraCore.getValue("lac_version_list");
BaseLauncherActivity.updateVersionSpinner(context,versions,versionSpinner, selectedVersionId);
dialog.show();
return true;
}
public void save(DialogInterface dialog, int which) {
System.out.println(editingProfile);
MinecraftProfile prof;
boolean isNew;
if(LauncherProfiles.mainProfileJson.profiles.containsKey(editingProfile)) {
prof = LauncherProfiles.mainProfileJson.profiles.get(editingProfile);
LauncherProfiles.mainProfileJson.profiles.remove(editingProfile);
isNew = false;
}else{
prof = new MinecraftProfile();
isNew = true;
}
prof.name = profileNameView.getText().toString();
prof.lastVersionId = (String)versionSpinner.getSelectedItem();
MultiRTUtils.Runtime selectedRuntime = (MultiRTUtils.Runtime) javaRuntimeSpinner.getSelectedItem();
if(selectedRuntime.name.equals("<Default>")) {
prof.javaDir = null;
}else if(selectedRuntime.versionString == null) {
prof.javaDir = null;
}else{
prof.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX+selectedRuntime.name;
}
if(rendererSpinner.getSelectedItemPosition() == renderNames.size()) prof.__P_renderer_name = null;
else prof.__P_renderer_name = renderNames.get(rendererSpinner.getSelectedItemPosition());
LauncherProfiles.mainProfileJson.profiles.put(editingProfile,prof);
cb.onSave(editingProfile,isNew, false);
destroy(dialog);
}
public void destroy(@NonNull DialogInterface dialog) {
ExtraCore.removeExtraListenerFromValue("lac_version_list",this);
editingProfile = null;
selectedVersionId = null;
}
@Override
public boolean onValueSet(String key, @Nullable ArrayList<String> value) {
if(value != null) ((Activity)context).runOnUiThread(()->{
BaseLauncherActivity.updateVersionSpinner(context,value,versionSpinner, selectedVersionId);
});
return false;
}
public interface EditSaveCallback {
void onSave(String name, boolean isNew, boolean isRemoving);
}
}

View File

@ -0,0 +1,64 @@
package net.kdt.pojavlaunch.profiles;
import java.nio.charset.StandardCharsets;
public class StringCRC64 {
private final static long POLY = 0xc96c5795d7870f42L; // ECMA-182
private final static long[][] table;
static
{
table = new long[8][256];
for (int n = 0; n < 256; n++)
{
long crc = n;
for (int k = 0; k < 8; k++)
{
if ((crc & 1) == 1)
{
crc = (crc >>> 1) ^ POLY;
}
else
{
crc = (crc >>> 1);
}
}
table[0][n] = crc;
}
for (int n = 0; n < 256; n++)
{
long crc = table[0][n];
for (int k = 1; k < 8; k++)
{
crc = table[0][(int) (crc & 0xff)] ^ (crc >>> 8);
table[k][n] = crc;
}
}
}
public static long strhash(String str) {
byte[] b = str.getBytes(StandardCharsets.US_ASCII);
long value = 0;
int idx = 0;
int len = b.length;
while (len >= 8)
{
value = table[7][(int) (value & 0xff ^ (b[idx] & 0xff))]
^ table[6][(int) ((value >>> 8) & 0xff ^ (b[idx + 1] & 0xff))]
^ table[5][(int) ((value >>> 16) & 0xff ^ (b[idx + 2] & 0xff))]
^ table[4][(int) ((value >>> 24) & 0xff ^ (b[idx + 3] & 0xff))]
^ table[3][(int) ((value >>> 32) & 0xff ^ (b[idx + 4] & 0xff))]
^ table[2][(int) ((value >>> 40) & 0xff ^ (b[idx + 5] & 0xff))]
^ table[1][(int) ((value >>> 48) & 0xff ^ (b[idx + 6] & 0xff))]
^ table[0][(int) ((value >>> 56) ^ b[idx + 7] & 0xff)];
idx += 8;
len -= 8;
}
while (len > 0)
{
value = table[0][(int) ((value ^ b[idx]) & 0xff)] ^ (value >>> 8);
idx++;
len--;
}
return ~value;
}
}

View File

@ -14,6 +14,8 @@ import net.kdt.pojavlaunch.multirt.Runtime;
import net.kdt.pojavlaunch.prefs.*;
import net.kdt.pojavlaunch.utils.*;
import net.kdt.pojavlaunch.value.*;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.apache.commons.io.*;
@ -89,19 +91,40 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
//Now we have the reliable information to check if our runtime settings are good enough
if(verInfo.javaVersion != null) { //1.17+
String selectedRuntime = null;
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
PerVersionConfig.update();
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(p1[0]);
if(cfg == null) {
if (cfg == null) {
cfg = new PerVersionConfig.VersionConfig();
PerVersionConfig.configMap.put(p1[0],cfg);
PerVersionConfig.configMap.put(p1[0], cfg);
}
Runtime runtime = cfg.selectedRuntime != null?MultiRTUtils.read(cfg.selectedRuntime):MultiRTUtils.read(LauncherPreferences.PREF_DEFAULT_RUNTIME);
if(runtime.javaVersion < verInfo.javaVersion.majorVersion) {
String appropriateRuntime = MultiRTUtils.getNearestJreName(verInfo.javaVersion.majorVersion);
}else{
LauncherProfiles.update();
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(mActivity.mProfile.selectedProfile);
if(prof == null) throw new SilentException();
if(prof.javaDir != null && prof.javaDir.startsWith(Tools.LAUNCHERPROFILES_RTPREFIX)) {
selectedRuntime = prof.javaDir.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length());
}
}
MultiRTUtils.Runtime r = selectedRuntime != null?MultiRTUtils.read(selectedRuntime):MultiRTUtils.read(LauncherPreferences.PREF_DEFAULT_RUNTIME);
if(r.javaVersion < verInfo.javaVersion.majorVersion) {
String appropriateRuntime = MultiRTUtils.getNearestJREName(verInfo.javaVersion.majorVersion);
if(appropriateRuntime != null) {
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(p1[0]);
if (cfg == null) {
cfg = new PerVersionConfig.VersionConfig();
PerVersionConfig.configMap.put(p1[0], cfg);
}
cfg.selectedRuntime = appropriateRuntime;
PerVersionConfig.update();
}else{
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(mActivity.mProfile.selectedProfile);
if(prof == null) throw new SilentException();
prof.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX+appropriateRuntime;
LauncherProfiles.update();
}
}else{
mActivity.runOnUiThread(()->{
AlertDialog.Builder bldr = new AlertDialog.Builder(mActivity);
@ -378,6 +401,8 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
mActivity.startActivity(mainIntent);
mActivity.finish();
Log.i("ActCheck","mainActivity finishing="+mActivity.isFinishing()+", destroyed="+mActivity.isDestroyed());
}
catch (Throwable e) {
Tools.showError(mActivity, 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.extra.ExtraCore;
import net.kdt.pojavlaunch.extra.ExtraListener;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
import net.kdt.pojavlaunch.prefs.*;
@ -41,6 +43,8 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
Log.i("ExtVL", "Syncing to external: " + url);
list = Tools.GLOBAL_GSON.fromJson(DownloadUtils.downloadString(url), JMinecraftVersionList.class);
Log.i("ExtVL","Downloaded the version list, len="+list.versions.length);
if(list.latest != null && ExtraCore.getValue("release_table") == null)
ExtraCore.setValue("release_table",list.latest);
Collections.addAll(versions,list.versions);
}
mActivity.mVersionList = new JMinecraftVersionList();
@ -60,55 +64,7 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
protected void onPostExecute(ArrayList<String> result)
{
super.onPostExecute(result);
final PopupMenu popup = new PopupMenu(mActivity, mActivity.mVersionSelector);
popup.getMenuInflater().inflate(R.menu.menu_versionopt, popup.getMenu());
if(result != null && result.size() > 0) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, result);
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
mActivity.mVersionSelector.setAdapter(adapter);
mActivity.mVersionSelector.setSelection(selectAt(result.toArray(new String[0]), mActivity.mProfile.selectedVersion));
} else {
mActivity.mVersionSelector.setSelection(selectAt(mActivity.mAvailableVersions, mActivity.mProfile.selectedVersion));
}
PerVersionConfigDialog dialog = new PerVersionConfigDialog(this.mActivity);
mActivity.mVersionSelector.setOnLongClickListener((v)->dialog.openConfig(mActivity.mProfile.selectedVersion));
mActivity.mVersionSelector.setOnItemSelectedListener(new OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
{
mActivity.mProfile.selectedVersion = p1.getItemAtPosition(p3).toString();
PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile);
if (PojavProfile.isFileType(mActivity)) {
try {
PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile.save());
} catch (IOException e) {
Tools.showError(mActivity, e);
}
}
}
@Override
public void onNothingSelected(AdapterView<?> p1)
{
// TODO: Implement this method
}
});
/*mActivity.mVersionSelector.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> p1, View p2, int p3, long p4)
{
// Implement copy, remove, reinstall,...
return true;
}
});
*/
popup.setOnMenuItemClickListener(item -> true);
ExtraCore.setValue("lac_version_list",result);
}
private ArrayList<String> filter(JMinecraftVersionList.Version[] list1, File[] list2) {
@ -133,7 +89,17 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
return output;
}
private int selectAt(String[] strArr, String select) {
public static int selectAt(String[] strArr, String select) {
int count = 0;
for(String str : strArr){
if (str.equals(select)) {
return count;
}
count++;
}
return -1;
}
public static int selectAt(List<String> strArr, String select) {
int count = 0;
for(String str : strArr){
if (str.equals(select)) {

View File

@ -7,11 +7,14 @@ import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import net.kdt.pojavlaunch.BaseLauncherActivity;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
import net.kdt.pojavlaunch.tasks.MinecraftDownloaderTask;
import net.kdt.pojavlaunch.value.PerVersionConfig;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import org.apache.commons.io.IOUtils;
@ -105,11 +108,25 @@ public class V117CompatUtil {
public static void runCheck(String version, Activity ctx) throws Exception{
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(version);
MCOptionUtils.load();
List<String> packList =getTexturePackList(MCOptionUtils.get("resourcePacks"));
String renderer = cfg != null && cfg.renderer != null?cfg.renderer:LauncherPreferences.PREF_RENDERER;
String renderer;
String gamePath;
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
PerVersionConfig.update();
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(version);
renderer = cfg != null && cfg.renderer != null?cfg.renderer:LauncherPreferences.PREF_RENDERER;
gamePath = cfg != null && cfg.gamePath != null?cfg.gamePath:Tools.DIR_GAME_NEW;
}else{
LauncherProfiles.update();
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(((BaseLauncherActivity)ctx).mProfile.selectedProfile);
if(prof == null) throw new MinecraftDownloaderTask.SilentException();
renderer = prof.__P_renderer_name != null?prof.__P_renderer_name:LauncherPreferences.PREF_RENDERER;
gamePath = prof.gameDir != null?prof.gameDir:Tools.DIR_GAME_NEW;
}
//String
if(renderer.equals("vulkan_zink") || renderer.equals("opengles3_virgl")) return; //don't install for zink/virgl users;
if(packList.contains("\"assets-v0.zip\"") && renderer.equals("opengles3")) return;
@ -143,14 +160,21 @@ public class V117CompatUtil {
}
switch(proceed.get()) {
case 1:
if(!LauncherPreferences.PREF_ENABLE_PROFILES) {
PerVersionConfig.VersionConfig cfg = PerVersionConfig.configMap.get(version);
if (cfg == null) {
cfg = new PerVersionConfig.VersionConfig();
PerVersionConfig.configMap.put(version, cfg);
}
cfg.renderer = "opengles3";
String path = Tools.DIR_GAME_NEW;
if(cfg.gamePath != null && !cfg.gamePath.isEmpty()) path = cfg.gamePath;
copyResourcePack(path,ctx.getAssets());
PerVersionConfig.update();
}else{
MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(((BaseLauncherActivity)ctx).mProfile.selectedProfile);
if(prof == null) throw new MinecraftDownloaderTask.SilentException();
prof.__P_renderer_name = "opengles3";
LauncherProfiles.update();
}
copyResourcePack(gamePath,ctx.getAssets());
if(!packList.contains("\"assets-v0.zip\"")) packList.add(0,"\"assets-v0.zip\"");
MCOptionUtils.set("resourcePacks",regenPackList(packList));
MCOptionUtils.save();

View File

@ -18,6 +18,7 @@ public class MinecraftAccount
public String profileId = "00000000-0000-0000-0000-000000000000"; // profile UUID, for obtaining skin
public String username = "Steve";
public String selectedVersion = "1.7.10";
public String selectedProfile = "";
public boolean isMicrosoft = false;
public String msaRefreshToken = "0";
public String skinFaceBase64;

View File

@ -13,5 +13,6 @@ public class MinecraftProfile
public String javaArgs;
public String logConfig;
public boolean logConfigIsXML;
public String __P_renderer_name;
public MinecraftResolution[] resolution;
}

View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/vprof_editor_icon"
android:layout_width="0dp"
android:layout_height="32dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/vprof_editor_toptxv"
app:srcCompat="@drawable/ic_menu_java" />
<TextView
android:id="@+id/vprof_editor_toptxv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/profiles_editing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/vprof_editor_profile_name_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/profiles_profile_name"
app:layout_constraintBottom_toTopOf="@+id/vprof_editior_profile_name"
app:layout_constraintStart_toStartOf="@+id/vprof_editior_profile_name" />
<EditText
android:id="@+id/vprof_editior_profile_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:ems="10"
android:hint="@string/unnamed"
android:inputType="textPersonName"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/vprof_editor_icon" />
<Spinner
android:id="@+id/vprof_editor_version_spinner"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="16dp"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/vprof_editior_profile_name" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/profiles_profile_version"
app:layout_constraintBottom_toTopOf="@+id/vprof_editor_version_spinner"
app:layout_constraintStart_toStartOf="@+id/vprof_editor_version_spinner" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pedit_java_runtime"
app:layout_constraintBottom_toTopOf="@+id/vprof_editor_spinner_runtime"
app:layout_constraintStart_toStartOf="@+id/vprof_editor_spinner_runtime" />
<Spinner
android:id="@+id/vprof_editor_spinner_runtime"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="@+id/vprof_editor_version_spinner"
app:layout_constraintStart_toStartOf="@+id/vprof_editor_version_spinner"
app:layout_constraintTop_toBottomOf="@+id/vprof_editor_version_spinner" />
<Spinner
android:id="@+id/vprof_editor_profile_renderer"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:minHeight="48dp"
app:layout_constraintEnd_toEndOf="@+id/vprof_editor_spinner_runtime"
app:layout_constraintStart_toStartOf="@+id/vprof_editor_spinner_runtime"
app:layout_constraintTop_toBottomOf="@+id/vprof_editor_spinner_runtime" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/vprof_editor_profile_renderer"
app:layout_constraintStart_toStartOf="@+id/vprof_editor_profile_renderer" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?attr/selectableItemBackground"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/vprof_icon_view"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginStart="4dp"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_menu_java" />
<TextView
android:id="@+id/vprof_profile_name_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:text="@android:string/unknownName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@+id/vprof_icon_view"
app:layout_constraintTop_toTopOf="@+id/vprof_icon_view" />
<TextView
android:id="@+id/vprof_version_id_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@android:string/unknownName"
android:textSize="8sp"
app:layout_constraintBottom_toBottomOf="@+id/vprof_icon_view"
app:layout_constraintStart_toStartOf="@+id/vprof_profile_name_view"
app:layout_constraintTop_toBottomOf="@+id/vprof_profile_name_view" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -283,9 +283,19 @@
<string name="gles_hack_none">Don\'t shrink textures</string>
<string name="gles_hack_always">Divides all textures by 2</string>
<string name="gles_hack_sometimes">Divides big textures by /2 or /4</string>
<string name="unnamed">Unnamed</string>
<string name="profiles_latest_snapshot">Latest snapshot</string>
<string name="profiles_latest_release">Latest release</string>
<string name="profiles_editing">Editing profile</string>
<string name="profiles_profile_name">Name</string>
<string name="profiles_profile_version">Version</string>
<string name="option_enable_profiles">Profiles</string>
<string name="option_enable_profiles_descritption">Use Minecraft Launcher profiles instead of the regular version list. Supports icons!</string>
<string name="vbo_hack_title">Disable VBOs</string>
<string name="vbo_hack_description">Help with compatibility on some old versions</string>
<string name="global_delete">Delete</string>
<string name="pedit_java_runtime">Java Runtime</string>
<string name="pedit_renderer">Renderer</string>
<string name="gles_version_hack_title">Force openGL 1</string>
<string name="gles_version_hack_description">Help with compatibility on some old versions</string>
<string name="arc_capes_title">Arc Capes</string>

View File

@ -18,6 +18,11 @@
android:defaultValue="false"
android:key="vbo_disable_hack"
/>
<CheckBoxPreference
android:defaultValue="false"
android:key="enable_profiles"
android:title="@string/option_enable_profiles"
android:summary="@string/option_enable_profiles_descritption"/>
<SwitchPreference
android:title="@string/gles_version_hack_title"