diff --git a/app_pojavlauncher/src/main/AndroidManifest.xml b/app_pojavlauncher/src/main/AndroidManifest.xml index 8e0710c5d..745a4a760 100644 --- a/app_pojavlauncher/src/main/AndroidManifest.xml +++ b/app_pojavlauncher/src/main/AndroidManifest.xml @@ -49,33 +49,10 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app_pojavlauncher/src/main/assets/plugins/MobileClientBindings.zip b/app_pojavlauncher/src/main/assets/plugins/MobileClientBindings.zip index 04e1c5dd1..1467b22ef 100644 Binary files a/app_pojavlauncher/src/main/assets/plugins/MobileClientBindings.zip and b/app_pojavlauncher/src/main/assets/plugins/MobileClientBindings.zip differ diff --git a/app_pojavlauncher/src/main/assets/rt4.jar b/app_pojavlauncher/src/main/assets/rt4.jar index a9de508d4..1e0418fa9 100644 Binary files a/app_pojavlauncher/src/main/assets/rt4.jar and b/app_pojavlauncher/src/main/assets/rt4.jar differ diff --git a/app_pojavlauncher/src/main/ic_launcher-playstore.png b/app_pojavlauncher/src/main/ic_launcher-playstore.png new file mode 100644 index 000000000..36a7edc7f Binary files /dev/null and b/app_pojavlauncher/src/main/ic_launcher-playstore.png differ diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java deleted file mode 100644 index 8d5c65f46..000000000 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineButton.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.kdt.mcgui; - -import android.content.*; -import android.graphics.*; -import android.util.*; - -import androidx.core.content.res.ResourcesCompat; - -import net.kdt.pojavlaunch.R; - -public class MineButton extends androidx.appcompat.widget.AppCompatButton { - - public MineButton(Context ctx) { - this(ctx, null); - } - - public MineButton(Context ctx, AttributeSet attrs) { - super(ctx, attrs); - init(); - } - - public void init() { - setTypeface(ResourcesCompat.getFont(getContext(), R.font.noto_sans_bold)); - setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.mine_button_background, null)); - setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen._13ssp)); - } - -} diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java deleted file mode 100644 index 5b1bc75c3..000000000 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/MineEditText.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.kdt.mcgui; - -import android.content.*; -import android.util.*; -import android.graphics.*; -import android.widget.EditText; - -public class MineEditText extends androidx.appcompat.widget.AppCompatEditText { - public MineEditText(Context ctx) { - super(ctx); - init(); - } - - public MineEditText(Context ctx, AttributeSet attrs) { - super(ctx, attrs); - init(); - } - - public void init() { - setBackgroundColor(Color.parseColor("#131313")); - setPadding(5, 5, 5, 5); - } -} diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcAccountSpinner.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcAccountSpinner.java deleted file mode 100644 index 79df93aff..000000000 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcAccountSpinner.java +++ /dev/null @@ -1,328 +0,0 @@ -package com.kdt.mcgui; - -import android.animation.ObjectAnimator; -import android.annotation.SuppressLint; -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.drawable.BitmapDrawable; -import android.net.Uri; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Toast; - -import androidx.annotation.Keep; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.AppCompatSpinner; - - -import net.kdt.pojavlaunch.PojavProfile; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.authenticator.listener.DoneListener; -import net.kdt.pojavlaunch.authenticator.listener.ErrorListener; -import net.kdt.pojavlaunch.authenticator.listener.ProgressListener; -import net.kdt.pojavlaunch.authenticator.microsoft.PresentedException; -import net.kdt.pojavlaunch.authenticator.microsoft.MicrosoftBackgroundLogin; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.extra.ExtraListener; -import net.kdt.pojavlaunch.value.MinecraftAccount; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import fr.spse.extended_view.ExtendedTextView; - -public class mcAccountSpinner extends AppCompatSpinner implements AdapterView.OnItemSelectedListener { - public mcAccountSpinner(@NonNull Context context) { - this(context, null); - } - public mcAccountSpinner(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - - private final List mAccountList = new ArrayList<>(2); - private MinecraftAccount mSelectecAccount = null; - - /* Display the head of the current profile, here just to allow bitmap recycling */ - private BitmapDrawable mHeadDrawable; - - /* Current animator to for the login bar, is swapped when changing step */ - private ObjectAnimator mLoginBarAnimator; - private float mLoginBarWidth = -1; - - /* Paint used to display the bottom bar, to show the login progress. */ - private final Paint mLoginBarPaint = new Paint(); - - /* When a login is performed in the background, we need to know where we are */ - private final static int MAX_LOGIN_STEP = 5; - private int mLoginStep = 0; - - /* Login listeners */ - private final ProgressListener mProgressListener = step -> { - // Animate the login bar, cosmetic purposes only - mLoginStep = step; - if(mLoginBarAnimator != null){ - mLoginBarAnimator.cancel(); - mLoginBarAnimator.setFloatValues( mLoginBarWidth, (getWidth()/MAX_LOGIN_STEP * mLoginStep)); - }else{ - mLoginBarAnimator = ObjectAnimator.ofFloat(this, "LoginBarWidth", mLoginBarWidth, (getWidth()/MAX_LOGIN_STEP * mLoginStep)); - } - mLoginBarAnimator.start(); - }; - - private final DoneListener mDoneListener = account -> { - Toast.makeText(getContext(), R.string.main_login_done, Toast.LENGTH_SHORT).show(); - - // Check if the account being added is not one that is already existing - // Like login twice on the same mc account... - for(String mcAccountName : mAccountList){ - if(mcAccountName.equals(account.username)) return; - } - - mSelectecAccount = account; - invalidate(); - mAccountList.add(account.username); - reloadAccounts(false, mAccountList.size() -1); - }; - - private final ErrorListener mErrorListener = errorMessage -> { - mLoginBarPaint.setColor(Color.RED); - if(errorMessage instanceof PresentedException) { - PresentedException exception = (PresentedException) errorMessage; - Tools.showError(getContext(), exception.toString(getContext()), exception.getCause()); - }else { - Tools.showError(getContext(), errorMessage); - } - invalidate(); - }; - - /* Triggered when we need to do microsoft login */ - private final ExtraListener mMicrosoftLoginListener = (key, value) -> { - mLoginBarPaint.setColor(getResources().getColor(R.color.minebutton_color)); - new MicrosoftBackgroundLogin(false, value.getQueryParameter("code")).performLogin( - mProgressListener, mDoneListener, mErrorListener); - return false; - }; - - /* Triggered when we need to perform mojang login */ - private final ExtraListener mMojangLoginListener = (key, value) -> { - if(value[1].isEmpty()){ // Test mode - MinecraftAccount account = new MinecraftAccount(); - account.username = value[0]; - try { - account.save(); - }catch (IOException e){ - Log.e("McAccountSpinner", "Failed to save the account : " + e); - } - - mDoneListener.onLoginDone(account); - } - return false; - }; - - - @SuppressLint("ClickableViewAccessibility") - private void init(){ - // Set visual properties - setBackgroundColor(getResources().getColor(R.color.background_status_bar)); - mLoginBarPaint.setColor(getResources().getColor(R.color.minebutton_color)); - mLoginBarPaint.setStrokeWidth(getResources().getDimensionPixelOffset(R.dimen._2sdp)); - - // Set behavior - reloadAccounts(true, 0); - setOnItemSelectedListener(this); - - ExtraCore.addExtraListener(ExtraConstants.MOJANG_LOGIN_TODO, mMojangLoginListener); - ExtraCore.addExtraListener(ExtraConstants.MICROSOFT_LOGIN_TODO, mMicrosoftLoginListener); - } - - - @Override - public final void onItemSelected(AdapterView parent, View view, int position, long id) { - if(position == 0){ // Add account button - if(mAccountList.size() > 1){ - ExtraCore.setValue(ExtraConstants.SELECT_AUTH_METHOD, true); - } - return; - } - - pickAccount(position); - if(mSelectecAccount != null) - performLogin(mSelectecAccount); - } - - @Override - public final void onNothingSelected(AdapterView parent) {} - - - @Override - protected void onDraw(Canvas canvas) { - if(mLoginBarWidth == -1) mLoginBarWidth = getWidth(); // Initial draw - - float bottom = getHeight() - mLoginBarPaint.getStrokeWidth()/2; - canvas.drawLine(0, bottom, mLoginBarWidth, bottom, mLoginBarPaint); - } - - public void removeCurrentAccount(){ - int position = getSelectedItemPosition(); - if(position == 0) return; - File accountFile = new File(Tools.DIR_ACCOUNT_NEW, mAccountList.get(position)+".json"); - if(accountFile.exists()) accountFile.delete(); - mAccountList.remove(position); - - reloadAccounts(false, 0); - } - - @Keep - public void setLoginBarWidth(float value){ - mLoginBarWidth = value; - invalidate(); // Need to redraw each time this is changed - } - - /** Allows checking whether we have an online account */ - public boolean isAccountOnline(){ - return mSelectecAccount != null && !mSelectecAccount.accessToken.equals("0"); - } - - public MinecraftAccount getSelectedAccount(){ - return mSelectecAccount; - } - - public int getLoginState(){ - return mLoginStep; - } - - public boolean isLoginDone(){ - return mLoginStep >= MAX_LOGIN_STEP; - } - - @SuppressLint("ClickableViewAccessibility") - private void setNoAccountBehavior(){ - // Set custom behavior when no account are present, to make it act as a button - if(mAccountList.size() != 1){ - // Remove any touch listener - setOnTouchListener(null); - return; - } - - // Make the spinner act like a button, since there is no item to really select - setOnTouchListener((v, event) -> { - if(event.getAction() != MotionEvent.ACTION_UP) return false; - // The activity should intercept this and spawn another fragment - ExtraCore.setValue(ExtraConstants.SELECT_AUTH_METHOD, true); - return true; - }); - } - - /** - * Reload the spinner, from memory or from scratch. A default account can be selected - * @param fromFiles Whether we use files as the source of truth - * @param overridePosition Force the spinner to be at this position, if not 0 - */ - private void reloadAccounts(boolean fromFiles, int overridePosition){ - if(fromFiles){ - mAccountList.clear(); - - mAccountList.add(getContext().getString(R.string.main_add_account)); - File accountFolder = new File(Tools.DIR_ACCOUNT_NEW); - if(accountFolder.exists()){ - for (String fileName : accountFolder.list()) { - mAccountList.add(fileName.substring(0, fileName.length() - 5)); - } - } - } - - String[] accountArray = mAccountList.toArray(new String[0]); - ArrayAdapter accountAdapter = new ArrayAdapter<>(getContext(), R.layout.item_minecraft_account, accountArray); - accountAdapter.setDropDownViewResource(R.layout.item_minecraft_account); - setAdapter(accountAdapter); - - // Pick what's available, might just be the the add account "button" - pickAccount(overridePosition == 0 ? -1 : overridePosition); - if(mSelectecAccount != null) - performLogin(mSelectecAccount); - - // Remove or add the behavior if needed - setNoAccountBehavior(); - - } - - private void performLogin(MinecraftAccount minecraftAccount){ - if(minecraftAccount.isLocal()) return; - - mLoginBarPaint.setColor(getResources().getColor(R.color.minebutton_color)); - if(minecraftAccount.isMicrosoft){ - if(System.currentTimeMillis() > minecraftAccount.expiresAt){ - // Perform login only if needed - new MicrosoftBackgroundLogin(true, minecraftAccount.msaRefreshToken) - .performLogin(mProgressListener, mDoneListener, mErrorListener); - } - return; - } - } - - /** Pick the selected account, the one in settings if 0 is passed */ - private void pickAccount(int position){ - MinecraftAccount selectedAccount; - if(position != -1){ - PojavProfile.setCurrentProfile(getContext(), mAccountList.get(position)); - selectedAccount = PojavProfile.getCurrentProfileContent(getContext(), mAccountList.get(position)); - - - // WORKAROUND - // Account file corrupted due to previous versions having improper encoding - if (selectedAccount == null){ - removeCurrentAccount(); - pickAccount(-1); - setSelection(0); - return; - } - setSelection(position); - }else { - // Get the current profile, or the first available profile if the wanted one is unavailable - selectedAccount = PojavProfile.getCurrentProfileContent(getContext(), null); - int spinnerPosition = selectedAccount == null - ? mAccountList.size() <= 1 ? 0 : 1 - : mAccountList.indexOf(selectedAccount.username); - setSelection(spinnerPosition, false); - } - - mSelectecAccount = selectedAccount; - BitmapDrawable oldBitmapDrawable = mHeadDrawable; - - if(mSelectecAccount != null){ - ExtendedTextView view = ((ExtendedTextView) getSelectedView()); - if(view != null){ - Bitmap bitmap = mSelectecAccount.getSkinFace(); - if(bitmap != null) { - mHeadDrawable = new BitmapDrawable(bitmap); - mHeadDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight()); - - view.setCompoundDrawables(mHeadDrawable, null, null, null); - view.postProcessDrawables(); - }else{ - view.setCompoundDrawables(null, null, null, null); - view.postProcessDrawables(); - } - } - } - - if(oldBitmapDrawable != null){ - oldBitmapDrawable.getBitmap().recycle(); - } - - } - -} diff --git a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java b/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java deleted file mode 100644 index d0cd464c2..000000000 --- a/app_pojavlauncher/src/main/java/com/kdt/mcgui/mcVersionSpinner.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.kdt.mcgui; - -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static net.kdt.pojavlaunch.fragments.ProfileEditorFragment.DELETED_PROFILE; - -import android.annotation.SuppressLint; -import android.content.Context; -import android.os.Build; -import android.transition.Slide; -import android.transition.Transition; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.widget.ListView; -import android.widget.PopupWindow; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.FragmentActivity; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.fragments.ProfileTypeSelectFragment; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; -import net.kdt.pojavlaunch.profiles.ProfileAdapter; -import net.kdt.pojavlaunch.profiles.ProfileAdapterExtra; - -import fr.spse.extended_view.ExtendedTextView; - -/** - * A class implementing custom spinner like behavior, notably: - * dropdown popup view with a custom direction. - */ -public class mcVersionSpinner extends ExtendedTextView { - private static final int VERSION_SPINNER_PROFILE_CREATE = 0; - private static final int VERSION_SPINNER_PROFILE_CREATE_MODDED = 1; - public mcVersionSpinner(@NonNull Context context) { - super(context); - init(); - } - public mcVersionSpinner(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - public mcVersionSpinner(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - /* The class is in charge of displaying its own list with adapter content being known in advance */ - private ListView mListView = null; - private PopupWindow mPopupWindow = null; - private Object mPopupAnimation; - private final ProfileAdapter mProfileAdapter = new ProfileAdapter(getContext(), new ProfileAdapterExtra[]{ - new ProfileAdapterExtra(VERSION_SPINNER_PROFILE_CREATE, - R.string.create_profile, - ResourcesCompat.getDrawable(getResources(), R.drawable.ic_add, null)), - }); - - - /** Set the selection AND saves it as a shared preference */ - public void setProfileSelection(int position){ - setSelection(position); - LauncherPreferences.DEFAULT_PREF.edit() - .putString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, - mProfileAdapter.getItem(position).toString()) - .apply(); - } - - public void setSelection(int position){ - if(mListView != null) mListView.setSelection(position); - mProfileAdapter.setViewProfile(this, (String) mProfileAdapter.getItem(position), false); - } - - /** Initialize various behaviors */ - private void init(){ - // Setup various attributes - setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimensionPixelSize(R.dimen._12ssp)); - setGravity(Gravity.CENTER_VERTICAL); - int startPadding = getContext().getResources().getDimensionPixelOffset(R.dimen._17sdp); - int endPadding = getContext().getResources().getDimensionPixelOffset(R.dimen._5sdp); - setPaddingRelative(startPadding, 0, endPadding, 0); - setCompoundDrawablePadding(startPadding); - - int profileIndex; - String extra_value = (String) ExtraCore.consumeValue(ExtraConstants.REFRESH_VERSION_SPINNER); - if(extra_value != null){ - profileIndex = extra_value.equals(DELETED_PROFILE) ? 0 - : getProfileAdapter().resolveProfileIndex(extra_value); - }else - profileIndex = mProfileAdapter.resolveProfileIndex( - LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,"")); - - setProfileSelection(Math.max(0,profileIndex)); - - // Popup window behavior - setOnClickListener(new OnClickListener() { - final int offset = -getContext().getResources().getDimensionPixelOffset(R.dimen._4sdp); - @Override - public void onClick(View v) { - if(mPopupWindow == null) getPopupWindow(); - - if(mPopupWindow.isShowing()){ - mPopupWindow.dismiss(); - return; - } - mPopupWindow.showAsDropDown(mcVersionSpinner.this, 0, offset); - } - }); - } - - - /** Create the listView and popup window for the interface, and set up the click behavior */ - @SuppressLint("ClickableViewAccessibility") - private void getPopupWindow(){ - mListView = (ListView) inflate(getContext(), R.layout.spinner_mc_version, null); - mListView.setAdapter(mProfileAdapter); - mListView.setOnItemClickListener((parent, view, position, id) -> { - Object item = mProfileAdapter.getItem(position); - if(item instanceof String) { - hidePopup(true); - setProfileSelection(position); - }else if(item instanceof ProfileAdapterExtra) { - hidePopup(false); - ProfileAdapterExtra extra = (ProfileAdapterExtra) item; - switch (extra.id) { - case VERSION_SPINNER_PROFILE_CREATE: - Tools.swapFragment((FragmentActivity) getContext(), ProfileTypeSelectFragment.class, - ProfileTypeSelectFragment.TAG, true, null); - break; - } - } - }); - - mPopupWindow = new PopupWindow(mListView, MATCH_PARENT, getContext().getResources().getDimensionPixelOffset(R.dimen._184sdp)); - mPopupWindow.setElevation(5); - mPopupWindow.setClippingEnabled(false); - - // Block clicking outside of the popup window - mPopupWindow.setOutsideTouchable(true); - mPopupWindow.setFocusable(true); - mPopupWindow.setTouchInterceptor((v, event) -> { - if(event.getAction() == MotionEvent.ACTION_OUTSIDE){ - mPopupWindow.dismiss(); - return true; - } - return false; - }); - - - // Custom animation, nice slide in - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ - mPopupAnimation = new Slide(Gravity.BOTTOM); - mPopupWindow.setEnterTransition((Transition) mPopupAnimation); - mPopupWindow.setExitTransition((Transition) mPopupAnimation); - } - } - - private void hidePopup(boolean animate) { - if(mPopupWindow == null) return; - if(!animate && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - mPopupWindow.setEnterTransition(null); - mPopupWindow.setExitTransition(null); - mPopupWindow.dismiss(); - mPopupWindow.setEnterTransition((Transition) mPopupAnimation); - mPopupWindow.setExitTransition((Transition) mPopupAnimation); - }else { - mPopupWindow.dismiss(); - } - } - - public ProfileAdapter getProfileAdapter() { - return mProfileAdapter; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java index 429d8e764..5fb1802e5 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/FatalErrorActivity.java @@ -24,7 +24,7 @@ public class FatalErrorActivity extends AppCompatActivity { .setTitle(R.string.error_fatal) .setMessage(errHeader + "\n\n" + stackTrace) .setPositiveButton(android.R.string.ok, (p1, p2) -> finish()) - .setNegativeButton(R.string.global_restart, (p1, p2) -> startActivity(new Intent(FatalErrorActivity.this, LauncherActivity.class))) + .setNegativeButton(R.string.global_restart, (p1, p2) -> startActivity(new Intent(FatalErrorActivity.this, DummyLauncher.class))) .setNeutralButton(android.R.string.copy, (p1, p2) -> { ClipboardManager mgr = (ClipboardManager) FatalErrorActivity.this.getSystemService(CLIPBOARD_SERVICE); mgr.setPrimaryClip(ClipData.newPlainText("error", stackTrace)); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java deleted file mode 100644 index a3739dbd5..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/ImportControlActivity.java +++ /dev/null @@ -1,187 +0,0 @@ -package net.kdt.pojavlaunch; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.Toast; - -import androidx.annotation.Nullable; - -import net.kdt.pojavlaunch.utils.FileUtils; - -import org.apache.commons.io.IOUtils; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -/** - * An activity dedicated to importing control files. - */ -@SuppressWarnings("IOStreamConstructor") -public class ImportControlActivity extends Activity { - - private Uri mUriData; - private boolean mHasIntentChanged = true; - private volatile boolean mIsFileVerified = false; - - private EditText mEditText; - - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - Tools.initContextConstants(getApplicationContext()); - - setContentView(R.layout.activity_import_control); - mEditText = findViewById(R.id.editText_import_control_file_name); - } - - /** - * Override the previous loaded intent - * @param intent the intent used to replace the old one. - */ - @Override - protected void onNewIntent(Intent intent) { - if(intent != null) setIntent(intent); - mHasIntentChanged = true; - } - - /** - * Update all over again if the intent changed. - */ - @Override - protected void onPostResume() { - super.onPostResume(); - if(!mHasIntentChanged) return; - mIsFileVerified = false; - getUriData(); - if(mUriData == null) { - finishAndRemoveTask(); - return; - } - mEditText.setText(trimFileName(Tools.getFileName(this, mUriData))); - mHasIntentChanged = false; - - //Import and verify thread - //Kill the app if the file isn't valid. - new Thread(() -> { - importControlFile(); - - if(verify())mIsFileVerified = true; - else runOnUiThread(() -> { - Toast.makeText( - ImportControlActivity.this, - getText(R.string.import_control_invalid_file), - Toast.LENGTH_SHORT).show(); - finishAndRemoveTask(); - }); - }).start(); - - //Auto show the keyboard - Tools.MAIN_HANDLER.postDelayed(() -> { - InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE); - imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0); - mEditText.setSelection(mEditText.getText().length()); - }, 100); - } - - /** - * Start the import. - * @param view the view which called the function - */ - public void startImport(View view) { - String fileName = trimFileName(mEditText.getText().toString()); - //Step 1 check for suffixes. - if(!isFileNameValid(fileName)){ - Toast.makeText(this, getText(R.string.import_control_invalid_name), Toast.LENGTH_SHORT).show(); - return; - } - if(!mIsFileVerified){ - Toast.makeText(this, getText(R.string.import_control_verifying_file), Toast.LENGTH_LONG).show(); - return; - } - - new File(Tools.CTRLMAP_PATH + "/TMP_IMPORT_FILE.json").renameTo(new File(Tools.CTRLMAP_PATH + "/" + fileName + ".json")); - Toast.makeText(getApplicationContext(), getText(R.string.import_control_done), Toast.LENGTH_SHORT).show(); - finishAndRemoveTask(); - } - - /** - * Copy a the file from the Intent data with a provided name into the controlmap folder. - */ - private void importControlFile(){ - InputStream is; - try { - is = getContentResolver().openInputStream(mUriData); - OutputStream os = new FileOutputStream(Tools.CTRLMAP_PATH + "/" + "TMP_IMPORT_FILE" + ".json"); - IOUtils.copy(is, os); - - os.close(); - is.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Tell if the clean version of the filename is valid. - * @param fileName the string to test - * @return whether the filename is valid - */ - private static boolean isFileNameValid(String fileName){ - fileName = trimFileName(fileName); - - if(fileName.isEmpty()) return false; - return !FileUtils.exists(Tools.CTRLMAP_PATH + "/" + fileName + ".json"); - } - - /** - * Remove or undesirable chars from the string - * @param fileName The string to trim - * @return The trimmed string - */ - private static String trimFileName(String fileName){ - return fileName - .replace(".json", "") - .replaceAll("%..", "/") - .replace("/", "") - .replace("\\", "") - .trim(); - } - - /** - * Tries to get an Uri from the various sources - */ - private void getUriData(){ - mUriData = getIntent().getData(); - if(mUriData != null) return; - try { - mUriData = getIntent().getClipData().getItemAt(0).getUri(); - }catch (Exception ignored){} - } - - /** - * Verify if the control file is valid - * @return Whether the control file is valid - */ - private static boolean verify(){ - try{ - String jsonLayoutData = Tools.read(Tools.CTRLMAP_PATH + "/TMP_IMPORT_FILE.json"); - JSONObject layoutJobj = new JSONObject(jsonLayoutData); - return layoutJobj.has("version") && layoutJobj.has("mControlDataList"); - }catch (JSONException | IOException e) { - e.printStackTrace(); - return false; - } - } - -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java index 5b753efa5..c34892017 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JMinecraftVersionList.java @@ -2,7 +2,6 @@ package net.kdt.pojavlaunch; import androidx.annotation.Keep; import java.util.*; -import net.kdt.pojavlaunch.value.*; @Keep @SuppressWarnings("unused") // all unused fields here are parts of JSON structures @@ -23,10 +22,8 @@ public class JMinecraftVersionList { public AssetIndex assetIndex; public String assets; - public Map downloads; public String inheritsFrom; public JavaVersionInfo javaVersion; - public DependentLibrary[] libraries; public LoggingConfig logging; public String mainClass; public String minecraftArguments; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JRE17Util.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JRE17Util.java index f004f1307..d7b778386 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JRE17Util.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/JRE17Util.java @@ -8,8 +8,6 @@ import android.util.Log; import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.Runtime; -import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; -import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; import java.io.IOException; @@ -49,46 +47,6 @@ public class JRE17Util { return NEW_JRE_NAME.equals(runtime.name); } - /** @return true if everything is good, false otherwise. */ - public static boolean installNewJreIfNeeded(Activity activity, JMinecraftVersionList.Version versionInfo) { - //Now we have the reliable information to check if our runtime settings are good enough - if (versionInfo.javaVersion == null || versionInfo.javaVersion.component.equalsIgnoreCase("jre-legacy")) - return true; - - LauncherProfiles.update(); - MinecraftProfile minecraftProfile = LauncherProfiles.getCurrentProfile(); - - String selectedRuntime = Tools.getSelectedRuntime(minecraftProfile); - - Runtime runtime = MultiRTUtils.read(selectedRuntime); - if (runtime.javaVersion >= versionInfo.javaVersion.majorVersion) { - return true; - } - - String appropriateRuntime = MultiRTUtils.getNearestJreName(versionInfo.javaVersion.majorVersion); - if (appropriateRuntime != null) { - if (JRE17Util.isInternalNewJRE(appropriateRuntime)) { - JRE17Util.checkInternalNewJre(activity.getAssets()); - } - minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX + appropriateRuntime; - LauncherProfiles.update(); - } else { - if (versionInfo.javaVersion.majorVersion <= 17) { // there's a chance we have an internal one for this case - if (!JRE17Util.checkInternalNewJre(activity.getAssets())){ - showRuntimeFail(activity, versionInfo); - return false; - } else { - minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX + JRE17Util.NEW_JRE_NAME; - LauncherProfiles.update(); - } - } else { - showRuntimeFail(activity, versionInfo); - return false; - } - } - - return true; - } private static void showRuntimeFail(Activity activity, JMinecraftVersionList.Version verInfo) { Tools.dialogOnUiThread(activity, activity.getString(R.string.global_error), diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java deleted file mode 100644 index d1eb9bafc..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/LauncherActivity.java +++ /dev/null @@ -1,305 +0,0 @@ -package net.kdt.pojavlaunch; - -import static net.kdt.pojavlaunch.MainActivity.INTENT_MINECRAFT_VERSION; - -import android.Manifest; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.ImageButton; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentContainerView; -import androidx.fragment.app.FragmentManager; - -import com.kdt.mcgui.ProgressLayout; -import com.kdt.mcgui.mcAccountSpinner; - -import net.kdt.pojavlaunch.fragments.MainMenuFragment; -import net.kdt.pojavlaunch.fragments.MicrosoftLoginFragment; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.extra.ExtraListener; - -import net.kdt.pojavlaunch.fragments.SelectAuthFragment; -import net.kdt.pojavlaunch.multirt.MultiRTConfigDialog; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; -import net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceFragment; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.services.ProgressServiceKeeper; -import net.kdt.pojavlaunch.tasks.AsyncMinecraftDownloader; -import net.kdt.pojavlaunch.tasks.AsyncVersionList; -import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; -import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; - -public class LauncherActivity extends BaseActivity { - public static final String SETTING_FRAGMENT_TAG = "SETTINGS_FRAGMENT"; - - private final int REQUEST_STORAGE_REQUEST_CODE = 1; - private final Object mLockStoragePerm = new Object(); - - - private mcAccountSpinner mAccountSpinner; - private FragmentContainerView mFragmentView; - private ImageButton mSettingsButton, mDeleteAccountButton; - private ProgressLayout mProgressLayout; - private ProgressServiceKeeper mProgressServiceKeeper; - - /* Allows to switch from one button "type" to another */ - private final FragmentManager.FragmentLifecycleCallbacks mFragmentCallbackListener = new FragmentManager.FragmentLifecycleCallbacks() { - @Override - public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) { - mSettingsButton.setImageDrawable(ContextCompat.getDrawable(getBaseContext(), f instanceof MainMenuFragment - ? R.drawable.ic_menu_settings : R.drawable.ic_menu_home)); - } - }; - - /* Listener for the back button in settings */ - private final ExtraListener mBackPreferenceListener = (key, value) -> { - if(value.equals("true")) onBackPressed(); - return false; - }; - - /* Listener for the auth method selection screen */ - private final ExtraListener mSelectAuthMethod = (key, value) -> { - Fragment fragment = getSupportFragmentManager().findFragmentById(mFragmentView.getId()); - // Allow starting the add account only from the main menu, should it be moved to fragment itself ? - if(!(fragment instanceof MainMenuFragment)) return false; - - Tools.swapFragment(this, SelectAuthFragment.class, SelectAuthFragment.TAG, true, null); - return false; - }; - - /* Listener for the settings fragment */ - private final View.OnClickListener mSettingButtonListener = v -> { - Fragment fragment = getSupportFragmentManager().findFragmentById(mFragmentView.getId()); - if(fragment instanceof MainMenuFragment){ - Tools.swapFragment(this, LauncherPreferenceFragment.class, SETTING_FRAGMENT_TAG, true, null); - } else{ - // The setting button doubles as a home button now - while(!(getSupportFragmentManager().findFragmentById(mFragmentView.getId()) instanceof MainMenuFragment)){ - getSupportFragmentManager().popBackStackImmediate(); - } - } - }; - - /* Listener for account deletion */ - private final View.OnClickListener mAccountDeleteButtonListener = v -> new AlertDialog.Builder(this) - .setMessage(R.string.warning_remove_account) - .setPositiveButton(android.R.string.cancel, null) - .setNeutralButton(R.string.global_delete, (dialog, which) -> mAccountSpinner.removeCurrentAccount()) - .show(); - - private final ExtraListener mLaunchGameListener = (key, value) -> { - if(mProgressLayout.hasProcesses()){ - Toast.makeText(this, R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - return false; - } - - String selectedProfile = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,""); - if (LauncherProfiles.mainProfileJson == null || !LauncherProfiles.mainProfileJson.profiles.containsKey(selectedProfile)){ - Toast.makeText(this, R.string.error_no_version, Toast.LENGTH_LONG).show(); - return false; - } - MinecraftProfile prof = LauncherProfiles.mainProfileJson.profiles.get(selectedProfile); - if (prof == null || prof.lastVersionId == null || "Unknown".equals(prof.lastVersionId)){ - Toast.makeText(this, R.string.error_no_version, Toast.LENGTH_LONG).show(); - return false; - } - - if(mAccountSpinner.getSelectedAccount() == null){ - Toast.makeText(this, R.string.no_saved_accounts, Toast.LENGTH_LONG).show(); - ExtraCore.setValue(ExtraConstants.SELECT_AUTH_METHOD, true); - return false; - } - String normalizedVersionId = AsyncMinecraftDownloader.normalizeVersionId(prof.lastVersionId); - JMinecraftVersionList.Version mcVersion = AsyncMinecraftDownloader.getListedVersion(normalizedVersionId); - new AsyncMinecraftDownloader(this, mcVersion, normalizedVersionId, new AsyncMinecraftDownloader.DoneListener() { - @Override - public void onDownloadDone() { - ProgressKeeper.waitUntilDone(()-> runOnUiThread(() -> { - try { - Intent mainIntent = new Intent(getBaseContext(), MainActivity.class); - mainIntent.putExtra(INTENT_MINECRAFT_VERSION, normalizedVersionId); - mainIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - startActivity(mainIntent); - finish(); - android.os.Process.killProcess(android.os.Process.myPid()); //You should kill yourself, NOW! - } catch (Throwable e) { - Tools.showError(getBaseContext(), e); - } - })); - } - - @Override - public void onDownloadFailed(Throwable th) { - if(th != null) Tools.showError(LauncherActivity.this, R.string.mc_download_failed, th); - } - }); - return false; - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_pojav_launcher); - getWindow().setBackgroundDrawable(null); - bindViews(); - ProgressKeeper.addTaskCountListener((mProgressServiceKeeper = new ProgressServiceKeeper(this))); - askForStoragePermission(); // Will wait here - - mSettingsButton.setOnClickListener(mSettingButtonListener); - mDeleteAccountButton.setOnClickListener(mAccountDeleteButtonListener); - ProgressKeeper.addTaskCountListener(mProgressLayout); - ExtraCore.addExtraListener(ExtraConstants.BACK_PREFERENCE, mBackPreferenceListener); - ExtraCore.addExtraListener(ExtraConstants.SELECT_AUTH_METHOD, mSelectAuthMethod); - - ExtraCore.addExtraListener(ExtraConstants.LAUNCH_GAME, mLaunchGameListener); - - new AsyncVersionList().getVersionList(versions -> ExtraCore.setValue(ExtraConstants.RELEASE_TABLE, versions), false); - - mProgressLayout.observe(ProgressLayout.DOWNLOAD_MINECRAFT); - mProgressLayout.observe(ProgressLayout.UNPACK_RUNTIME); - mProgressLayout.observe(ProgressLayout.INSTALL_MODPACK); - mProgressLayout.observe(ProgressLayout.AUTHENTICATE_MICROSOFT); - mProgressLayout.observe(ProgressLayout.DOWNLOAD_VERSION_LIST); - } - - @Override - public boolean setFullscreen() { - return false; - } - - @Override - protected void onStart() { - super.onStart(); - getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentCallbackListener, true); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - mProgressLayout.cleanUpObservers(); - ProgressKeeper.removeTaskCountListener(mProgressLayout); - ProgressKeeper.removeTaskCountListener(mProgressServiceKeeper); - ExtraCore.removeExtraListenerFromValue(ExtraConstants.BACK_PREFERENCE, mBackPreferenceListener); - ExtraCore.removeExtraListenerFromValue(ExtraConstants.SELECT_AUTH_METHOD, mSelectAuthMethod); - ExtraCore.removeExtraListenerFromValue(ExtraConstants.LAUNCH_GAME, mLaunchGameListener); - - getSupportFragmentManager().unregisterFragmentLifecycleCallbacks(mFragmentCallbackListener); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if(resultCode != RESULT_OK) return; - if(requestCode == Tools.RUN_MOD_INSTALLER && data != null){ - Tools.launchModInstaller(this, data); - return; - } - if(requestCode == MultiRTConfigDialog.MULTIRT_PICK_RUNTIME && data != null){ - Tools.installRuntimeFromUri(this, data.getData()); - } - } - - /** Custom implementation to feel more natural when a backstack isn't present */ - @Override - public void onBackPressed() { - MicrosoftLoginFragment fragment = (MicrosoftLoginFragment) getVisibleFragment(MicrosoftLoginFragment.TAG); - if(fragment != null){ - if(fragment.canGoBack()){ - fragment.goBack(); - return; - } - } - - super.onBackPressed(); - } - - @Override - public void onAttachedToWindow() { - LauncherPreferences.computeNotchSize(this); - } - - @SuppressWarnings("SameParameterValue") - private Fragment getVisibleFragment(String tag){ - Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag); - if(fragment != null && fragment.isVisible()) { - return fragment; - } - return null; - } - - @SuppressWarnings("unused") - private Fragment getVisibleFragment(int id){ - Fragment fragment = getSupportFragmentManager().findFragmentById(id); - if(fragment != null && fragment.isVisible()) { - return fragment; - } - return null; - } - - private void askForStoragePermission(){ - int revokeCount = 0; - while (Build.VERSION.SDK_INT >= 23 && Build.VERSION.SDK_INT < 29 && !isStorageAllowed()) { //Do not ask for storage at all on Android 10+ - try { - revokeCount++; - if (revokeCount >= 3) { - Toast.makeText(this, R.string.toast_permission_denied, Toast.LENGTH_LONG).show(); - finish(); - } - requestStoragePermission(); - - synchronized (mLockStoragePerm) { - mLockStoragePerm.wait(); - } - } catch (InterruptedException e) { - Log.e("LauncherActivity", e.toString()); - } - } - } - - private boolean isStorageAllowed() { - //Getting the permission status - int result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE); - int result2 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE); - - - //If permission is granted returning true - return result1 == PackageManager.PERMISSION_GRANTED && - result2 == PackageManager.PERMISSION_GRANTED; - } - - private void requestStoragePermission() { - ActivityCompat.requestPermissions(this, new String[]{ - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_STORAGE_REQUEST_CODE); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - if (requestCode == REQUEST_STORAGE_REQUEST_CODE) { - synchronized (mLockStoragePerm) { - mLockStoragePerm.notifyAll(); - } - } - } - - /** Stuff all the view boilerplate here */ - private void bindViews(){ - mFragmentView = findViewById(R.id.container_fragment); - mSettingsButton = findViewById(R.id.setting_button); - mDeleteAccountButton = findViewById(R.id.delete_account_button); - mAccountSpinner = findViewById(R.id.account_spinner); - mProgressLayout = findViewById(R.id.progress_layout); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java index d3b4876d4..c896c0a7a 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -14,7 +14,6 @@ import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; @@ -48,12 +47,7 @@ import net.kdt.pojavlaunch.customcontrols.EditorExitable; import net.kdt.pojavlaunch.customcontrols.keyboard.LwjglCharSender; import net.kdt.pojavlaunch.customcontrols.keyboard.TouchCharInput; import net.kdt.pojavlaunch.prefs.LauncherPreferences; -import net.kdt.pojavlaunch.services.GameService; -import net.kdt.pojavlaunch.utils.JREUtils; import net.kdt.pojavlaunch.utils.MCOptionUtils; -import net.kdt.pojavlaunch.value.MinecraftAccount; -import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles; -import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile; import org.lwjgl.glfw.CallbackBridge; @@ -76,8 +70,6 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe private GyroControl mGyroControl = null; public static ControlLayout mControlLayout; - MinecraftProfile minecraftProfile; - private ArrayAdapter gameActionArrayAdapter; private AdapterView.OnItemClickListener gameActionClickListener; public ArrayAdapter ingameControlsEditorArrayAdapter; @@ -86,7 +78,6 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - GameService.startService(this); initLayout(R.layout.activity_basemain); CallbackBridge.addGrabListener(touchpad); CallbackBridge.addGrabListener(minecraftGLView); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java index 898f34618..e2edf8f45 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MinecraftGLSurface.java @@ -18,6 +18,7 @@ import android.os.Looper; import android.os.Message; import android.util.AttributeSet; import android.util.Log; +import android.view.GestureDetector; import android.view.InputDevice; import android.view.KeyEvent; import android.view.MotionEvent; @@ -53,14 +54,15 @@ public class MinecraftGLSurface extends View implements GrabListener { float startX = 0; float startY = 0; - ScaleGestureDetector scaleGestureDetector; + private ScaleGestureDetector scaleGestureDetector; + private GestureDetector longPressDetector; + /* The RemapperView.Builder object allows you to set which buttons to remap */ private final RemapperManager mInputManager = new RemapperManager(getContext(), new RemapperView.Builder(null) .remapA(true) .remapB(true) .remapX(true) .remapY(true) - .remapDpad(true) .remapLeftJoystick(true) .remapRightJoystick(true) @@ -215,6 +217,30 @@ public class MinecraftGLSurface extends View implements GrabListener { public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {} }); + this.longPressDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { + + boolean isDragClicking = false; + @Override + public void onLongPress(MotionEvent e) { + super.onLongPress(e); + if(!isDragClicking) { + isDragClicking = true; + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F5, AWTInputEvent.VK_F5); + } + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + if(isDragClicking) { + isDragClicking = false; + AWTInputBridge.sendKey((char)AWTInputEvent.VK_F5, AWTInputEvent.VK_F5); + } + return super.onSingleTapUp(e); + } + }); + + //this.longPressDetector.setIsLongpressEnabled(true); + ((ViewGroup)getParent()).addView(textureView); } } @@ -228,9 +254,7 @@ public class MinecraftGLSurface extends View implements GrabListener { @SuppressWarnings("accessibility") public boolean onTouchEvent(MotionEvent e) { scaleGestureDetector.onTouchEvent(e); - - Log.i("downthecrop","ya I still see these events"); - + //longPressDetector.onTouchEvent(e); // Kinda need to send this back to the layout if(((ControlLayout)getParent()).getModifiable()) return false; @@ -252,7 +276,8 @@ public class MinecraftGLSurface extends View implements GrabListener { CallbackBridge.mouseX = (e.getX() * mScaleFactor); CallbackBridge.mouseY = (e.getY() * mScaleFactor); //One android click = one MC click - if(mSingleTapDetector.onTouchEvent(e)){ // Touch Mode + if(mSingleTapDetector.onTouchEvent(e)){ // + //longPressDetector.onTouchEvent(e);// Touch Mode CallbackBridge.putMouseEventWithCoords(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_LEFT, CallbackBridge.mouseX, CallbackBridge.mouseY); return true; } @@ -397,25 +422,6 @@ public class MinecraftGLSurface extends View implements GrabListener { sendMouseButton(LwjglGlfwKeycode.GLFW_MOUSE_BUTTON_RIGHT, false); } break; - - case MotionEvent.ACTION_POINTER_DOWN: // 5 - //TODO Hey we could have some sort of middle click detection ? - - mScrollLastInitialX = e.getX(); - mScrollLastInitialY = e.getY(); - //Checking if we are pressing the hotbar to select the item - hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1)); - if(hudKeyHandled != -1){ - sendKeyPress(hudKeyHandled); - if(hasDoubleTapped && hudKeyHandled == mLastHotbarKey){ - //Prevent double tapping Event on two different slots - sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_F); - } - } - - mLastHotbarKey = hudKeyHandled; - break; - } // Actualise the pointer count diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java deleted file mode 100644 index ae9d5421e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/PojavProfile.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.kdt.pojavlaunch; - -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import net.kdt.pojavlaunch.value.MinecraftAccount; - -public class PojavProfile { - private static final String PROFILE_PREF = "pojav_profile"; - private static final String PROFILE_PREF_FILE = "file"; - - public static SharedPreferences getPrefs(Context ctx) { - return ctx.getSharedPreferences(PROFILE_PREF, Context.MODE_PRIVATE); - } - - public static MinecraftAccount getCurrentProfileContent(@NonNull Context ctx, @Nullable String profileName) { - return MinecraftAccount.load(profileName == null ? getCurrentProfileName(ctx) : profileName); - } - - public static String getCurrentProfileName(Context ctx) { - String name = getPrefs(ctx).getString(PROFILE_PREF_FILE, ""); - // A dirty fix - if (!name.isEmpty() && name.startsWith(Tools.DIR_ACCOUNT_NEW) && name.endsWith(".json")) { - name = name.substring(0, name.length() - 5).replace(Tools.DIR_ACCOUNT_NEW, "").replace(".json", ""); - setCurrentProfile(ctx, name); - } - return name; - } - - public static void setCurrentProfile(@NonNull Context ctx, @Nullable Object obj) { - SharedPreferences.Editor pref = getPrefs(ctx).edit(); - - try { if (obj instanceof String) { - String acc = (String) obj; - pref.putString(PROFILE_PREF_FILE, acc); - //MinecraftAccount.clearTempAccount(); - } else if (obj == null) { - pref.putString(PROFILE_PREF_FILE, ""); - } else { - throw new IllegalArgumentException("Profile must be String.class or null"); - } - } finally { - pref.apply(); - } - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java index 155b71e36..653632685 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -49,16 +49,11 @@ import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.Runtime; -import net.kdt.pojavlaunch.plugins.FFmpegPlugin; import net.kdt.pojavlaunch.prefs.LauncherPreferences; import net.kdt.pojavlaunch.utils.DownloadUtils; import net.kdt.pojavlaunch.utils.JREUtils; import net.kdt.pojavlaunch.utils.JSONUtils; import net.kdt.pojavlaunch.utils.OldVersionsUtils; -import net.kdt.pojavlaunch.value.DependentLibrary; -import net.kdt.pojavlaunch.value.MinecraftAccount; -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.io.IOUtils; @@ -188,15 +183,6 @@ public final class Tools { JREUtils.launchJavaVM(activity, runtime, gamedir, javaArgList, args); } - public static File getGameDirPath(@NonNull MinecraftProfile minecraftProfile){ - if(minecraftProfile.gameDir != null){ - if(minecraftProfile.gameDir.startsWith(Tools.LAUNCHERPROFILES_RTPREFIX)) - return new File(minecraftProfile.gameDir.replace(Tools.LAUNCHERPROFILES_RTPREFIX,Tools.DIR_GAME_HOME+"/")); - else - return new File(Tools.DIR_GAME_HOME,minecraftProfile.gameDir); - } - return new File(Tools.DIR_GAME_NEW); - } public static void buildNotificationChannel(Context context){ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return; @@ -276,72 +262,6 @@ public final class Tools { javaArgList.add(cacioClasspath.toString()); } - public static String[] getMinecraftJVMArgs(String versionName, File gameDir) { - JMinecraftVersionList.Version versionInfo = Tools.getVersionInfo(versionName, true); - // Parse Forge 1.17+ additional JVM Arguments - if (versionInfo.inheritsFrom == null || versionInfo.arguments == null || versionInfo.arguments.jvm == null) { - return new String[0]; - } - - Map varArgMap = new ArrayMap<>(); - varArgMap.put("classpath_separator", ":"); - varArgMap.put("library_directory", DIR_HOME_LIBRARY); - varArgMap.put("version_name", versionInfo.id); - varArgMap.put("natives_directory", Tools.NATIVE_LIB_DIR); - - List minecraftArgs = new ArrayList<>(); - if (versionInfo.arguments != null) { - for (Object arg : versionInfo.arguments.jvm) { - if (arg instanceof String) { - minecraftArgs.add((String) arg); - } //TODO: implement (?maybe?) - } - } - return JSONUtils.insertJSONValueList(minecraftArgs.toArray(new String[0]), varArgMap); - } - - public static String[] getMinecraftClientArgs(MinecraftAccount profile, JMinecraftVersionList.Version versionInfo, File gameDir) { - String username = profile.username; - String versionName = versionInfo.id; - if (versionInfo.inheritsFrom != null) { - versionName = versionInfo.inheritsFrom; - } - - String userType = "mojang"; - - Map varArgMap = new ArrayMap<>(); - varArgMap.put("auth_session", profile.accessToken); // For legacy versions of MC - varArgMap.put("auth_access_token", profile.accessToken); - varArgMap.put("auth_player_name", username); - varArgMap.put("auth_uuid", profile.profileId.replace("-", "")); - varArgMap.put("auth_xuid", profile.xuid); - varArgMap.put("assets_root", Tools.ASSETS_PATH); - varArgMap.put("assets_index_name", versionInfo.assets); - varArgMap.put("game_assets", Tools.ASSETS_PATH); - varArgMap.put("game_directory", gameDir.getAbsolutePath()); - varArgMap.put("user_properties", "{}"); - varArgMap.put("user_type", userType); - varArgMap.put("version_name", versionName); - varArgMap.put("version_type", versionInfo.type); - - List minecraftArgs = new ArrayList<>(); - if (versionInfo.arguments != null) { - // Support Minecraft 1.13+ - for (Object arg : versionInfo.arguments.game) { - if (arg instanceof String) { - minecraftArgs.add((String) arg); - } //TODO: implement else clause - } - } - - return JSONUtils.insertJSONValueList( - splitAndFilterEmpty( - versionInfo.minecraftArguments == null ? - fromStringArray(minecraftArgs.toArray(new String[0])): - versionInfo.minecraftArguments - ), varArgMap - ); - } public static String fromStringArray(String[] strArr) { StringBuilder builder = new StringBuilder(); @@ -364,15 +284,6 @@ public final class Tools { return strList.toArray(new String[0]); } - public static String artifactToPath(DependentLibrary library) { - if (library.downloads != null && - library.downloads.artifact != null && - library.downloads.artifact.path != null) - return library.downloads.artifact.path; - String[] libInfos = library.name.split(":"); - return libInfos[0].replaceAll("\\.", "/") + "/" + libInfos[1] + "/" + libInfos[2] + "/" + libInfos[1] + "-" + libInfos[2] + ".jar"; - } - public static String getPatchedFile(String version) { return DIR_HOME_VERSION + "/" + version + "/" + version + ".jar"; } @@ -394,27 +305,6 @@ public final class Tools { } private final static boolean isClientFirst = false; - public static String generateLaunchClassPath(JMinecraftVersionList.Version info,String actualname) { - StringBuilder libStr = new StringBuilder(); //versnDir + "/" + version + "/" + version + ".jar:"; - - String[] classpath = generateLibClasspath(info); - - if (isClientFirst) { - libStr.append(getPatchedFile(actualname)); - } - for (String perJar : classpath) { - if (!new File(perJar).exists()) { - Log.d(APP_NAME, "Ignored non-exists file: " + perJar); - continue; - } - libStr.append((isClientFirst ? ":" : "")).append(perJar).append(!isClientFirst ? ":" : ""); - } - if (!isClientFirst) { - libStr.append(getPatchedFile(actualname)); - } - - return libStr.toString(); - } public static DisplayMetrics getDisplayMetrics(Activity activity) { DisplayMetrics displayMetrics = new DisplayMetrics(); @@ -595,105 +485,9 @@ public final class Tools { } return true; // allow if none match } - public static String[] generateLibClasspath(JMinecraftVersionList.Version info) { - List libDir = new ArrayList<>(); - for (DependentLibrary libItem: info.libraries) { - if(!checkRules(libItem.rules)) continue; - libDir.add(Tools.DIR_HOME_LIBRARY + "/" + artifactToPath(libItem)); - } - return libDir.toArray(new String[0]); - } - - public static JMinecraftVersionList.Version getVersionInfo(String versionName) { - return getVersionInfo(versionName, false); - } @SuppressWarnings({"unchecked", "rawtypes"}) - public static JMinecraftVersionList.Version getVersionInfo(String versionName, boolean skipInheriting) { - try { - JMinecraftVersionList.Version customVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + versionName + "/" + versionName + ".json"), JMinecraftVersionList.Version.class); - if (skipInheriting || customVer.inheritsFrom == null || customVer.inheritsFrom.equals(customVer.id)) { - return customVer; - } else { - JMinecraftVersionList.Version inheritsVer; - //If it won't download, just search for it - try{ - inheritsVer = Tools.GLOBAL_GSON.fromJson(read(DIR_HOME_VERSION + "/" + customVer.inheritsFrom + "/" + customVer.inheritsFrom + ".json"), JMinecraftVersionList.Version.class); - }catch(IOException e) { - throw new RuntimeException("Can't find the source version for "+ versionName +" (req version="+customVer.inheritsFrom+")"); - } - //inheritsVer.inheritsFrom = inheritsVer.id; - insertSafety(inheritsVer, customVer, - "assetIndex", "assets", "id", - "mainClass", "minecraftArguments", - "releaseTime", "time", "type" - ); - List libList = new ArrayList<>(Arrays.asList(inheritsVer.libraries)); - try { - loop_1: - for (DependentLibrary lib : customVer.libraries) { - String libName = lib.name.substring(0, lib.name.lastIndexOf(":")); - for (int i = 0; i < libList.size(); i++) { - DependentLibrary libAdded = libList.get(i); - String libAddedName = libAdded.name.substring(0, libAdded.name.lastIndexOf(":")); - - if (libAddedName.equals(libName)) { - Log.d(APP_NAME, "Library " + libName + ": Replaced version " + - libName.substring(libName.lastIndexOf(":") + 1) + " with " + - libAddedName.substring(libAddedName.lastIndexOf(":") + 1)); - libList.set(i, lib); - continue loop_1; - } - } - - libList.add(0, lib); - } - } finally { - inheritsVer.libraries = libList.toArray(new DependentLibrary[0]); - } - - // Inheriting Minecraft 1.13+ with append custom args - if (inheritsVer.arguments != null && customVer.arguments != null) { - List totalArgList = new ArrayList(Arrays.asList(inheritsVer.arguments.game)); - - int nskip = 0; - for (int i = 0; i < customVer.arguments.game.length; i++) { - if (nskip > 0) { - nskip--; - continue; - } - - Object perCustomArg = customVer.arguments.game[i]; - if (perCustomArg instanceof String) { - String perCustomArgStr = (String) perCustomArg; - // Check if there is a duplicate argument on combine - if (perCustomArgStr.startsWith("--") && totalArgList.contains(perCustomArgStr)) { - perCustomArg = customVer.arguments.game[i + 1]; - if (perCustomArg instanceof String) { - perCustomArgStr = (String) perCustomArg; - // If the next is argument value, skip it - if (!perCustomArgStr.startsWith("--")) { - nskip++; - } - } - } else { - totalArgList.add(perCustomArgStr); - } - } else if (!totalArgList.contains(perCustomArg)) { - totalArgList.add(perCustomArg); - } - } - - inheritsVer.arguments.game = totalArgList.toArray(new Object[0]); - } - - return inheritsVer; - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } // Prevent NullPointerException private static void insertSafety(JMinecraftVersionList.Version targetVer, JMinecraftVersionList.Version fromVer, String... keyArr) { @@ -868,18 +662,6 @@ public final class Tools { return fileName; } - /** Swap the main fragment with another */ - public static void swapFragment(FragmentActivity fragmentActivity , Class fragmentClass, - @Nullable String fragmentTag, boolean addCurrentToBackstack, @Nullable Bundle bundle) { - // When people tab out, it might happen - //TODO handle custom animations - FragmentTransaction transaction = fragmentActivity.getSupportFragmentManager().beginTransaction() - .setReorderingAllowed(true) - .replace(R.id.container_fragment, fragmentClass, bundle, fragmentTag); - if(addCurrentToBackstack) transaction.addToBackStack(null); - - transaction.commit(); - } /** Remove the current fragment */ public static void removeCurrentFragment(FragmentActivity fragmentActivity){ @@ -994,34 +776,10 @@ public final class Tools { return prefixedName.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length()); } - public static String getSelectedRuntime(MinecraftProfile minecraftProfile) { - String runtime = LauncherPreferences.PREF_DEFAULT_RUNTIME; - String profileRuntime = getRuntimeName(minecraftProfile.javaDir); - if(profileRuntime != null) { - if(MultiRTUtils.forceReread(profileRuntime).versionString != null) { - runtime = profileRuntime; - } - } - return runtime; - } - public static void runOnUiThread(Runnable runnable) { MAIN_HANDLER.post(runnable); } - public static @NonNull String pickRuntime(MinecraftProfile minecraftProfile, int targetJavaVersion) { - String runtime = getSelectedRuntime(minecraftProfile); - String profileRuntime = getRuntimeName(minecraftProfile.javaDir); - Runtime pickedRuntime = MultiRTUtils.read(runtime); - if(runtime == null || pickedRuntime.javaVersion == 0 || pickedRuntime.javaVersion < targetJavaVersion) { - String preferredRuntime = MultiRTUtils.getNearestJreName(targetJavaVersion); - if(preferredRuntime == null) throw new RuntimeException("Failed to autopick runtime!"); - if(profileRuntime != null) minecraftProfile.javaDir = Tools.LAUNCHERPROFILES_RTPREFIX+preferredRuntime; - runtime = preferredRuntime; - } - return runtime; - } - /** Triggers the share intent chooser, with the latestlog file attached to it */ public static void shareLog(Context context){ Uri contentUri = DocumentsContract.buildDocumentUri(context.getString(R.string.storageProviderAuthorities), Tools.DIR_GAME_HOME + "/latestlog.txt"); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/DoneListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/DoneListener.java deleted file mode 100644 index 9bc5c3617..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/DoneListener.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.listener; - -import net.kdt.pojavlaunch.value.MinecraftAccount; - -/** Called when the login is done and the account received. guaranteed to be on the UI Thread */ -public interface DoneListener { - void onLoginDone(MinecraftAccount account); -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ErrorListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ErrorListener.java deleted file mode 100644 index 14ccf4fc5..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ErrorListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.listener; - -/** Called when there is a complete failure, guaranteed to be on the UI Thread */ -public interface ErrorListener { - void onLoginError(Throwable errorMessage); -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ProgressListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ProgressListener.java deleted file mode 100644 index 4dae81c60..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/listener/ProgressListener.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.listener; - -/** Called when a step is started, guaranteed to be in the UI Thread */ -public interface ProgressListener { - /** */ - void onLoginProgress(int step); -} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java deleted file mode 100644 index b4191803b..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/MicrosoftBackgroundLogin.java +++ /dev/null @@ -1,336 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.microsoft; - -import static net.kdt.pojavlaunch.PojavApplication.sExecutorService; - -import android.util.ArrayMap; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.kdt.mcgui.ProgressLayout; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.authenticator.listener.DoneListener; -import net.kdt.pojavlaunch.authenticator.listener.ErrorListener; -import net.kdt.pojavlaunch.authenticator.listener.ProgressListener; -import net.kdt.pojavlaunch.value.MinecraftAccount; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.HttpURLConnection; -import java.net.ProtocolException; -import java.net.URL; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.Map; - -/** Allow to perform a background login on a given account */ -// TODO handle connection errors ! -public class MicrosoftBackgroundLogin { - private static final String authTokenUrl = "https://login.live.com/oauth20_token.srf"; - private static final String xblAuthUrl = "https://user.auth.xboxlive.com/user/authenticate"; - private static final String xstsAuthUrl = "https://xsts.auth.xboxlive.com/xsts/authorize"; - private static final String mcLoginUrl = "https://api.minecraftservices.com/authentication/login_with_xbox"; - private static final String mcProfileUrl = "https://api.minecraftservices.com/minecraft/profile"; - - private final boolean mIsRefresh; - private final String mAuthCode; - private static final Map XSTS_ERRORS; - static { - XSTS_ERRORS = new ArrayMap<>(); - XSTS_ERRORS.put(2148916233L, R.string.xerr_no_account); - XSTS_ERRORS.put(2148916235L, R.string.xerr_not_available); - XSTS_ERRORS.put(2148916236L ,R.string.xerr_adult_verification); - XSTS_ERRORS.put(2148916237L ,R.string.xerr_adult_verification); - XSTS_ERRORS.put(2148916238L ,R.string.xerr_child); - } - - /* Fields used to fill the account */ - public String msRefreshToken; - public String mcName; - public String mcToken; - public String mcUuid; - public boolean doesOwnGame; - public long expiresAt; - - public MicrosoftBackgroundLogin(boolean isRefresh, String authCode){ - mIsRefresh = isRefresh; - mAuthCode = authCode; - } - - /** Performs a full login, calling back listeners appropriately */ - public void performLogin(@Nullable final ProgressListener progressListener, - @Nullable final DoneListener doneListener, - @Nullable final ErrorListener errorListener){ - sExecutorService.execute(() -> { - try { - notifyProgress(progressListener, 1); - String accessToken = acquireAccessToken(mIsRefresh, mAuthCode); - notifyProgress(progressListener, 2); - String xboxLiveToken = acquireXBLToken(accessToken); - notifyProgress(progressListener, 3); - String[] xsts = acquireXsts(xboxLiveToken); - notifyProgress(progressListener, 4); - String mcToken = acquireMinecraftToken(xsts[0], xsts[1]); - notifyProgress(progressListener, 5); - checkMcProfile(mcToken); - - MinecraftAccount acc = MinecraftAccount.load(mcName); - if(acc == null) acc = new MinecraftAccount(); - if (doesOwnGame) { - acc.xuid = xsts[0]; - acc.clientToken = "0"; /* FIXME */ - acc.accessToken = mcToken; - acc.username = mcName; - acc.profileId = mcUuid; - acc.isMicrosoft = true; - acc.msaRefreshToken = msRefreshToken; - acc.expiresAt = expiresAt; - acc.updateSkinFace(); - } - acc.save(); - - if(doneListener != null) { - MinecraftAccount finalAcc = acc; - Tools.runOnUiThread(() -> doneListener.onLoginDone(finalAcc)); - } - - }catch (Exception e){ - Log.e("MicroAuth", e.toString()); - if(errorListener != null) - Tools.runOnUiThread(() -> errorListener.onLoginError(e)); - } - ProgressLayout.clearProgress(ProgressLayout.AUTHENTICATE_MICROSOFT); - }); - } - - public String acquireAccessToken(boolean isRefresh, String authcode) throws IOException, JSONException { - URL url = new URL(authTokenUrl); - Log.i("MicrosoftLogin", "isRefresh=" + isRefresh + ", authCode= "+authcode); - - String formData = convertToFormData( - "client_id", "00000000402b5328", - isRefresh ? "refresh_token" : "code", authcode, - "grant_type", isRefresh ? "refresh_token" : "authorization_code", - "redirect_url", "https://login.live.com/oauth20_desktop.srf", - "scope", "service::user.auth.xboxlive.com::MBI_SSL" - ); - - Log.i("MicroAuth", formData); - - //да пошла yf[eq1 она ваша джава 11 - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("charset", "utf-8"); - conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes(StandardCharsets.UTF_8).length)); - conn.setRequestMethod("POST"); - conn.setUseCaches(false); - conn.setDoInput(true); - conn.setDoOutput(true); - conn.connect(); - try(OutputStream wr = conn.getOutputStream()) { - wr.write(formData.getBytes(StandardCharsets.UTF_8)); - } - if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { - JSONObject jo = new JSONObject(Tools.read(conn.getInputStream())); - msRefreshToken = jo.getString("refresh_token"); - conn.disconnect(); - Log.i("MicrosoftLogin","Acess Token = " + jo.getString("access_token")); - return jo.getString("access_token"); - //acquireXBLToken(jo.getString("access_token")); - }else{ - throw getResponseThrowable(conn); - } - } - - private String acquireXBLToken(String accessToken) throws IOException, JSONException { - URL url = new URL(xblAuthUrl); - - JSONObject data = new JSONObject(); - JSONObject properties = new JSONObject(); - properties.put("AuthMethod", "RPS"); - properties.put("SiteName", "user.auth.xboxlive.com"); - properties.put("RpsTicket", accessToken); - data.put("Properties",properties); - data.put("RelyingParty", "http://auth.xboxlive.com"); - data.put("TokenType", "JWT"); - - String req = data.toString(); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - setCommonProperties(conn, req); - conn.connect(); - - try(OutputStream wr = conn.getOutputStream()) { - wr.write(req.getBytes(StandardCharsets.UTF_8)); - } - if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { - JSONObject jo = new JSONObject(Tools.read(conn.getInputStream())); - conn.disconnect(); - Log.i("MicrosoftLogin","Xbl Token = "+jo.getString("Token")); - return jo.getString("Token"); - //acquireXsts(jo.getString("Token")); - }else{ - throw getResponseThrowable(conn); - } - } - - /** @return [uhs, token]*/ - private @NonNull String[] acquireXsts(String xblToken) throws IOException, JSONException { - URL url = new URL(xstsAuthUrl); - - JSONObject data = new JSONObject(); - JSONObject properties = new JSONObject(); - properties.put("SandboxId", "RETAIL"); - properties.put("UserTokens", new JSONArray(Collections.singleton(xblToken))); - data.put("Properties", properties); - data.put("RelyingParty", "rp://api.minecraftservices.com/"); - data.put("TokenType", "JWT"); - - String req = data.toString(); - Log.i("MicroAuth", req); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - setCommonProperties(conn, req); - Log.i("MicroAuth", conn.getRequestMethod()); - conn.connect(); - - try(OutputStream wr = conn.getOutputStream()) { - wr.write(req.getBytes(StandardCharsets.UTF_8)); - } - - if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { - JSONObject jo = new JSONObject(Tools.read(conn.getInputStream())); - String uhs = jo.getJSONObject("DisplayClaims").getJSONArray("xui").getJSONObject(0).getString("uhs"); - String token = jo.getString("Token"); - conn.disconnect(); - Log.i("MicrosoftLogin","Xbl Xsts = " + token + "; Uhs = " + uhs); - return new String[]{uhs, token}; - //acquireMinecraftToken(uhs,jo.getString("Token")); - }else if(conn.getResponseCode() == 401) { - String responseContents = Tools.read(conn.getErrorStream()); - JSONObject jo = new JSONObject(responseContents); - long xerr = jo.optLong("XErr", -1); - Integer locale_id = XSTS_ERRORS.get(xerr); - if(locale_id != null) { - throw new PresentedException(new RuntimeException(responseContents), locale_id); - } - throw new PresentedException(new RuntimeException(responseContents), R.string.xerr_unknown, xerr); - }else{ - throw getResponseThrowable(conn); - } - } - - private String acquireMinecraftToken(String xblUhs, String xblXsts) throws IOException, JSONException { - URL url = new URL(mcLoginUrl); - - JSONObject data = new JSONObject(); - data.put("identityToken", "XBL3.0 x=" + xblUhs + ";" + xblXsts); - - String req = data.toString(); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - setCommonProperties(conn, req); - conn.connect(); - - try(OutputStream wr = conn.getOutputStream()) { - wr.write(req.getBytes(StandardCharsets.UTF_8)); - } - - if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { - expiresAt = System.currentTimeMillis() + 86400000; - JSONObject jo = new JSONObject(Tools.read(conn.getInputStream())); - conn.disconnect(); - Log.i("MicrosoftLogin","MC token: "+jo.getString("access_token")); - mcToken = jo.getString("access_token"); - //checkMcProfile(jo.getString("access_token")); - return jo.getString("access_token"); - }else{ - throw getResponseThrowable(conn); - } - } - - private void checkMcProfile(String mcAccessToken) throws IOException, JSONException { - URL url = new URL(mcProfileUrl); - - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setRequestProperty("Authorization", "Bearer " + mcAccessToken); - conn.setUseCaches(false); - conn.connect(); - - if(conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { - String s= Tools.read(conn.getInputStream()); - conn.disconnect(); - Log.i("MicrosoftLogin","profile:" + s); - JSONObject jsonObject = new JSONObject(s); - String name = (String) jsonObject.get("name"); - String uuid = (String) jsonObject.get("id"); - String uuidDashes = uuid.replaceFirst( - "(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)", "$1-$2-$3-$4-$5" - ); - doesOwnGame = true; - Log.i("MicrosoftLogin","UserName = " + name); - Log.i("MicrosoftLogin","Uuid Minecraft = " + uuidDashes); - mcName=name; - mcUuid=uuidDashes; - }else{ - Log.i("MicrosoftLogin","It seems that this Microsoft Account does not own the game."); - doesOwnGame = false; - throw new PresentedException(new RuntimeException(conn.getResponseMessage()), R.string.minecraft_not_owned); - //throwResponseError(conn); - } - } - - /** Wrapper to ease notifying the listener */ - private void notifyProgress(@Nullable ProgressListener listener, int step){ - if(listener != null){ - Tools.runOnUiThread(() -> listener.onLoginProgress(step)); - } - ProgressLayout.setProgress(ProgressLayout.AUTHENTICATE_MICROSOFT, step*20); - } - - - /** Set common properties for the connection. Given that all requests are POST, interactivity is always enabled */ - private static void setCommonProperties(HttpURLConnection conn, String formData) { - conn.setRequestProperty("Content-Type", "application/json"); - conn.setRequestProperty("Accept", "application/json"); - conn.setRequestProperty("charset", "utf-8"); - try { - conn.setRequestProperty("Content-Length", Integer.toString(formData.getBytes(StandardCharsets.UTF_8).length)); - conn.setRequestMethod("POST"); - }catch (ProtocolException e) { - Log.e("MicrosoftAuth", e.toString()); - } - conn.setUseCaches(false); - conn.setDoInput(true); - conn.setDoOutput(true); - } - - /** - * @param data A series a strings: key1, value1, key2, value2... - * @return the data converted as a form string for a POST request - */ - private static String convertToFormData(String... data) throws UnsupportedEncodingException { - StringBuilder builder = new StringBuilder(); - for(int i=0; i 0) builder.append("&"); - builder.append(URLEncoder.encode(data[i], "UTF-8")) - .append("=") - .append(URLEncoder.encode(data[i+1], "UTF-8")); - } - return builder.toString(); - } - - private RuntimeException getResponseThrowable(HttpURLConnection conn) throws IOException { - Log.i("MicrosoftLogin", "Error code: " + conn.getResponseCode() + ": " + conn.getResponseMessage()); - if(conn.getResponseCode() == 429) { - return new PresentedException(R.string.microsoft_login_retry_later); - } - return new RuntimeException(conn.getResponseMessage()); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/PresentedException.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/PresentedException.java deleted file mode 100644 index 7842379c4..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/authenticator/microsoft/PresentedException.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.kdt.pojavlaunch.authenticator.microsoft; - -import android.content.Context; - -public class PresentedException extends RuntimeException { - final int localizationStringId; - final Object[] extraArgs; - - public PresentedException(int localizationStringId, Object... extraArgs) { - this.localizationStringId = localizationStringId; - this.extraArgs = extraArgs; - } - - public PresentedException(Throwable throwable, int localizationStringId, Object... extraArgs) { - super(throwable); - this.localizationStringId = localizationStringId; - this.extraArgs = extraArgs; - } - - public String toString(Context context) { - return context.getString(localizationStringId, extraArgs); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FabricInstallFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FabricInstallFragment.java deleted file mode 100644 index 4626a1df9..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FabricInstallFragment.java +++ /dev/null @@ -1,195 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.util.Log; -import android.view.View; -import android.widget.Adapter; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.ProgressBar; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; - -import net.kdt.pojavlaunch.JavaGUILauncherActivity; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.modloaders.FabricDownloadTask; -import net.kdt.pojavlaunch.modloaders.FabricUtils; -import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener; -import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy; -import net.kdt.pojavlaunch.profiles.VersionSelectorDialog; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -public class FabricInstallFragment extends Fragment implements AdapterView.OnItemSelectedListener, ModloaderDownloadListener, Runnable { - public static final String TAG = "FabricInstallTarget"; - private static ModloaderListenerProxy sTaskProxy; - private TextView mSelectedVersionLabel; - private String mSelectedLoaderVersion; - private Spinner mLoaderVersionSpinner; - private String mSelectedGameVersion; - private boolean mSelectedSnapshot; - private ProgressBar mProgressBar; - private File mDestinationDir; - private Button mStartButton; - private View mRetryView; - public FabricInstallFragment() { - super(R.layout.fragment_fabric_install); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.mDestinationDir = new File(Tools.DIR_CACHE, "fabric-installer"); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - mStartButton = view.findViewById(R.id.fabric_installer_start_button); - mStartButton.setOnClickListener(this::onClickStart); - mSelectedVersionLabel = view.findViewById(R.id.fabric_installer_version_select_label); - view.findViewById(R.id.fabric_installer_game_version_change).setOnClickListener(this::onClickSelect); - mLoaderVersionSpinner = view.findViewById(R.id.fabric_installer_loader_ver_spinner); - mLoaderVersionSpinner.setOnItemSelectedListener(this); - mProgressBar = view.findViewById(R.id.fabric_installer_progress_bar); - mRetryView = view.findViewById(R.id.fabric_installer_retry_layout); - view.findViewById(R.id.fabric_installer_retry_button).setOnClickListener(this::onClickRetry); - if(sTaskProxy != null) { - mStartButton.setEnabled(false); - sTaskProxy.attachListener(this); - } - new Thread(this).start(); - } - - @Override - public void onDestroyView() { - super.onDestroyView(); - if(sTaskProxy != null) { - sTaskProxy.detachListener(); - } - } - - private void onClickStart(View v) { - if(ProgressKeeper.hasOngoingTasks()) { - Toast.makeText(v.getContext(), R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - return; - } - sTaskProxy = new ModloaderListenerProxy(); - FabricDownloadTask fabricDownloadTask = new FabricDownloadTask(sTaskProxy, mDestinationDir); - sTaskProxy.attachListener(this); - mStartButton.setEnabled(false); - new Thread(fabricDownloadTask).start(); - } - - private void onClickSelect(View v) { - VersionSelectorDialog.open(v.getContext(), true, (id, snapshot)->{ - mSelectedGameVersion = id; - mSelectedVersionLabel.setText(mSelectedGameVersion); - mSelectedSnapshot = snapshot; - if(mSelectedLoaderVersion != null && sTaskProxy == null) mStartButton.setEnabled(true); - }); - } - - private void onClickRetry(View v) { - mLoaderVersionSpinner.setAdapter(null); - mStartButton.setEnabled(false); - mProgressBar.setVisibility(View.VISIBLE); - mRetryView.setVisibility(View.GONE); - new Thread(this).start(); - } - - @Override - public void onItemSelected(AdapterView adapterView, View view, int i, long l) { - Adapter adapter = adapterView.getAdapter(); - mSelectedLoaderVersion = (String) adapter.getItem(i); - } - - @Override - public void onNothingSelected(AdapterView adapterView) { - mSelectedLoaderVersion = null; - } - - @Override - public void onDownloadFinished(File downloadedFile) { - Tools.runOnUiThread(()->{ - Context context = requireContext(); - sTaskProxy.detachListener(); - sTaskProxy = null; - mStartButton.setEnabled(true); - // This works because the due to the fact that we have transitioned here - // without adding a transaction to the back stack, which caused the previous - // transaction to be amended (i guess?? thats how the back stack dump looks like) - // we can get back to the main fragment with just one back stack pop. - // For some reason that amendment causes the transaction to lose its tag - // so we cant use the tag here. - getParentFragmentManager().popBackStackImmediate(); - Intent intent = new Intent(context, JavaGUILauncherActivity.class); - FabricUtils.addAutoInstallArgs(intent, downloadedFile, mSelectedGameVersion, mSelectedLoaderVersion, mSelectedSnapshot, true); - context.startActivity(intent); - }); - } - - @Override - public void onDataNotAvailable() { - Tools.runOnUiThread(()->{ - Context context = requireContext(); - sTaskProxy.detachListener(); - sTaskProxy = null; - mStartButton.setEnabled(true); - Tools.dialog(context, - context.getString(R.string.global_error), - context.getString(R.string.fabric_dl_cant_read_meta)); - }); - } - - @Override - public void onDownloadError(Exception e) { - Tools.runOnUiThread(()-> { - Context context = requireContext(); - sTaskProxy.detachListener(); - sTaskProxy = null; - mStartButton.setEnabled(true); - Tools.showError(context, e); - }); - } - - @Override - public void run() { - try { - List mLoaderVersions = FabricUtils.downloadLoaderVersionList(false); - if (mLoaderVersions != null) { - Tools.runOnUiThread(()->{ - Context context = getContext(); - if(context == null) return; - ArrayAdapter arrayAdapter = new ArrayAdapter<>(context, R.layout.support_simple_spinner_dropdown_item, mLoaderVersions); - mLoaderVersionSpinner.setAdapter(arrayAdapter); - mProgressBar.setVisibility(View.GONE); - }); - }else{ - Tools.runOnUiThread(()-> { - mRetryView.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - }); - } - }catch (IOException e) { - Tools.runOnUiThread(()-> { - if(getContext() != null) Tools.showError(getContext(), e); - mRetryView.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - }); - } - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FileSelectorFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FileSelectorFragment.java deleted file mode 100644 index 7cb262746..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/FileSelectorFragment.java +++ /dev/null @@ -1,111 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.app.AlertDialog; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import com.kdt.pickafile.FileListView; -import com.kdt.pickafile.FileSelectedListener; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; - -import java.io.File; -public class FileSelectorFragment extends Fragment { - public static final String TAG = "FileSelectorFragment"; - public static final String BUNDLE_SELECT_FOLDER = "select_folder"; - public static final String BUNDLE_SHOW_FILE = "show_file"; - public static final String BUNDLE_SHOW_FOLDER = "show_folder"; - public static final String BUNDLE_ROOT_PATH = "root_path"; - - private Button mSelectFolderButton, mCreateFolderButton; - private FileListView mFileListView; - private TextView mFilePathView; - - private boolean mSelectFolder = true; - private boolean mShowFiles = true; - private boolean mShowFolders = true; - private String mRootPath = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P - ? Tools.DIR_GAME_NEW - : Environment.getExternalStorageDirectory().getAbsolutePath(); - - - public FileSelectorFragment(){ - super(R.layout.fragment_file_selector); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - bindViews(view); - parseBundle(); - if(!mSelectFolder) mSelectFolderButton.setVisibility(View.GONE); - else mSelectFolderButton.setVisibility(View.VISIBLE); - - mFileListView.setShowFiles(mShowFiles); - mFileListView.setShowFolders(mShowFolders); - mFileListView.lockPathAt(new File(mRootPath)); - mFileListView.setDialogTitleListener((title)->mFilePathView.setText(removeLockPath(title))); - mFileListView.refreshPath(); - - mCreateFolderButton.setOnClickListener(v -> { - final EditText editText = new EditText(getContext()); - new AlertDialog.Builder(getContext()) - .setTitle(R.string.folder_dialog_insert_name) - .setView(editText) - .setNegativeButton(android.R.string.cancel, null) - .setPositiveButton(R.string.folder_dialog_create, (dialog, which) -> { - File folder = new File(mFileListView.getFullPath(), editText.getText().toString()); - boolean success = folder.mkdir(); - if(success){ - mFileListView.listFileAt(new File(mFileListView.getFullPath(),editText.getText().toString())); - }else{ - mFileListView.refreshPath(); - } - }).show(); - }); - - mSelectFolderButton.setOnClickListener(v -> { - ExtraCore.setValue(ExtraConstants.FILE_SELECTOR, removeLockPath(mFileListView.getFullPath().getAbsolutePath())); - Tools.removeCurrentFragment(requireActivity()); - }); - - mFileListView.setFileSelectedListener(new FileSelectedListener() { - @Override - public void onFileSelected(File file, String path) { - ExtraCore.setValue(ExtraConstants.FILE_SELECTOR, removeLockPath(path)); - Tools.removeCurrentFragment(requireActivity()); - } - }); - } - - private String removeLockPath(String path){ - return path.replace(mRootPath, "."); - } - - private void parseBundle(){ - Bundle bundle = getArguments(); - if(bundle == null) return; - mSelectFolder = bundle.getBoolean(BUNDLE_SELECT_FOLDER, mSelectFolder); - mShowFiles = bundle.getBoolean(BUNDLE_SHOW_FILE, mShowFiles); - mShowFolders = bundle.getBoolean(BUNDLE_SHOW_FOLDER, mShowFolders); - mRootPath = bundle.getString(BUNDLE_ROOT_PATH, mRootPath); - } - - private void bindViews(@NonNull View view){ - mSelectFolderButton = view.findViewById(R.id.file_selector_select_folder); - mCreateFolderButton = view.findViewById(R.id.file_selector_create_folder); - mFileListView = view.findViewById(R.id.file_selector); - mFilePathView = view.findViewById(R.id.file_selector_current_path); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ForgeInstallFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ForgeInstallFragment.java deleted file mode 100644 index fe609697f..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ForgeInstallFragment.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.widget.ExpandableListAdapter; - -import androidx.annotation.NonNull; - -import net.kdt.pojavlaunch.JavaGUILauncherActivity; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.modloaders.ForgeDownloadTask; -import net.kdt.pojavlaunch.modloaders.ForgeUtils; -import net.kdt.pojavlaunch.modloaders.ForgeVersionListAdapter; -import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -public class ForgeInstallFragment extends ModVersionListFragment> { - public static final String TAG = "ForgeInstallFragment"; - private static ModloaderListenerProxy sTaskProxy; - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - } - - @Override - public int getTitleText() { - return R.string.forge_dl_select_version; - } - - @Override - public int getNoDataMsg() { - return R.string.forge_dl_no_installer; - } - - @Override - public ModloaderListenerProxy getTaskProxy() { - return sTaskProxy; - } - @Override - public void setTaskProxy(ModloaderListenerProxy proxy) { - sTaskProxy = proxy; - } - - @Override - public List loadVersionList() throws IOException { - return ForgeUtils.downloadForgeVersions(); - } - - @Override - public ExpandableListAdapter createAdapter(List versionList, LayoutInflater layoutInflater) { - return new ForgeVersionListAdapter(versionList, layoutInflater); - } - - @Override - public Runnable createDownloadTask(Object selectedVersion, ModloaderListenerProxy listenerProxy) { - return new ForgeDownloadTask(listenerProxy, (String) selectedVersion, new File(Tools.DIR_CACHE, "forge-installer.jar")); - } - - @Override - public void onDownloadFinished(Context context, File downloadedFile) { - Intent modInstallerStartIntent = new Intent(context, JavaGUILauncherActivity.class); - ForgeUtils.addAutoInstallArgs(modInstallerStartIntent, downloadedFile, true); - context.startActivity(modInstallerStartIntent); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java deleted file mode 100644 index 6b704642e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/LocalLoginFragment.java +++ /dev/null @@ -1,53 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.os.Bundle; -import android.view.View; -import android.widget.EditText; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; - -import java.io.File; - -public class LocalLoginFragment extends Fragment { - public static final String TAG = "LOCAL_LOGIN_FRAGMENT"; - - private EditText mUsernameEditText; - - public LocalLoginFragment(){ - super(R.layout.fragment_local_login); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - mUsernameEditText = view.findViewById(R.id.login_edit_email); - view.findViewById(R.id.login_button).setOnClickListener(v -> { - if(!checkEditText()) return; - - ExtraCore.setValue(ExtraConstants.MOJANG_LOGIN_TODO, new String[]{ - mUsernameEditText.getText().toString(), "" }); - - Tools.swapFragment(requireActivity(), MainMenuFragment.class, MainMenuFragment.TAG, false, null); - }); - } - - - /** @return Whether the mail (and password) text are eligible to make an auth request */ - private boolean checkEditText(){ - - String text = mUsernameEditText.getText().toString(); - - return !(text.isEmpty() - || text.length() < 3 - || text.length() > 16 - || !text.matches("\\w+") - || new File(Tools.DIR_ACCOUNT_NEW + "/" + text + ".json").exists() - ); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java deleted file mode 100644 index 29e5b4d33..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MainMenuFragment.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import static net.kdt.pojavlaunch.Tools.shareLog; - -import android.content.Intent; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.ImageButton; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.CustomControlsActivity; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; - -public class MainMenuFragment extends Fragment { - public static final String TAG = "MainMenuFragment"; - - public MainMenuFragment(){ - super(R.layout.fragment_launcher); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - Button mNewsButton = view.findViewById(R.id.news_button); - Button mCustomControlButton = view.findViewById(R.id.custom_control_button); - Button mInstallJarButton = view.findViewById(R.id.install_jar_button); - Button mShareLogsButton = view.findViewById(R.id.share_logs_button); - - ImageButton mEditProfileButton = view.findViewById(R.id.edit_profile_button); - Button mPlayButton = view.findViewById(R.id.play_button); - - mNewsButton.setOnClickListener(v -> Tools.openURL(requireActivity(), Tools.URL_HOME)); - mCustomControlButton.setOnClickListener(v -> startActivity(new Intent(requireContext(), CustomControlsActivity.class))); - mInstallJarButton.setOnClickListener(v -> runInstallerWithConfirmation(false)); - mInstallJarButton.setOnLongClickListener(v->{ - runInstallerWithConfirmation(true); - return true; - }); - mEditProfileButton.setOnClickListener(v -> Tools.swapFragment(requireActivity(), ProfileEditorFragment.class, ProfileEditorFragment.TAG, true, null)); - - mPlayButton.setOnClickListener(v -> ExtraCore.setValue(ExtraConstants.LAUNCH_GAME, true)); - - mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext())); - - mNewsButton.setOnLongClickListener((v)->{ - Tools.swapFragment(requireActivity(), FabricInstallFragment.class, FabricInstallFragment.TAG, true, null); - return true; - }); - } - private void runInstallerWithConfirmation(boolean isCustomArgs) { - if (ProgressKeeper.getTaskCount() == 0) - Tools.installMod(requireActivity(), isCustomArgs); - else - Toast.makeText(requireContext(), R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java deleted file mode 100644 index 5c41d0f8b..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/MicrosoftLoginFragment.java +++ /dev/null @@ -1,89 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.annotation.SuppressLint; -import android.graphics.Bitmap; -import android.net.Uri; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.webkit.CookieManager; -import android.webkit.WebSettings; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.Toast; - -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; - -public class MicrosoftLoginFragment extends Fragment { - public static final String TAG = "MICROSOFT_LOGIN_FRAGMENT"; - private WebView mWebview; - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mWebview = (WebView) inflater.inflate(R.layout.fragment_microsoft_login, container, false); - CookieManager.getInstance().removeAllCookies(this::onCookiesRemoved); - return mWebview; - } - - @SuppressLint("SetJavaScriptEnabled") // required for Microsoft log-in - public void onCookiesRemoved(Boolean b) { - WebSettings settings = mWebview.getSettings(); - - settings.setJavaScriptEnabled(true); - mWebview.clearHistory(); - mWebview.clearCache(true); - mWebview.clearFormData(); - mWebview.clearHistory(); - mWebview.setWebViewClient(new WebViewTrackClient()); - - mWebview.loadUrl("https://login.live.com/oauth20_authorize.srf" + - "?client_id=00000000402b5328" + - "&response_type=code" + - "&scope=service%3A%3Auser.auth.xboxlive.com%3A%3AMBI_SSL" + - "&redirect_url=https%3A%2F%2Flogin.live.com%2Foauth20_desktop.srf"); - } - - /* Expose webview actions to others */ - public boolean canGoBack(){ return mWebview.canGoBack();} - public void goBack(){ mWebview.goBack();} - - /** Client to track when to sent the data to the launcher */ - class WebViewTrackClient extends WebViewClient { - - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if(url.startsWith("ms-xal-00000000402b5328")) { - // Should be captured by the activity to kill the fragment and get - ExtraCore.setValue(ExtraConstants.MICROSOFT_LOGIN_TODO, Uri.parse(url)); - Toast.makeText(view.getContext(), "Login started !", Toast.LENGTH_SHORT).show(); - Tools.removeCurrentFragment(requireActivity()); - - return true; - } - - // Sometimes, the user just clicked cancel - if(url.contains("res=cancel")){ - requireActivity().onBackPressed(); - return true; - } - - - return super.shouldOverrideUrlLoading(view, url); - } - - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) {} - - @Override - public void onPageFinished(WebView view, String url) {} - } - - -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModVersionListFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModVersionListFragment.java deleted file mode 100644 index f1ac32a51..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ModVersionListFragment.java +++ /dev/null @@ -1,158 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ExpandableListAdapter; -import android.widget.ExpandableListView; -import android.widget.ProgressBar; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener; -import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; - -import java.io.File; -import java.io.IOException; - -public abstract class ModVersionListFragment extends Fragment implements Runnable, View.OnClickListener, ExpandableListView.OnChildClickListener, ModloaderDownloadListener { - public static final String TAG = "ForgeInstallFragment"; - private ExpandableListView mExpandableListView; - private ProgressBar mProgressBar; - private LayoutInflater mInflater; - private View mRetryView; - - public ModVersionListFragment() { - super(R.layout.fragment_mod_version_list); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.mInflater = LayoutInflater.from(context); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - ((TextView)view.findViewById(R.id.title_textview)).setText(getTitleText()); - mProgressBar = view.findViewById(R.id.mod_dl_list_progress); - mExpandableListView = view.findViewById(R.id.mod_dl_expandable_version_list); - mExpandableListView.setOnChildClickListener(this); - mRetryView = view.findViewById(R.id.mod_dl_retry_layout); - view.findViewById(R.id.forge_installer_retry_button).setOnClickListener(this); - ModloaderListenerProxy taskProxy = getTaskProxy(); - if(taskProxy != null) { - mExpandableListView.setEnabled(false); - taskProxy.attachListener(this); - } - new Thread(this).start(); - } - - @Override - public void onDestroyView() { - ModloaderListenerProxy taskProxy = getTaskProxy(); - if(taskProxy != null) taskProxy.detachListener(); - super.onDestroyView(); - } - - @Override - public void run() { - try { - T versions = loadVersionList(); - Tools.runOnUiThread(()->{ - if(versions != null) { - mExpandableListView.setAdapter(createAdapter(versions, mInflater)); - }else{ - mRetryView.setVisibility(View.VISIBLE); - } - mProgressBar.setVisibility(View.GONE); - }); - }catch (IOException e) { - Tools.runOnUiThread(()-> { - if (getContext() != null) { - Tools.showError(getContext(), e); - mRetryView.setVisibility(View.VISIBLE); - mProgressBar.setVisibility(View.GONE); - } - }); - } - } - - @Override - public void onClick(View view) { - mRetryView.setVisibility(View.GONE); - mProgressBar.setVisibility(View.VISIBLE); - new Thread(this).start(); - } - - @Override - public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) { - if(ProgressKeeper.hasOngoingTasks()) { - Toast.makeText(expandableListView.getContext(), R.string.tasks_ongoing, Toast.LENGTH_LONG).show(); - return true; - } - Object forgeVersion = expandableListView.getExpandableListAdapter().getChild(i, i1); - ModloaderListenerProxy taskProxy = new ModloaderListenerProxy(); - Runnable downloadTask = createDownloadTask(forgeVersion, taskProxy); - setTaskProxy(taskProxy); - taskProxy.attachListener(this); - mExpandableListView.setEnabled(false); - new Thread(downloadTask).start(); - return true; - } - - @Override - public void onDownloadFinished(File downloadedFile) { - Tools.runOnUiThread(()->{ - Context context = requireContext(); - getTaskProxy().detachListener(); - setTaskProxy(null); - mExpandableListView.setEnabled(true); - // Read the comment in FabricInstallFragment.onDownloadFinished() to see how this works - getParentFragmentManager().popBackStackImmediate(); - onDownloadFinished(context, downloadedFile); - }); - } - - @Override - public void onDataNotAvailable() { - Tools.runOnUiThread(()->{ - Context context = requireContext(); - getTaskProxy().detachListener(); - setTaskProxy(null); - mExpandableListView.setEnabled(true); - Tools.dialog(context, - context.getString(R.string.global_error), - context.getString(getNoDataMsg())); - }); - } - - @Override - public void onDownloadError(Exception e) { - Tools.runOnUiThread(()->{ - Context context = requireContext(); - getTaskProxy().detachListener(); - setTaskProxy(null); - mExpandableListView.setEnabled(true); - Tools.showError(context, e); - }); - } - - public abstract int getTitleText(); - public abstract int getNoDataMsg(); - public abstract ModloaderListenerProxy getTaskProxy(); - public abstract T loadVersionList() throws IOException; - public abstract void setTaskProxy(ModloaderListenerProxy proxy); - public abstract ExpandableListAdapter createAdapter(T versionList, LayoutInflater layoutInflater); - public abstract Runnable createDownloadTask(Object selectedVersion, ModloaderListenerProxy listenerProxy); - public abstract void onDownloadFinished(Context context, File downloadedFile); -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/OptiFineInstallFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/OptiFineInstallFragment.java deleted file mode 100644 index a37704618..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/OptiFineInstallFragment.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.widget.ExpandableListAdapter; - -import net.kdt.pojavlaunch.JavaGUILauncherActivity; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy; -import net.kdt.pojavlaunch.modloaders.OptiFineDownloadTask; -import net.kdt.pojavlaunch.modloaders.OptiFineUtils; -import net.kdt.pojavlaunch.modloaders.OptiFineVersionListAdapter; - -import java.io.File; -import java.io.IOException; - -public class OptiFineInstallFragment extends ModVersionListFragment { - public static final String TAG = "OptiFineInstallFragment"; - private static ModloaderListenerProxy sTaskProxy; - @Override - public int getTitleText() { - return R.string.of_dl_select_version; - } - - @Override - public int getNoDataMsg() { - return R.string.of_dl_failed_to_scrape; - } - - @Override - public ModloaderListenerProxy getTaskProxy() { - return sTaskProxy; - } - - @Override - public OptiFineUtils.OptiFineVersions loadVersionList() throws IOException { - return OptiFineUtils.downloadOptiFineVersions(); - } - - @Override - public void setTaskProxy(ModloaderListenerProxy proxy) { - sTaskProxy = proxy; - } - - @Override - public ExpandableListAdapter createAdapter(OptiFineUtils.OptiFineVersions versionList, LayoutInflater layoutInflater) { - return new OptiFineVersionListAdapter(versionList, layoutInflater); - } - - @Override - public Runnable createDownloadTask(Object selectedVersion, ModloaderListenerProxy listenerProxy) { - return new OptiFineDownloadTask((OptiFineUtils.OptiFineVersion) selectedVersion, - new File(Tools.DIR_CACHE, "optifine-installer.jar"), listenerProxy); - } - - @Override - public void onDownloadFinished(Context context, File downloadedFile) { - Intent modInstallerStartIntent = new Intent(context, JavaGUILauncherActivity.class); - OptiFineUtils.addAutoInstallArgs(modInstallerStartIntent, downloadedFile); - context.startActivity(modInstallerStartIntent); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java deleted file mode 100644 index 5df28efa7..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileEditorFragment.java +++ /dev/null @@ -1,214 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Spinner; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.multirt.MultiRTUtils; -import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter; -import net.kdt.pojavlaunch.multirt.Runtime; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; -import net.kdt.pojavlaunch.profiles.VersionSelectorDialog; -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.UUID; - -public class ProfileEditorFragment extends Fragment { - public static final String TAG = "ProfileEditorFragment"; - public static final String DELETED_PROFILE = "deleted_profile"; - - private String mProfileKey; - private MinecraftProfile mTempProfile = null; - private String mValueToConsume = ""; - private Button mSaveButton, mDeleteButton, mControlSelectButton, mGameDirButton, mVersionSelectButton; - private Spinner mDefaultRuntime, mDefaultRenderer; - private EditText mDefaultName, mDefaultJvmArgument; - private TextView mDefaultPath, mDefaultVersion, mDefaultControl; - - private List mRenderNames; - - public ProfileEditorFragment(){ - super(R.layout.fragment_profile_editor); - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - // Paths, which can be changed - String value = (String) ExtraCore.consumeValue(ExtraConstants.FILE_SELECTOR); - if(value != null){ - if(mValueToConsume.equals(FileSelectorFragment.BUNDLE_SELECT_FOLDER)){ - mTempProfile.gameDir = value; - }else{ - mTempProfile.controlFile = value; - } - } - return super.onCreateView(inflater, container, savedInstanceState); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - mRenderNames = Arrays.asList(getResources().getStringArray(R.array.renderer_values)); - bindViews(view); - - // Renderer spinner - List renderList = new ArrayList<>(5); - Collections.addAll(renderList, getResources().getStringArray(R.array.renderer)); - renderList.add("Default"); - mDefaultRenderer.setAdapter(new ArrayAdapter<>(getContext(), android.R.layout.simple_list_item_1, renderList)); - - // Set up behaviors - mSaveButton.setOnClickListener(v -> { - save(); - Tools.removeCurrentFragment(requireActivity()); - }); - - mDeleteButton.setOnClickListener(v -> { - LauncherProfiles.mainProfileJson.profiles.remove(mProfileKey); - LauncherProfiles.update(); - ExtraCore.setValue(ExtraConstants.REFRESH_VERSION_SPINNER, DELETED_PROFILE); - Tools.removeCurrentFragment(requireActivity()); - }); - - mGameDirButton.setOnClickListener(v -> { - Bundle bundle = new Bundle(2); - bundle.putBoolean(FileSelectorFragment.BUNDLE_SELECT_FOLDER, true); - bundle.putString(FileSelectorFragment.BUNDLE_ROOT_PATH, Tools.DIR_GAME_HOME); - bundle.putBoolean(FileSelectorFragment.BUNDLE_SHOW_FILE, false); - mValueToConsume = FileSelectorFragment.BUNDLE_SELECT_FOLDER; - - Tools.swapFragment(requireActivity(), - FileSelectorFragment.class, FileSelectorFragment.TAG, true, bundle); - }); - - mControlSelectButton.setOnClickListener(v -> { - Bundle bundle = new Bundle(3); - bundle.putBoolean(FileSelectorFragment.BUNDLE_SELECT_FOLDER, false); - bundle.putString(FileSelectorFragment.BUNDLE_ROOT_PATH, Tools.CTRLMAP_PATH); - Tools.swapFragment(requireActivity(), - FileSelectorFragment.class, FileSelectorFragment.TAG, true, bundle); - }); - - // Setup the expendable list behavior - mVersionSelectButton.setOnClickListener(v -> VersionSelectorDialog.open(v.getContext(), false, (id, snapshot)->{ - mTempProfile.lastVersionId = id; - mDefaultVersion.setText(id); - })); - - - - loadValues(LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, ""), view.getContext()); - } - - - private void loadValues(@NonNull String profile, @NonNull Context context){ - if(mTempProfile == null){ - mTempProfile = getProfile(profile); - } - - // Runtime spinner - List runtimes = MultiRTUtils.getRuntimes(); - int jvmIndex = runtimes.indexOf(new Runtime("")); - if (mTempProfile.javaDir != null) { - String selectedRuntime = mTempProfile.javaDir.substring(Tools.LAUNCHERPROFILES_RTPREFIX.length()); - int nindex = runtimes.indexOf(new Runtime(selectedRuntime)); - if (nindex != -1) jvmIndex = nindex; - } - mDefaultRuntime.setAdapter(new RTSpinnerAdapter(context, runtimes)); - if(jvmIndex == -1) jvmIndex = runtimes.size() - 1; - mDefaultRuntime.setSelection(jvmIndex); - - // Renderer spinner - int rendererIndex = mDefaultRenderer.getAdapter().getCount() - 1; - if(mTempProfile.pojavRendererName != null) { - int nindex = mRenderNames.indexOf(mTempProfile.pojavRendererName); - if(nindex != -1) rendererIndex = nindex; - } - mDefaultRenderer.setSelection(rendererIndex); - - mDefaultVersion.setText(mTempProfile.lastVersionId); - mDefaultJvmArgument.setText(mTempProfile.javaArgs == null ? "" : mTempProfile.javaArgs); - mDefaultName.setText(mTempProfile.name); - mDefaultPath.setText(mTempProfile.gameDir == null ? "" : mTempProfile.gameDir); - mDefaultControl.setText(mTempProfile.controlFile == null ? "" : mTempProfile.controlFile); - } - - private MinecraftProfile getProfile(@NonNull String profile){ - MinecraftProfile minecraftProfile; - if(getArguments() == null) { - minecraftProfile = new MinecraftProfile(LauncherProfiles.mainProfileJson.profiles.get(profile)); - mProfileKey = profile; - }else{ - minecraftProfile = MinecraftProfile.createTemplate(); - String uuid = UUID.randomUUID().toString(); - while(LauncherProfiles.mainProfileJson.profiles.containsKey(uuid)) { - uuid = UUID.randomUUID().toString(); - } - mProfileKey = uuid; - } - return minecraftProfile; - } - - - private void bindViews(@NonNull View view){ - mDefaultControl = view.findViewById(R.id.vprof_editor_ctrl_spinner); - mDefaultRuntime = view.findViewById(R.id.vprof_editor_spinner_runtime); - mDefaultRenderer = view.findViewById(R.id.vprof_editor_profile_renderer); - mDefaultVersion = view.findViewById(R.id.vprof_editor_version_spinner); - - mDefaultPath = view.findViewById(R.id.vprof_editor_path); - mDefaultName = view.findViewById(R.id.vprof_editor_profile_name); - mDefaultJvmArgument = view.findViewById(R.id.vprof_editor_jre_args); - - mSaveButton = view.findViewById(R.id.vprof_editor_save_button); - mDeleteButton = view.findViewById(R.id.vprof_editor_delete_button); - mControlSelectButton = view.findViewById(R.id.vprof_editor_ctrl_button); - mVersionSelectButton = view.findViewById(R.id.vprof_editor_version_button); - mGameDirButton = view.findViewById(R.id.vprof_editor_path_button); - } - - private void save(){ - //First, check for potential issues in the inputs - mTempProfile.lastVersionId = mDefaultVersion.getText().toString(); - mTempProfile.controlFile = mDefaultControl.getText().toString(); - mTempProfile.name = mDefaultName.getText().toString(); - mTempProfile.javaArgs = mDefaultJvmArgument.getText().toString(); - mTempProfile.gameDir = mDefaultPath.getText().toString(); - - if(mTempProfile.controlFile.isEmpty()) mTempProfile.controlFile = null; - if(mTempProfile.javaArgs.isEmpty()) mTempProfile.javaArgs = null; - if(mTempProfile.gameDir.isEmpty()) mTempProfile.gameDir = null; - - Runtime selectedRuntime = (Runtime) mDefaultRuntime.getSelectedItem(); - mTempProfile.javaDir = (selectedRuntime.name.equals("") || selectedRuntime.versionString == null) - ? null : Tools.LAUNCHERPROFILES_RTPREFIX + selectedRuntime.name; - - if(mDefaultRenderer.getSelectedItemPosition() == mRenderNames.size()) mTempProfile.pojavRendererName = null; - else mTempProfile.pojavRendererName = mRenderNames.get(mDefaultRenderer.getSelectedItemPosition()); - - - LauncherProfiles.mainProfileJson.profiles.put(mProfileKey, mTempProfile); - LauncherProfiles.update(); - ExtraCore.setValue(ExtraConstants.REFRESH_VERSION_SPINNER, mProfileKey); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java deleted file mode 100644 index 2c29ffff5..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/ProfileTypeSelectFragment.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.os.Bundle; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; - -public class ProfileTypeSelectFragment extends Fragment { - public static final String TAG = "ProfileTypeSelectFragment"; - public ProfileTypeSelectFragment() { - super(R.layout.fragment_profile_type); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - view.findViewById(R.id.vanilla_profile).setOnClickListener(v -> Tools.swapFragment(requireActivity(), ProfileEditorFragment.class, - ProfileEditorFragment.TAG, false, new Bundle(1))); - - // NOTE: Special care needed! If you wll decide to add these to the back stack, please read - // the comment in FabricInstallFragment.onDownloadFinished() and amend the code - // in FabricInstallFragment.onDownloadFinished() and ModVersionListFragment.onDownloadFinished() - view.findViewById(R.id.optifine_profile).setOnClickListener(v -> Tools.swapFragment(requireActivity(), OptiFineInstallFragment.class, - OptiFineInstallFragment.TAG, false, null)); - view.findViewById(R.id.modded_profile_fabric).setOnClickListener((v)-> - Tools.swapFragment(requireActivity(), FabricInstallFragment.class, FabricInstallFragment.TAG, false, null)); - view.findViewById(R.id.modded_profile_forge).setOnClickListener((v)-> - Tools.swapFragment(requireActivity(), ForgeInstallFragment.class, ForgeInstallFragment.TAG, false, null)); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java deleted file mode 100644 index f27a5e7d4..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/fragments/SelectAuthFragment.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.kdt.pojavlaunch.fragments; - -import android.os.Bundle; -import android.view.View; -import android.widget.Button; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; - -public class SelectAuthFragment extends Fragment { - public static final String TAG = "AUTH_SELECT_FRAGMENT"; - - public SelectAuthFragment(){ - super(R.layout.fragment_select_auth_method); - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - Button mMicrosoftButton = view.findViewById(R.id.button_microsoft_authentication); - Button mLocalButton = view.findViewById(R.id.button_local_authentication); - - mMicrosoftButton.setOnClickListener(v -> Tools.swapFragment(requireActivity(), MicrosoftLoginFragment.class, MicrosoftLoginFragment.TAG, false, null)); - mLocalButton.setOnClickListener(v -> Tools.swapFragment(requireActivity(), LocalLoginFragment.class, LocalLoginFragment.TAG, false, null)); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricDownloadTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricDownloadTask.java deleted file mode 100644 index 03ea723ad..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricDownloadTask.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import com.kdt.mcgui.ProgressLayout; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import java.io.File; -import java.io.IOException; - -public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{ - private final File mDestinationDir; - private final File mDestinationFile; - private final ModloaderDownloadListener mModloaderDownloadListener; - - public FabricDownloadTask(ModloaderDownloadListener modloaderDownloadListener, File mDestinationDir) { - this.mModloaderDownloadListener = modloaderDownloadListener; - this.mDestinationDir = mDestinationDir; - this.mDestinationFile = new File(mDestinationDir, "fabric-installer.jar"); - } - - @Override - public void run() { - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.fabric_dl_progress); - try { - if(runCatching()) mModloaderDownloadListener.onDownloadFinished(mDestinationFile); - }catch (IOException e) { - mModloaderDownloadListener.onDownloadError(e); - } - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, -1, -1); - } - - private boolean runCatching() throws IOException { - if(!mDestinationDir.exists() && !mDestinationDir.mkdirs()) throw new IOException("Failed to create cache directory"); - String[] urlAndVersion = FabricUtils.getInstallerUrlAndVersion(); - if(urlAndVersion == null) { - mModloaderDownloadListener.onDataNotAvailable(); - return false; - } - File versionFile = new File(mDestinationDir, "fabric-installer-version"); - boolean shouldDownloadInstaller = true; - if(urlAndVersion[1] != null && versionFile.canRead()) { // if we know the latest version that we have and the server has - try { - shouldDownloadInstaller = !urlAndVersion[1].equals(Tools.read(versionFile.getAbsolutePath())); - }catch (IOException e) { - e.printStackTrace(); - } - } - if(shouldDownloadInstaller) { - if (urlAndVersion[0] != null) { - byte[] buffer = new byte[8192]; - DownloadUtils.downloadFileMonitored(urlAndVersion[0], mDestinationFile, buffer, this); - if(urlAndVersion[1] != null) { - try { - Tools.write(versionFile.getAbsolutePath(), urlAndVersion[1]); - }catch (IOException e) { - e.printStackTrace(); - } - } - return true; - } else { - mModloaderDownloadListener.onDataNotAvailable(); - return false; - } - }else{ - return true; - } - } - - @Override - public void updateProgress(int curr, int max) { - int progress100 = (int)(((float)curr / (float)max)*100f); - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, progress100, R.string.fabric_dl_progress); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricMetaReader.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricMetaReader.java deleted file mode 100644 index 151c61c2a..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricMetaReader.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import org.json.JSONException; -import org.json.JSONObject; - -public interface FabricMetaReader { - boolean processMetadata(JSONObject jsonObject) throws JSONException; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricUtils.java deleted file mode 100644 index 83f849a78..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/FabricUtils.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import android.content.Intent; - -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -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 downloadLoaderVersionList(boolean onlyStable) throws IOException { - try { - return DownloadUtils.downloadStringCached(FABRIC_LOADER_METADATA_URL, - "fabric_loader_versions", (input)->{ - final List 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); - 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, - String gameVersion, String loaderVersion, - boolean isSnapshot, boolean createProfile) { - intent.putExtra("javaArgs", "-jar " + modInstalllerJar.getAbsolutePath() + " client -dir "+ Tools.DIR_GAME_NEW - + " -mcversion "+gameVersion +" -loader "+loaderVersion + - (isSnapshot ? " -snapshot" : "") + - (createProfile ? "" : " -noprofile")); - intent.putExtra("openLogOutput", true); - - } - - 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++) { - metadataObject = fullMetadata.getJSONObject(i); - if(metaReader.processMetadata(metadataObject)) return metadataObject; - } - return metadataObject; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeDownloadTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeDownloadTask.java deleted file mode 100644 index 60dcd9b2d..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeDownloadTask.java +++ /dev/null @@ -1,48 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import com.kdt.mcgui.ProgressLayout; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - -public class ForgeDownloadTask implements Runnable, Tools.DownloaderFeedback { - private final String mForgeUrl; - private final String mForgeVersion; - private final File mDestinationFile; - private final ModloaderDownloadListener mListener; - public ForgeDownloadTask(ModloaderDownloadListener listener, String forgeVersion, File destinationFile) { - this.mListener = listener; - this.mForgeUrl = ForgeUtils.getInstallerUrl(forgeVersion); - this.mForgeVersion = forgeVersion; - this.mDestinationFile = destinationFile; - } - @Override - public void run() { - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.forge_dl_progress, mForgeVersion); - try { - byte[] buffer = new byte[8192]; - DownloadUtils.downloadFileMonitored(mForgeUrl, mDestinationFile, buffer, this); - mListener.onDownloadFinished(mDestinationFile); - }catch (IOException e) { - if(e instanceof FileNotFoundException) { - mListener.onDataNotAvailable(); - }else{ - mListener.onDownloadError(e); - } - } - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, -1, -1); - } - - @Override - public void updateProgress(int curr, int max) { - int progress100 = (int)(((float)curr / (float)max)*100f); - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, progress100, R.string.forge_dl_progress, mForgeVersion); - } - -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeUtils.java deleted file mode 100644 index 31420de90..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeUtils.java +++ /dev/null @@ -1,62 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import android.content.Intent; - -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; - -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -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 downloadForgeVersions() throws IOException { - SAXParser saxParser; - try { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - 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 { - //of_test(); - 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); - } - - public static void addAutoInstallArgs(Intent intent, File modInstallerJar, boolean createProfile) { - intent.putExtra("javaArgs", "-javaagent:"+ Tools.DIR_DATA+"/forge_installer/forge_installer.jar" - + (createProfile ? "=NPS" : "") + // No Profile Suppression - " -jar "+modInstallerJar.getAbsolutePath()); - intent.putExtra("skipDetectMod", true); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListAdapter.java deleted file mode 100644 index 4b96cd03e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListAdapter.java +++ /dev/null @@ -1,102 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; -import android.widget.ExpandableListAdapter; -import android.widget.TextView; - -import java.util.ArrayList; -import java.util.List; - -public class ForgeVersionListAdapter extends BaseExpandableListAdapter implements ExpandableListAdapter { - private final List mGameVersions; - private final List> mForgeVersions; - private final LayoutInflater mLayoutInflater; - - public ForgeVersionListAdapter(List forgeVersions, LayoutInflater layoutInflater) { - this.mLayoutInflater = layoutInflater; - mGameVersions = new ArrayList<>(); - mForgeVersions = new ArrayList<>(); - for(String version : forgeVersions) { - int dashIndex = version.indexOf("-"); - String gameVersion = version.substring(0, dashIndex); - List versionList; - int gameVersionIndex = mGameVersions.indexOf(gameVersion); - if(gameVersionIndex != -1) versionList = mForgeVersions.get(gameVersionIndex); - else { - versionList = new ArrayList<>(); - mGameVersions.add(gameVersion); - mForgeVersions.add(versionList); - } - versionList.add(version); - } - } - - @Override - public int getGroupCount() { - return mGameVersions.size(); - } - - @Override - public int getChildrenCount(int i) { - return mForgeVersions.get(i).size(); - } - - @Override - public Object getGroup(int i) { - return getGameVersion(i); - } - - @Override - public Object getChild(int i, int i1) { - return getForgeVersion(i, i1); - } - - @Override - public long getGroupId(int i) { - return i; - } - - @Override - public long getChildId(int i, int i1) { - return i1; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getGroupView(int i, boolean b, View convertView, ViewGroup viewGroup) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, viewGroup, false); - - ((TextView) convertView).setText(getGameVersion(i)); - - return convertView; - } - - @Override - public View getChildView(int i, int i1, boolean b, View convertView, ViewGroup viewGroup) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, viewGroup, false); - ((TextView) convertView).setText(getForgeVersion(i, i1)); - return convertView; - } - - private String getGameVersion(int i) { - return mGameVersions.get(i); - } - - private String getForgeVersion(int i, int i1){ - return mForgeVersions.get(i).get(i1); - } - - @Override - public boolean isChildSelectable(int i, int i1) { - return true; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListHandler.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListHandler.java deleted file mode 100644 index 8de024ccd..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ForgeVersionListHandler.java +++ /dev/null @@ -1,39 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import java.util.ArrayList; -import java.util.List; - -public class ForgeVersionListHandler extends DefaultHandler { - private List mForgeVersions; - private StringBuilder mCurrentVersion = null; - @Override - public void startDocument() throws SAXException { - mForgeVersions = new ArrayList<>(); - } - - @Override - public void characters(char[] ch, int start, int length) throws SAXException { - if(mCurrentVersion != null) mCurrentVersion.append(ch, start, length); - } - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - if(qName.equals("version")) mCurrentVersion = new StringBuilder(); - } - - @Override - public void endElement(String uri, String localName, String qName) throws SAXException { - if (qName.equals("version")) { - String version = mCurrentVersion.toString(); - mForgeVersions.add(version); - mCurrentVersion = null; - } - } - public List getVersions() { - return mForgeVersions; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderDownloadListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderDownloadListener.java deleted file mode 100644 index 9260d4cbc..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderDownloadListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import java.io.File; - -public interface ModloaderDownloadListener { - void onDownloadFinished(File downloadedFile); - void onDataNotAvailable(); - void onDownloadError(Exception e); -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderListenerProxy.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderListenerProxy.java deleted file mode 100644 index 97713c9e4..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/ModloaderListenerProxy.java +++ /dev/null @@ -1,61 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import java.io.File; - -public class ModloaderListenerProxy implements ModloaderDownloadListener { - public static final int PROXY_RESULT_NONE = -1; - public static final int PROXY_RESULT_FINISHED = 0; - public static final int PROXY_RESULT_NOT_AVAILABLE = 1; - public static final int PROXY_RESULT_ERROR = 2; - private ModloaderDownloadListener mDestinationListener; - private Object mProxyResultObject; - private int mProxyResult = PROXY_RESULT_NONE; - - @Override - public synchronized void onDownloadFinished(File downloadedFile) { - if(mDestinationListener != null) { - mDestinationListener.onDownloadFinished(downloadedFile); - }else{ - mProxyResult = PROXY_RESULT_FINISHED; - mProxyResultObject = downloadedFile; - } - } - - @Override - public synchronized void onDataNotAvailable() { - if(mDestinationListener != null) { - mDestinationListener.onDataNotAvailable(); - }else{ - mProxyResult = PROXY_RESULT_NOT_AVAILABLE; - mProxyResultObject = null; - } - } - - @Override - public synchronized void onDownloadError(Exception e) { - if(mDestinationListener != null) { - mDestinationListener.onDownloadError(e); - }else { - mProxyResult = PROXY_RESULT_ERROR; - mProxyResultObject = e; - } - } - - public synchronized void attachListener(ModloaderDownloadListener listener) { - switch(mProxyResult) { - case PROXY_RESULT_FINISHED: - listener.onDownloadFinished((File) mProxyResultObject); - break; - case PROXY_RESULT_NOT_AVAILABLE: - listener.onDataNotAvailable(); - break; - case PROXY_RESULT_ERROR: - listener.onDownloadError((Exception) mProxyResultObject); - break; - } - mDestinationListener = listener; - } - public synchronized void detachListener() { - mDestinationListener = null; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OFDownloadPageScraper.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OFDownloadPageScraper.java deleted file mode 100644 index 62d74b2eb..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OFDownloadPageScraper.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import org.htmlcleaner.HtmlCleaner; -import org.htmlcleaner.HtmlNode; -import org.htmlcleaner.TagNode; -import org.htmlcleaner.TagNodeVisitor; - -import java.io.IOException; -import java.net.URL; - -public class OFDownloadPageScraper implements TagNodeVisitor { - public static String run(String urlInput) throws IOException{ - return new OFDownloadPageScraper().runInner(urlInput); - } - - private String mDownloadFullUrl; - - private String runInner(String url) throws IOException { - HtmlCleaner htmlCleaner = new HtmlCleaner(); - htmlCleaner.clean(new URL(url)).traverse(this); - return mDownloadFullUrl; - } - - @Override - public boolean visit(TagNode parentNode, HtmlNode htmlNode) { - if(isDownloadUrl(parentNode, htmlNode)) { - TagNode tagNode = (TagNode) htmlNode; - String href = tagNode.getAttributeByName("href"); - if(!href.startsWith("https://")) href = "https://optifine.net/"+href; - this.mDownloadFullUrl = href; - return false; - } - return true; - } - - public boolean isDownloadUrl(TagNode parentNode, HtmlNode htmlNode) { - if(!(htmlNode instanceof TagNode)) return false; - if(parentNode == null) return false; - TagNode tagNode = (TagNode) htmlNode; - if(!(parentNode.getName().equals("span") - && "Download".equals(parentNode.getAttributeByName("id")))) return false; - return tagNode.getName().equals("a") && - "onDownload()".equals(tagNode.getAttributeByName("onclick")); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineDownloadTask.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineDownloadTask.java deleted file mode 100644 index c5278340d..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineDownloadTask.java +++ /dev/null @@ -1,121 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import com.kdt.mcgui.ProgressLayout; - -import net.kdt.pojavlaunch.JMinecraftVersionList; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.tasks.AsyncMinecraftDownloader; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import java.io.File; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class OptiFineDownloadTask implements Runnable, Tools.DownloaderFeedback, AsyncMinecraftDownloader.DoneListener { - private static final Pattern sMcVersionPattern = Pattern.compile("([0-9]+)\\.([0-9]+)\\.?([0-9]+)?"); - private final OptiFineUtils.OptiFineVersion mOptiFineVersion; - private final File mDestinationFile; - private final ModloaderDownloadListener mListener; - private final Object mMinecraftDownloadLock = new Object(); - private Throwable mDownloaderThrowable; - - public OptiFineDownloadTask(OptiFineUtils.OptiFineVersion mOptiFineVersion, File mDestinationFile, ModloaderDownloadListener mListener) { - this.mOptiFineVersion = mOptiFineVersion; - this.mDestinationFile = mDestinationFile; - this.mListener = mListener; - } - - @Override - public void run() { - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.of_dl_progress, mOptiFineVersion.versionName); - try { - if(runCatching()) mListener.onDownloadFinished(mDestinationFile); - }catch (IOException e) { - mListener.onDownloadError(e); - } - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, -1, -1); - } - - public boolean runCatching() throws IOException { - String downloadUrl = scrapeDownloadsPage(); - if(downloadUrl == null) return false; - String minecraftVersion = determineMinecraftVersion(); - if(minecraftVersion == null) return false; - if(!downloadMinecraft(minecraftVersion)) { - if(mDownloaderThrowable instanceof Exception) { - mListener.onDownloadError((Exception) mDownloaderThrowable); - }else { - Exception exception = new Exception(mDownloaderThrowable); - mListener.onDownloadError(exception); - } - return false; - } - DownloadUtils.downloadFileMonitored(downloadUrl, mDestinationFile, new byte[8192], this); - return true; - } - - public String scrapeDownloadsPage() throws IOException{ - String scrapeResult = OFDownloadPageScraper.run(mOptiFineVersion.downloadUrl); - if(scrapeResult == null) mListener.onDataNotAvailable(); - return scrapeResult; - } - - public String determineMinecraftVersion() { - Matcher matcher = sMcVersionPattern.matcher(mOptiFineVersion.minecraftVersion); - if(matcher.find()) { - StringBuilder mcVersionBuilder = new StringBuilder(); - mcVersionBuilder.append(matcher.group(1)); - mcVersionBuilder.append('.'); - mcVersionBuilder.append(matcher.group(2)); - String thirdGroup = matcher.group(3); - if(thirdGroup != null && !thirdGroup.isEmpty() && !"0".equals(thirdGroup)) { - mcVersionBuilder.append('.'); - mcVersionBuilder.append(thirdGroup); - } - return mcVersionBuilder.toString(); - }else{ - mListener.onDataNotAvailable(); - return null; - } - } - - public boolean downloadMinecraft(String minecraftVersion) { - // the string is always normalized - JMinecraftVersionList.Version minecraftJsonVersion = AsyncMinecraftDownloader.getListedVersion(minecraftVersion); - if(minecraftJsonVersion == null) return false; - try { - synchronized (mMinecraftDownloadLock) { - new AsyncMinecraftDownloader(null, minecraftJsonVersion, minecraftVersion, this); - mMinecraftDownloadLock.wait(); - } - }catch (InterruptedException e) { - e.printStackTrace(); - } - return mDownloaderThrowable == null; - } - - @Override - public void updateProgress(int curr, int max) { - int progress100 = (int)(((float)curr / (float)max)*100f); - ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, progress100, R.string.of_dl_progress, mOptiFineVersion.versionName); - } - - @Override - public void onDownloadDone() { - synchronized (mMinecraftDownloadLock) { - mDownloaderThrowable = null; - mMinecraftDownloadLock.notifyAll(); - } - } - - @Override - public void onDownloadFailed(Throwable throwable) { - synchronized (mMinecraftDownloadLock) { - mDownloaderThrowable = throwable; - mMinecraftDownloadLock.notifyAll(); - } - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineScraper.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineScraper.java deleted file mode 100644 index 56a89bd02..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineScraper.java +++ /dev/null @@ -1,90 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import org.htmlcleaner.HtmlCleaner; -import org.htmlcleaner.TagNode; - -import java.util.ArrayList; -import java.util.List; - -public class OptiFineScraper implements DownloadUtils.ParseCallback { - private final OptiFineUtils.OptiFineVersions mOptiFineVersions; - private List mListInProgress; - private String mMinecraftVersion; - - public OptiFineScraper() { - mOptiFineVersions = new OptiFineUtils.OptiFineVersions(); - mOptiFineVersions.minecraftVersions = new ArrayList<>(); - mOptiFineVersions.optifineVersions = new ArrayList<>(); - } - - @Override - public OptiFineUtils.OptiFineVersions process(String input) throws DownloadUtils.ParseException { - HtmlCleaner htmlCleaner = new HtmlCleaner(); - TagNode tagNode = htmlCleaner.clean(input); - traverseTagNode(tagNode); - insertVersionContent(null); - if(mOptiFineVersions.optifineVersions.size() < 1 || - mOptiFineVersions.minecraftVersions.size() < 1) throw new DownloadUtils.ParseException(null); - return mOptiFineVersions; - } - - public void traverseTagNode(TagNode tagNode) { - if(isDownloadLine(tagNode) && mMinecraftVersion != null) { - traverseDownloadLine(tagNode); - } else if(isMinecraftVersionTag(tagNode)) { - insertVersionContent(tagNode); - } else { - for(TagNode tagNodes : tagNode.getChildTags()) { - traverseTagNode(tagNodes); - } - } - } - - private boolean isDownloadLine(TagNode tagNode) { - return tagNode.getName().equals("tr") && - tagNode.hasAttribute("class") && - tagNode.getAttributeByName("class").startsWith("downloadLine"); - } - - private boolean isMinecraftVersionTag(TagNode tagNode) { - return tagNode.getName().equals("h2") && - tagNode.getText().toString().startsWith("Minecraft "); - } - - private void traverseDownloadLine(TagNode tagNode) { - OptiFineUtils.OptiFineVersion optiFineVersion = new OptiFineUtils.OptiFineVersion(); - optiFineVersion.minecraftVersion = mMinecraftVersion; - for(TagNode subNode : tagNode.getChildTags()) { - if(!subNode.getName().equals("td")) continue; - switch(subNode.getAttributeByName("class")) { - case "colFile": - optiFineVersion.versionName = subNode.getText().toString(); - break; - case "colMirror": - optiFineVersion.downloadUrl = getLinkHref(subNode); - } - } - mListInProgress.add(optiFineVersion); - } - private String getLinkHref(TagNode parent) { - for(TagNode subNode : parent.getChildTags()) { - if(subNode.getName().equals("a") && subNode.hasAttribute("href")) { - return subNode.getAttributeByName("href").replace("http://", "https://"); - } - } - return null; - } - - private void insertVersionContent(TagNode tagNode) { - if(mListInProgress != null && mMinecraftVersion != null) { - mOptiFineVersions.minecraftVersions.add(mMinecraftVersion); - mOptiFineVersions.optifineVersions.add(mListInProgress); - } - if(tagNode != null) { - mMinecraftVersion = tagNode.getText().toString(); - mListInProgress = new ArrayList<>(); - } - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineUtils.java deleted file mode 100644 index 32cf9938b..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import android.content.Intent; - -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.utils.DownloadUtils; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -public class OptiFineUtils { - - public static OptiFineVersions downloadOptiFineVersions() throws IOException { - try { - return DownloadUtils.downloadStringCached("https://optifine.net/downloads", - "of_downloads_page", new OptiFineScraper()); - }catch (DownloadUtils.ParseException e) { - e.printStackTrace(); - return null; - } - } - - public static void addAutoInstallArgs(Intent intent, File modInstallerJar) { - intent.putExtra("javaArgs", "-javaagent:"+ Tools.DIR_DATA+"/forge_installer/forge_installer.jar" - + "=OFNPS" +// No Profile Suppression - " -jar "+modInstallerJar.getAbsolutePath()); - intent.putExtra("skipDetectMod", true); - } - - public static class OptiFineVersions { - public List minecraftVersions; - public List> optifineVersions; - } - public static class OptiFineVersion { - public String minecraftVersion; - public String versionName; - public String downloadUrl; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineVersionListAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineVersionListAdapter.java deleted file mode 100644 index a63111398..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/modloaders/OptiFineVersionListAdapter.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.kdt.pojavlaunch.modloaders; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; -import android.widget.ExpandableListAdapter; -import android.widget.TextView; - -public class OptiFineVersionListAdapter extends BaseExpandableListAdapter implements ExpandableListAdapter { - - private final OptiFineUtils.OptiFineVersions mOptiFineVersions; - private final LayoutInflater mLayoutInflater; - - public OptiFineVersionListAdapter(OptiFineUtils.OptiFineVersions optiFineVersions, LayoutInflater mLayoutInflater) { - mOptiFineVersions = optiFineVersions; - this.mLayoutInflater = mLayoutInflater; - } - - @Override - public int getGroupCount() { - return mOptiFineVersions.minecraftVersions.size(); - } - - @Override - public int getChildrenCount(int i) { - return mOptiFineVersions.optifineVersions.get(i).size(); - } - - @Override - public Object getGroup(int i) { - return mOptiFineVersions.minecraftVersions.get(i); - } - - @Override - public Object getChild(int i, int i1) { - return mOptiFineVersions.optifineVersions.get(i).get(i1); - } - - @Override - public long getGroupId(int i) { - return i; - } - - @Override - public long getChildId(int i, int i1) { - return i1; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getGroupView(int i, boolean b, View convertView, ViewGroup viewGroup) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, viewGroup, false); - - ((TextView) convertView).setText((String)getGroup(i)); - - return convertView; - } - - @Override - public View getChildView(int i, int i1, boolean b, View convertView, ViewGroup viewGroup) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, viewGroup, false); - ((TextView) convertView).setText(((OptiFineUtils.OptiFineVersion)getChild(i,i1)).versionName); - return convertView; - } - - @Override - public boolean isChildSelectable(int i, int i1) { - return true; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/plugins/FFmpegPlugin.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/plugins/FFmpegPlugin.java deleted file mode 100644 index bd1b30812..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/plugins/FFmpegPlugin.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.kdt.pojavlaunch.plugins; - -import android.content.Context; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.util.Log; - -public class FFmpegPlugin { - public static boolean isAvailable = false; - public static String libraryPath; - public static void discover(Context context) { - PackageManager manager = context.getPackageManager(); - try { - PackageInfo ffmpegPluginInfo = manager.getPackageInfo("net.kdt.pojavlaunch.ffmpeg", PackageManager.GET_SHARED_LIBRARY_FILES); - libraryPath = ffmpegPluginInfo.applicationInfo.nativeLibraryDir; - isAvailable = true; - }catch (Exception e) { - Log.i("FFmpegPlugin", "Failed to discover plugin", e); - } - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/BackButtonPreference.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/BackButtonPreference.java index 22a4be7f1..7a6678586 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/BackButtonPreference.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/BackButtonPreference.java @@ -1,13 +1,10 @@ package net.kdt.pojavlaunch.prefs; -import android.app.Activity; import android.content.Context; import android.util.AttributeSet; -import android.util.Log; import androidx.preference.Preference; -import net.kdt.pojavlaunch.LauncherActivity; import net.kdt.pojavlaunch.R; import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java deleted file mode 100644 index a3a9266da..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapter.java +++ /dev/null @@ -1,137 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -import android.content.Context; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; - -import androidx.core.graphics.ColorUtils; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; -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; - -import fr.spse.extended_view.ExtendedTextView; - -/* - * Adapter for listing launcher profiles in a Spinner - */ -public class ProfileAdapter extends BaseAdapter { - private Map mProfiles; - private final MinecraftProfile dummy = new MinecraftProfile(); - private List mProfileList; - private final ProfileAdapterExtra[] mExtraEntires; - - public ProfileAdapter(Context context, ProfileAdapterExtra[] extraEntries) { - ProfileIconCache.initDefault(context); - LauncherProfiles.update(); - mProfiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles); - if(extraEntries == null) mExtraEntires = new ProfileAdapterExtra[0]; - else mExtraEntires = extraEntries; - mProfileList = new ArrayList<>(Arrays.asList(mProfiles.keySet().toArray(new String[0]))); - } - /* - * Gets how much profiles are loaded in the adapter right now - * @returns loaded profile count - */ - @Override - public int getCount() { - return mProfileList.size() + mExtraEntires.length; - } - /* - * Gets the profile at a given index - * @param position index to retreive - * @returns MinecraftProfile name or null - */ - @Override - public Object getItem(int position) { - int profileListSize = mProfileList.size(); - int extraPosition = position - profileListSize; - if(position < profileListSize){ - String profileName = mProfileList.get(position); - if(mProfiles.containsKey(profileName)) return profileName; - }else if(extraPosition >= 0 && extraPosition < mExtraEntires.length) { - return mExtraEntires[extraPosition]; - } - return null; - } - - public int resolveProfileIndex(String name) { - return mProfileList.indexOf(name); - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public void notifyDataSetChanged() { - mProfiles = new HashMap<>(LauncherProfiles.mainProfileJson.profiles); - mProfileList = new ArrayList<>(Arrays.asList(mProfiles.keySet().toArray(new String[0]))); - 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.item_version_profile_layout,parent,false); - Object profileObject = getItem(position); - if(profileObject instanceof String) setViewProfile(v, (String) profileObject, true); - else if(profileObject instanceof ProfileAdapterExtra) setViewExtra(v, (ProfileAdapterExtra) profileObject); - return v; - } - - public void setViewProfile(View v, String nm, boolean displaySelection) { - ExtendedTextView extendedTextView = (ExtendedTextView) v; - - MinecraftProfile minecraftProfile = mProfiles.get(nm); - if(minecraftProfile == null) minecraftProfile = dummy; - Drawable cachedIcon = ProfileIconCache.getCachedIcon(nm); - - if(cachedIcon == null) { - cachedIcon = ProfileIconCache.tryResolveIcon(v.getResources(), nm, minecraftProfile.icon); - } - extendedTextView.setCompoundDrawablesRelative(cachedIcon, null, extendedTextView.getCompoundsDrawables()[2], null); - - if(Tools.isValidString(minecraftProfile.name)) - extendedTextView.setText(minecraftProfile.name); - else - extendedTextView.setText(R.string.unnamed); - - if(minecraftProfile.lastVersionId != null){ - if(minecraftProfile.lastVersionId.equalsIgnoreCase("latest-release")){ - extendedTextView.setText( String.format("%s - %s", extendedTextView.getText(), v.getContext().getText(R.string.profiles_latest_release))); - } else if(minecraftProfile.lastVersionId.equalsIgnoreCase("latest-snapshot")){ - extendedTextView.setText( String.format("%s - %s", extendedTextView.getText(), v.getContext().getText(R.string.profiles_latest_snapshot))); - } else { - extendedTextView.setText( String.format("%s - %s", extendedTextView.getText(), minecraftProfile.lastVersionId)); - } - - } else extendedTextView.setText(extendedTextView.getText()); - - // Set selected background if needed - if(displaySelection){ - String selectedProfile = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE,""); - extendedTextView.setBackgroundColor(selectedProfile.equals(nm) ? ColorUtils.setAlphaComponent(Color.WHITE,60) : Color.TRANSPARENT); - }else extendedTextView.setBackgroundColor(Color.TRANSPARENT); - } - - public void setViewExtra(View v, ProfileAdapterExtra extra) { - ExtendedTextView extendedTextView = (ExtendedTextView) v; - extendedTextView.setCompoundDrawablesRelative(extra.icon, null, extendedTextView.getCompoundsDrawables()[2], null); - extendedTextView.setText(extra.name); - extendedTextView.setBackgroundColor(Color.TRANSPARENT); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java deleted file mode 100644 index b09d39b5c..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileAdapterExtra.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -import android.graphics.drawable.Drawable; - -public class ProfileAdapterExtra { - public final int id; - public final int name; - public final Drawable icon; - - public ProfileAdapterExtra(int id, int name, Drawable icon) { - this.id = id; - this.name = name; - this.icon = icon; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java deleted file mode 100644 index ccbd05470..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/ProfileIconCache.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.BitmapFactory; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.util.Base64; -import android.util.Log; - -import androidx.core.content.res.ResourcesCompat; - -import net.kdt.pojavlaunch.R; - -import java.util.HashMap; -import java.util.Map; - -public class ProfileIconCache { - private static final String BASE64_PNG_HEADER = "data:image/png;base64,"; - private static final Map sIconCache = new HashMap<>(); - private static Drawable sDefaultIcon; - - - public static void initDefault(Context context) { - if(sDefaultIcon != null) return; - sDefaultIcon = ResourcesCompat.getDrawable(context.getResources(), R.mipmap.ic_launcher_foreground, null); - if(sDefaultIcon != null) sDefaultIcon.setBounds(0, 0, 10, 10); - } - - public static Drawable getCachedIcon(String key) { - return sIconCache.get(key); - } - - public static Drawable submitIcon(Resources resources, String key, String base64) { - byte[] pngBytes = Base64.decode(base64, Base64.DEFAULT); - Drawable drawable = new BitmapDrawable(resources, BitmapFactory.decodeByteArray(pngBytes, 0, pngBytes.length)); - sIconCache.put(key, drawable); - return drawable; - } - - public static Drawable tryResolveIcon(Resources resources, String profileName, String b64Icon) { - Drawable icon; - if (b64Icon != null && b64Icon.startsWith(BASE64_PNG_HEADER)) { - icon = ProfileIconCache.submitIcon(resources, profileName, b64Icon.substring(BASE64_PNG_HEADER.length())); - }else{ - Log.i("IconParser","Unsupported icon: "+b64Icon); - icon = ProfileIconCache.pushDefaultIcon(profileName); - } - return icon; - } - - public static Drawable pushDefaultIcon(String key) { - sIconCache.put(key, sDefaultIcon); - - return sDefaultIcon; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionListAdapter.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionListAdapter.java deleted file mode 100644 index 6b54d0474..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionListAdapter.java +++ /dev/null @@ -1,136 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; -import android.widget.ExpandableListAdapter; -import android.widget.TextView; - -import net.kdt.pojavlaunch.JMinecraftVersionList; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.utils.FilteredSubList; - -import java.io.File; -import java.util.Arrays; -import java.util.List; - -public class VersionListAdapter extends BaseExpandableListAdapter implements ExpandableListAdapter { - - private final LayoutInflater mLayoutInflater; - - private final String[] mGroups; - private final String[] mInstalledVersions; - private final List[] mData; - private final boolean mHideCustomVersions; - private final int mSnapshotListPosition; - - public VersionListAdapter(JMinecraftVersionList.Version[] versionList, boolean hideCustomVersions, Context ctx){ - mHideCustomVersions = hideCustomVersions; - mLayoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - - List releaseList = new FilteredSubList<>(versionList, item -> item.type.equals("release")); - List snapshotList = new FilteredSubList<>(versionList, item -> item.type.equals("snapshot")); - List betaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_beta")); - List alphaList = new FilteredSubList<>(versionList, item -> item.type.equals("old_alpha")); - - // Query installed versions - mInstalledVersions = new File(Tools.DIR_GAME_NEW + "/versions").list(); - if(!areInstalledVersionsAvailable()){ - mGroups = new String[]{ - ctx.getString(R.string.mcl_setting_veroption_release), - ctx.getString(R.string.mcl_setting_veroption_snapshot), - ctx.getString(R.string.mcl_setting_veroption_oldbeta), - ctx.getString(R.string.mcl_setting_veroption_oldalpha) - }; - mData = new List[]{ releaseList, snapshotList, betaList, alphaList}; - mSnapshotListPosition = 1; - }else{ - mGroups = new String[]{ - ctx.getString(R.string.mcl_setting_veroption_installed), - ctx.getString(R.string.mcl_setting_veroption_release), - ctx.getString(R.string.mcl_setting_veroption_snapshot), - ctx.getString(R.string.mcl_setting_veroption_oldbeta), - ctx.getString(R.string.mcl_setting_veroption_oldalpha) - }; - mData = new List[]{Arrays.asList(mInstalledVersions), releaseList, snapshotList, betaList, alphaList}; - mSnapshotListPosition = 2; - } - } - - @Override - public int getGroupCount() { - return mGroups.length; - } - - @Override - public int getChildrenCount(int groupPosition) { - return mData[groupPosition].size(); - } - - @Override - public Object getGroup(int groupPosition) { - return mData[groupPosition]; - } - - @Override - public String getChild(int groupPosition, int childPosition) { - if(isInstalledVersionSelected(groupPosition)){ - return mInstalledVersions[childPosition]; - } - return ((JMinecraftVersionList.Version)mData[groupPosition].get(childPosition)).id; - } - - @Override - public long getGroupId(int groupPosition) { - return groupPosition; - } - - @Override - public long getChildId(int groupPosition, int childPosition) { - return childPosition; - } - - @Override - public boolean hasStableIds() { - return true; - } - - @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false); - - ((TextView) convertView).setText(mGroups[groupPosition]); - - return convertView; - } - - @Override - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { - if(convertView == null) - convertView = mLayoutInflater.inflate(android.R.layout.simple_expandable_list_item_1, parent, false); - ((TextView) convertView).setText(getChild(groupPosition, childPosition)); - return convertView; - } - - @Override - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - - public boolean isSnapshotSelected(int groupPosition) { - return groupPosition == mSnapshotListPosition; - } - - private boolean areInstalledVersionsAvailable(){ - if(mHideCustomVersions) return false; - return !(mInstalledVersions == null || mInstalledVersions.length == 0); - } - - private boolean isInstalledVersionSelected(int groupPosition){ - return groupPosition == 0 && areInstalledVersionsAvailable(); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorDialog.java deleted file mode 100644 index c88714c7f..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorDialog.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -import static net.kdt.pojavlaunch.extra.ExtraCore.getValue; - -import android.content.Context; -import android.view.LayoutInflater; -import android.widget.ExpandableListView; - -import androidx.appcompat.app.AlertDialog; - -import net.kdt.pojavlaunch.JMinecraftVersionList; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.extra.ExtraConstants; - -public class VersionSelectorDialog { - public static void open(Context context, boolean hideCustomVersions, VersionSelectorListener listener) { - AlertDialog.Builder builder = new AlertDialog.Builder(context); - ExpandableListView expandableListView = (ExpandableListView) LayoutInflater.from(context) - .inflate(R.layout.dialog_expendable_list_view , null); - JMinecraftVersionList jMinecraftVersionList = (JMinecraftVersionList) getValue(ExtraConstants.RELEASE_TABLE); - JMinecraftVersionList.Version[] versionArray; - if(jMinecraftVersionList == null || jMinecraftVersionList.versions == null) versionArray = new JMinecraftVersionList.Version[0]; - else versionArray = jMinecraftVersionList.versions; - VersionListAdapter adapter = new VersionListAdapter(versionArray, hideCustomVersions, context); - - expandableListView.setAdapter(adapter); - builder.setView(expandableListView); - AlertDialog dialog = builder.show(); - - expandableListView.setOnChildClickListener((parent, v1, groupPosition, childPosition, id) -> { - String version = adapter.getChild(groupPosition, childPosition); - listener.onVersionSelected(version, adapter.isSnapshotSelected(groupPosition)); - dialog.dismiss(); - return true; - }); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorListener.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorListener.java deleted file mode 100644 index 0d48a9207..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/profiles/VersionSelectorListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.kdt.pojavlaunch.profiles; - -public interface VersionSelectorListener { - void onVersionSelected(String versionId, boolean isSnapshot); -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/FolderProvider.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/FolderProvider.java deleted file mode 100644 index 2ce9dc901..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/scoped/FolderProvider.java +++ /dev/null @@ -1,335 +0,0 @@ -package net.kdt.pojavlaunch.scoped; - -import android.annotation.TargetApi; -import android.content.res.AssetFileDescriptor; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.graphics.Point; -import android.os.CancellationSignal; -import android.os.ParcelFileDescriptor; -import android.provider.DocumentsContract; -import android.provider.DocumentsContract.Document; -import android.provider.DocumentsContract.Root; -import android.provider.DocumentsProvider; -import android.util.Log; -import android.webkit.MimeTypeMap; - -import androidx.annotation.Nullable; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; - -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; - -/** - * A document provider for the Storage Access Framework which exposes the files in the - * $HOME/ directory to other apps. - *

- * Note that this replaces providing an activity matching the ACTION_GET_CONTENT intent: - *

- * "A document provider and ACTION_GET_CONTENT should be considered mutually exclusive. If you - * support both of them simultaneously, your app will appear twice in the system picker UI, - * offering two different ways of accessing your stored data. This would be confusing for users." - * - ... - */ -public class FolderProvider extends DocumentsProvider { - - private static final String ALL_MIME_TYPES = "*/*"; - - private static final File BASE_DIR = new File(Tools.DIR_GAME_HOME); - - - // The default columns to return information about a root if no specific - // columns are requested in a query. - private static final String[] DEFAULT_ROOT_PROJECTION = new String[]{ - Root.COLUMN_ROOT_ID, - Root.COLUMN_MIME_TYPES, - Root.COLUMN_FLAGS, - Root.COLUMN_ICON, - Root.COLUMN_TITLE, - Root.COLUMN_SUMMARY, - Root.COLUMN_DOCUMENT_ID, - Root.COLUMN_AVAILABLE_BYTES - }; - - // The default columns to return information about a document if no specific - // columns are requested in a query. - private static final String[] DEFAULT_DOCUMENT_PROJECTION = new String[]{ - Document.COLUMN_DOCUMENT_ID, - Document.COLUMN_MIME_TYPE, - Document.COLUMN_DISPLAY_NAME, - Document.COLUMN_LAST_MODIFIED, - Document.COLUMN_FLAGS, - Document.COLUMN_SIZE - }; - - @Override - public Cursor queryRoots(String[] projection) { - final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_ROOT_PROJECTION); - final String applicationName = getContext().getString(R.string.app_short_name); - - final MatrixCursor.RowBuilder row = result.newRow(); - row.add(Root.COLUMN_ROOT_ID, getDocIdForFile(BASE_DIR)); - row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(BASE_DIR)); - row.add(Root.COLUMN_SUMMARY, null); - row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD); - row.add(Root.COLUMN_TITLE, applicationName); - row.add(Root.COLUMN_MIME_TYPES, ALL_MIME_TYPES); - row.add(Root.COLUMN_AVAILABLE_BYTES, BASE_DIR.getFreeSpace()); - row.add(Root.COLUMN_ICON, R.mipmap.ic_launcher); - return result; - } - - @Override - public Cursor queryDocument(String documentId, String[] projection) throws FileNotFoundException { - final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION); - includeFile(result, documentId, null); - return result; - } - - @Override - public Cursor queryChildDocuments(String parentDocumentId, String[] projection, String sortOrder) throws FileNotFoundException { - final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION); - final File parent = getFileForDocId(parentDocumentId); - final File[] children = parent.listFiles(); - if(children == null) throw new FileNotFoundException("Unable to list files in "+parent.getAbsolutePath()); - for (File file : children) { - includeFile(result, null, file); - } - return result; - } - - @Override - public ParcelFileDescriptor openDocument(final String documentId, String mode, CancellationSignal signal) throws FileNotFoundException { - final File file = getFileForDocId(documentId); - final int accessMode = ParcelFileDescriptor.parseMode(mode); - return ParcelFileDescriptor.open(file, accessMode); - } - - @Override - public AssetFileDescriptor openDocumentThumbnail(String documentId, Point sizeHint, CancellationSignal signal) throws FileNotFoundException { - final File file = getFileForDocId(documentId); - final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); - return new AssetFileDescriptor(pfd, 0, file.length()); - } - - @Override - public boolean onCreate() { - return true; - } - - @Override - public String createDocument(String parentDocumentId, String mimeType, String displayName) throws FileNotFoundException { - File newFile = new File(parentDocumentId, displayName); - int noConflictId = 2; - while (newFile.exists()) { - newFile = new File(parentDocumentId, displayName + " (" + noConflictId++ + ")"); - } - try { - boolean succeeded; - if (Document.MIME_TYPE_DIR.equals(mimeType)) { - succeeded = newFile.mkdir(); - } else { - succeeded = newFile.createNewFile(); - } - if (!succeeded) { - throw new FileNotFoundException("Failed to create document with id " + newFile.getPath()); - } - } catch (IOException e) { - throw new FileNotFoundException("Failed to create document with id " + newFile.getPath()); - } - return newFile.getPath(); - } - - @Override - public String renameDocument(String documentId, String displayName) throws FileNotFoundException { - File sourceFile = getFileForDocId(documentId); - File sourceParent = sourceFile.getParentFile(); - if(sourceParent == null) throw new FileNotFoundException("Cannot rename root"); - File targetFile = new File(getDocIdForFile(sourceParent) + "/" + displayName); - if(!sourceFile.renameTo(targetFile)){ - throw new FileNotFoundException("Couldn't rename the document with id" + documentId); - } - return getDocIdForFile(targetFile); - } - - @Override - public String moveDocument(String sourceDocumentId, String sourceParentDocumentId, String targetParentDocumentId) throws FileNotFoundException { - File sourceFile = getFileForDocId(sourceParentDocumentId + sourceDocumentId); - File targetFile = new File(targetParentDocumentId + sourceDocumentId); - if(!sourceFile.renameTo(targetFile)){ - throw new FileNotFoundException("Failed to move the document with id " + sourceFile.getPath()); - } - return getDocIdForFile(targetFile); - } - - @Override - public void removeDocument(String documentId, String parentDocumentId) throws FileNotFoundException { - deleteDocument(parentDocumentId + "/" + documentId); - } - - @Override - public void deleteDocument(String documentId) throws FileNotFoundException { - File file = getFileForDocId(documentId); - if(file.isDirectory()){ - try { - FileUtils.deleteDirectory(file); - } catch (IOException e) { - throw new FileNotFoundException("Failed to delete document with id " + documentId); - } - }else{ - if (!file.delete()) { - throw new FileNotFoundException("Failed to delete document with id " + documentId); - } - } - } - - @Override - public String getDocumentType(String documentId) throws FileNotFoundException { - Log.i("FolderPRovider", "getDocumentType("+documentId+")"); - File file = getFileForDocId(documentId); - return getMimeType(file); - } - - @Override - public Cursor querySearchDocuments(String rootId, String query, String[] projection) throws FileNotFoundException { - final MatrixCursor result = new MatrixCursor(projection != null ? projection : DEFAULT_DOCUMENT_PROJECTION); - final File parent = getFileForDocId(rootId); - - // This example implementation searches file names for the query and doesn't rank search - // results, so we can stop as soon as we find a sufficient number of matches. Other - // implementations might rank results and use other data about files, rather than the file - // name, to produce a match. - final LinkedList pending = new LinkedList<>(); - pending.add(parent); - - final int MAX_SEARCH_RESULTS = 50; - while (!pending.isEmpty() && result.getCount() < MAX_SEARCH_RESULTS) { - final File file = pending.removeFirst(); - // Avoid directories outside the $HOME directory linked with symlinks (to avoid e.g. search - // through the whole SD card). - boolean isInsideHome; - try { - isInsideHome = file.getCanonicalPath().startsWith(Tools.DIR_GAME_HOME); - } catch (IOException e) { - isInsideHome = true; - } - if (isInsideHome) { - if (file.isDirectory()) { - File[] listing = file.listFiles(); - if(listing != null) Collections.addAll(pending, listing); - } else { - if (file.getName().toLowerCase().contains(query)) { - includeFile(result, null, file); - } - } - } - } - - return result; - } - - @Override - public boolean isChildDocument(String parentDocumentId, String documentId) { - return documentId.startsWith(parentDocumentId); - } - - /** - * Get the document id given a file. This document id must be consistent across time as other - * applications may save the ID and use it to reference documents later. - *

- * The reverse of @{link #getFileForDocId}. - */ - private static String getDocIdForFile(File file) { - return file.getAbsolutePath(); - } - - /** - * Get the file given a document id (the reverse of {@link #getDocIdForFile(File)}). - */ - private static File getFileForDocId(String docId) throws FileNotFoundException { - final File f = new File(docId); - if (!f.exists()) throw new FileNotFoundException(f.getAbsolutePath() + " not found"); - return f; - } - - private static String getMimeType(File file) { - if (file.isDirectory()) { - return Document.MIME_TYPE_DIR; - } else { - final String name = file.getName(); - final int lastDot = name.lastIndexOf('.'); - if (lastDot >= 0) { - final String extension = name.substring(lastDot + 1).toLowerCase(); - final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); - if (mime != null) return mime; - } - return "application/octet-stream"; - } - } - - /** - * Add a representation of a file to a cursor. - * - * @param result the cursor to modify - * @param docId the document ID representing the desired file (may be null if given file) - * @param file the File object representing the desired file (may be null if given docID) - */ - private void includeFile(MatrixCursor result, String docId, File file) - throws FileNotFoundException { - if (docId == null) { - docId = getDocIdForFile(file); - } else { - file = getFileForDocId(docId); - } - - int flags = 0; - if (file.isDirectory()) { - if (file.canWrite()) flags |= Document.FLAG_DIR_SUPPORTS_CREATE; - } else if (file.canWrite()) { - flags |= Document.FLAG_SUPPORTS_WRITE; - } - File parent = file.getParentFile(); - if(parent != null) { // Only fails in one case: when the parent is /, which you can't delete. - if(parent.canWrite()) flags |= Document.FLAG_SUPPORTS_DELETE; - } - - final String displayName = file.getName(); - final String mimeType = getMimeType(file); - if (mimeType.startsWith("image/")) flags |= Document.FLAG_SUPPORTS_THUMBNAIL; - - final MatrixCursor.RowBuilder row = result.newRow(); - row.add(Document.COLUMN_DOCUMENT_ID, docId); - row.add(Document.COLUMN_DISPLAY_NAME, displayName); - row.add(Document.COLUMN_SIZE, file.length()); - row.add(Document.COLUMN_MIME_TYPE, mimeType); - row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified()); - row.add(Document.COLUMN_FLAGS, flags); - row.add(Document.COLUMN_ICON, R.mipmap.ic_launcher); - } - - @Override - @TargetApi(26) - public DocumentsContract.Path findDocumentPath(@Nullable String parentDocumentId, String childDocumentId) throws FileNotFoundException { - File source = BASE_DIR; - if(parentDocumentId != null) source = getFileForDocId(parentDocumentId); - File destination = getFileForDocId(childDocumentId); - List pathIds = new ArrayList<>(); - while(!source.equals(destination) && destination != null) { - pathIds.add(getDocIdForFile(destination)); - destination = destination.getParentFile(); - } - pathIds.add(getDocIdForFile(source)); - Collections.reverse(pathIds); - Log.i("FolderProvider", pathIds.toString()); - return new DocumentsContract.Path(getDocIdForFile(source), pathIds); - } -} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/services/GameService.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/services/GameService.java deleted file mode 100644 index 00babeca1..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/services/GameService.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.kdt.pojavlaunch.services; - -import android.app.PendingIntent; -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.Build; -import android.os.IBinder; -import android.os.Process; - -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.content.ContextCompat; - -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; - -import java.lang.ref.WeakReference; - -public class GameService extends Service { - private static final WeakReference sGameService = new WeakReference<>(null); - public static void startService(Context context) { - Intent intent = new Intent(context, GameService.class); - ContextCompat.startForegroundService(context, intent); - } - - @Override - public void onCreate() { - Tools.buildNotificationChannel(getApplicationContext()); - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if(intent != null && intent.getBooleanExtra("kill", false)) { - stopSelf(); - Process.killProcess(Process.myPid()); - return START_NOT_STICKY; - } - Intent killIntent = new Intent(getApplicationContext(), GameService.class); - killIntent.putExtra("kill", true); - PendingIntent pendingKillIntent = PendingIntent.getService(this, 0, killIntent, Build.VERSION.SDK_INT >=23 ? PendingIntent.FLAG_IMMUTABLE : 0); - NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "channel_id") - .setContentTitle(getString(R.string.lazy_service_default_title)) - .setContentText(getString(R.string.notification_game_runs)) - .addAction(android.R.drawable.ic_menu_close_clear_cancel, getString(R.string.notification_terminate), pendingKillIntent) - .setSmallIcon(R.drawable.notif_icon) - .setNotificationSilent(); - startForeground(2, notificationBuilder.build()); - return START_NOT_STICKY; // non-sticky so android wont try restarting the game after the user uses the "Quit" button - } - - @Override - public void onTaskRemoved(Intent rootIntent) { - //At this point in time only the game runs and the user poofed the window, time to die - stopSelf(); - Process.killProcess(Process.myPid()); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncMinecraftDownloader.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncMinecraftDownloader.java deleted file mode 100644 index 74112fefd..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncMinecraftDownloader.java +++ /dev/null @@ -1,435 +0,0 @@ -package net.kdt.pojavlaunch.tasks; - -import static net.kdt.pojavlaunch.PojavApplication.sExecutorService; -import static net.kdt.pojavlaunch.utils.DownloadUtils.downloadFileMonitored; - -import android.app.Activity; -import android.util.Log; - -import androidx.annotation.NonNull; - -import com.kdt.mcgui.ProgressLayout; - -import net.kdt.pojavlaunch.JAssetInfo; -import net.kdt.pojavlaunch.JAssets; -import net.kdt.pojavlaunch.JMinecraftVersionList; -import net.kdt.pojavlaunch.JRE17Util; -import net.kdt.pojavlaunch.R; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.extra.ExtraConstants; -import net.kdt.pojavlaunch.extra.ExtraCore; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; -import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper; -import net.kdt.pojavlaunch.utils.DownloadUtils; -import net.kdt.pojavlaunch.value.DependentLibrary; -import net.kdt.pojavlaunch.value.MinecraftClientInfo; -import net.kdt.pojavlaunch.value.MinecraftLibraryArtifact; - -import org.apache.commons.io.IOUtils; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; - -public class AsyncMinecraftDownloader { - private static final float BYTE_TO_MB = 1024 * 1024; - public static final String MINECRAFT_RES = "https://resources.download.minecraft.net/"; - - /* Allows each downloading thread to have its own RECYCLED buffer */ - private final ConcurrentHashMap mThreadBuffers = new ConcurrentHashMap<>(5); - - public AsyncMinecraftDownloader(Activity activity, JMinecraftVersionList.Version version, String realVersion, - @NonNull DoneListener listener){ // this was there for a reason - sExecutorService.execute(() -> { - try { - downloadGame(activity, version, realVersion); - listener.onDownloadDone(); - }catch (DownloaderException e) { - listener.onDownloadFailed(e.getCause()); - } - }); - } - /* we do the throws DownloaderException thing to avoid blanket-catching Exception as a form of anti-lazy-developer protection */ - private void downloadGame(Activity activity, JMinecraftVersionList.Version verInfo, String versionName) throws DownloaderException { - final String downVName = "/" + versionName + "/" + versionName; - - //Downloading libraries - String minecraftMainJar = Tools.DIR_HOME_VERSION + downVName + ".jar"; - JAssets assets = null; - try { - File verJsonDir = new File(Tools.DIR_HOME_VERSION + downVName + ".json"); - if (verInfo != null && verInfo.url != null) { - downloadVersionJson(versionName, verJsonDir, verInfo); - } - JMinecraftVersionList.Version originalVersion = Tools.getVersionInfo(versionName, true); - if(Tools.isValidString(originalVersion.inheritsFrom)) { - Log.i("Downloader", "probe: inheritsFrom="+originalVersion.inheritsFrom); - String version = originalVersion.inheritsFrom; - String downName = Tools.DIR_HOME_VERSION+"/"+version+"/"+version+".json"; - JMinecraftVersionList.Version listedVersion = getListedVersion(originalVersion.inheritsFrom); - if(listedVersion != null) { - Log.i("Downloader", "probe: verifying "+version); - downloadVersionJson(version, new File(downName), listedVersion); - }else{ - Log.i("Downloader", "failed to test source version before downloading."); - Log.i("Downloader", "Inheriting from versions not in the Mojang list?"); - Log.i("Downloader", "If so, feel free to open a PR at our GitHub repository to add this feature!"); - } - } - - verInfo = Tools.getVersionInfo(versionName); - - // THIS one function need the activity in the case of an error - if(activity != null && !JRE17Util.installNewJreIfNeeded(activity, verInfo)){ - ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1); - throw new DownloaderException(); - } - - try { - if(verInfo.assets != null) - assets = downloadIndex(verInfo, new File(Tools.ASSETS_PATH, "indexes/" + verInfo.assets + ".json")); - } catch (IOException e) { - Log.e("AsyncMcDownloader", e.toString(), e); - throw new DownloaderException(e); - } - - File outLib; - - // Patch the Log4J RCE (CVE-2021-44228) - if (verInfo.logging != null) { - outLib = new File(Tools.DIR_DATA + "/security", verInfo.logging.client.file.id.replace("client", "log4j-rce-patch")); - boolean useLocal = outLib.exists(); - if (!useLocal) { - outLib = new File(Tools.DIR_GAME_NEW, verInfo.logging.client.file.id); - } - if (outLib.exists() && !useLocal) { - if(LauncherPreferences.PREF_CHECK_LIBRARY_SHA) { - if(!Tools.compareSHA1(outLib,verInfo.logging.client.file.sha1)) { - outLib.delete(); - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_fail,verInfo.logging.client.file.id); - }else{ - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_pass,verInfo.logging.client.file.id); - } - } else if (outLib.length() != verInfo.logging.client.file.size) { - // force updating anyways - outLib.delete(); - } - } - if (!outLib.exists()) { - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.mcl_launch_downloading, verInfo.logging.client.file.id); - JMinecraftVersionList.Version finalVerInfo = verInfo; - downloadFileMonitored( - verInfo.logging.client.file.url, outLib, getByteBuffer(), - (curr, max) -> ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, - (int) Math.max((float)curr/max*100,0), R.string.mcl_launch_downloading_progress, finalVerInfo.logging.client.file.id, curr/BYTE_TO_MB, max/BYTE_TO_MB) - ); - } - } - - - for (final DependentLibrary libItem : verInfo.libraries) { - if(libItem.name.startsWith("org.lwjgl")){ //Black list - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, "Ignored " + libItem.name); - continue; - } - - String libArtifact = Tools.artifactToPath(libItem); - outLib = new File(Tools.DIR_HOME_LIBRARY + "/" + libArtifact); - outLib.getParentFile().mkdirs(); - - if (!outLib.exists()) { - downloadLibrary(libItem,libArtifact,outLib); - }else{ - if(libItem.downloads != null && libItem.downloads.artifact != null && libItem.downloads.artifact.sha1 != null && !libItem.downloads.artifact.sha1.isEmpty()) { - if(!Tools.compareSHA1(outLib,libItem.downloads.artifact.sha1)) { - outLib.delete(); - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_fail,libItem.name); - downloadLibrary(libItem,libArtifact,outLib); - }else{ - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_pass,libItem.name); - } - }else{ - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_unknown,libItem.name); - } - } - } - File minecraftMainFile = new File(minecraftMainJar); - Log.i("Downloader", "originalVersion.inheritsFrom="+originalVersion.inheritsFrom); - Log.i("Downloader", "originalVersion.downloads="+originalVersion.downloads); - MinecraftClientInfo originalClientInfo; - if(originalVersion.inheritsFrom == null) { - if (originalVersion.downloads != null && (originalClientInfo = originalVersion.downloads.get("client")) != null) { - verifyAndDownloadMainJar(originalClientInfo.url, originalClientInfo.sha1, minecraftMainFile); - } - }else if(!minecraftMainFile.exists() || minecraftMainFile.length() == 0) { - File minecraftSourceFile = new File(Tools.DIR_HOME_VERSION + "/" + verInfo.id + "/" + verInfo.id + ".jar"); - MinecraftClientInfo inheritedClientInfo; - if(verInfo.downloads != null && (inheritedClientInfo = verInfo.downloads.get("client")) != null) { - verifyAndDownloadMainJar(inheritedClientInfo.url, inheritedClientInfo.sha1, minecraftSourceFile); - } - if(minecraftSourceFile.exists()) { - FileInputStream is = new FileInputStream(minecraftSourceFile); - FileOutputStream os = new FileOutputStream(minecraftMainFile); - IOUtils.copy(is, os); - is.close(); - os.close(); - } - } - } catch (DownloaderException e) { - throw e; - } catch (Throwable e) { - Log.e("AsyncMcDownloader", e.toString(),e ); - ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1); - throw new DownloaderException(e); - } - - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.mcl_launch_cleancache); - new File(Tools.DIR_HOME_VERSION).mkdir(); - for (File f : new File(Tools.DIR_HOME_VERSION).listFiles()) { - if(f.getName().endsWith(".part")) { - Log.d(Tools.APP_NAME, "Cleaning cache: " + f); - f.delete(); - } - } - - - try { - if(assets != null) - downloadAssets(assets, verInfo.assets, assets.mapToResources ? new File(Tools.OBSOLETE_RESOURCES_PATH) : new File(Tools.ASSETS_PATH)); - } catch (Exception e) { - Log.e("AsyncMcDownloader", e.toString(), e); - ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1); - throw new DownloaderException(e); - } - ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1); - } - - public void verifyAndDownloadMainJar(String url, String sha1, File destination) throws Exception{ - while(!destination.exists() || (destination.exists() && !Tools.compareSHA1(destination, sha1))) downloadFileMonitored( - url, - destination, getByteBuffer(), - (curr, max) -> ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, - (int) Math.max((float)curr/max*100,0), R.string.mcl_launch_downloading_progress, destination.getName(), curr/BYTE_TO_MB, max/BYTE_TO_MB)); - } - - public void downloadAssets(final JAssets assets, String assetsVersion, final File outputDir) { - LinkedBlockingQueue workQueue = new LinkedBlockingQueue<>(); - final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 500, TimeUnit.MILLISECONDS, workQueue); - - - Log.i("AsyncMcDownloader","Assets begin time: " + System.currentTimeMillis()); - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.mcl_launch_download_assets); - - Map assetsObjects = assets.objects; - int assetsSizeBytes = 0; - AtomicInteger downloadedSize = new AtomicInteger(0); - AtomicBoolean localInterrupt = new AtomicBoolean(false); - - File objectsDir = new File(outputDir, "objects"); - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.mcl_launch_downloading, "assets"); - - for(String assetKey : assetsObjects.keySet()) { - JAssetInfo asset = assetsObjects.get(assetKey); - assetsSizeBytes += asset.size; - String assetPath = asset.hash.substring(0, 2) + "/" + asset.hash; - File outFile = assets.mapToResources ? new File(outputDir,"/"+assetKey) : new File(objectsDir, assetPath); - boolean skip = outFile.exists();// skip if the file exists - - if(LauncherPreferences.PREF_CHECK_LIBRARY_SHA && skip) - skip = Tools.compareSHA1(outFile, asset.hash); - - if(skip) { - downloadedSize.addAndGet(asset.size); - continue; - } - - if(outFile.exists()) - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.dl_library_sha_fail, assetKey); - - executor.execute(()->{ - try { - if (!assets.mapToResources) downloadAsset(asset, objectsDir, downloadedSize); - else downloadAssetMapped(asset, assetKey, outputDir, downloadedSize); - }catch (IOException e) { - Log.e("AsyncMcManager", e.toString()); - localInterrupt.set(true); - } - }); - } - executor.shutdown(); - - try { - Log.i("AsyncMcDownloader","Queue size: " + workQueue.size()); - while ((!executor.awaitTermination(1000, TimeUnit.MILLISECONDS))&&(!localInterrupt.get()) /*&&mActivity.mIsAssetsProcessing*/) { - int DLSize = downloadedSize.get(); - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT,(int) Math.max((float) DLSize/assetsSizeBytes*100, 0), - R.string.mcl_launch_downloading_progress, "assets", (float)DLSize/BYTE_TO_MB, (float)assetsSizeBytes/BYTE_TO_MB); - } - - - executor.shutdownNow(); - while (!executor.awaitTermination(250, TimeUnit.MILLISECONDS)) {} - Log.i("AsyncMcDownloader","Fully shut down!"); - }catch(InterruptedException e) { - Log.e("AsyncMcDownloader", e.toString()); - } - Log.i("AsyncMcDownloader", "Assets end time: " + System.currentTimeMillis()); - } - - - public void downloadAsset(JAssetInfo asset, File objectsDir, AtomicInteger downloadCounter) throws IOException { - String assetPath = asset.hash.substring(0, 2) + "/" + asset.hash; - File outFile = new File(objectsDir, assetPath); - downloadFileMonitored(MINECRAFT_RES + assetPath, outFile, getByteBuffer(), - new Tools.DownloaderFeedback() { - int prevCurr; - @Override - public void updateProgress(int curr, int max) { - downloadCounter.addAndGet(curr - prevCurr); - prevCurr = curr; - } - }); - } - - public void downloadAssetMapped(JAssetInfo asset, String assetName, File resDir, AtomicInteger downloadCounter) throws IOException { - String assetPath = asset.hash.substring(0, 2) + "/" + asset.hash; - File outFile = new File(resDir,"/"+assetName); - downloadFileMonitored(MINECRAFT_RES + assetPath, outFile, getByteBuffer(), - new Tools.DownloaderFeedback() { - int prevCurr; - @Override - public void updateProgress(int curr, int max) { - downloadCounter.addAndGet(curr - prevCurr); - prevCurr = curr; - } - }); - } - - protected void downloadLibrary(DependentLibrary libItem, String libArtifact, File outLib) throws Throwable{ - String libPathURL; - boolean skipIfFailed = false; - - if (libItem.downloads == null || libItem.downloads.artifact == null) { - MinecraftLibraryArtifact artifact = new MinecraftLibraryArtifact(); - artifact.url = (libItem.url == null - ? "https://libraries.minecraft.net/" - : libItem.url.replace("http://","https://")) + libArtifact; - libItem.downloads = new DependentLibrary.LibraryDownloads(artifact); - - skipIfFailed = true; - } - - try { - libPathURL = libItem.downloads.artifact.url; - boolean isFileGood = false; - byte timesChecked=0; - while(!isFileGood) { - timesChecked++; - if(timesChecked > 5) throw new RuntimeException("Library download failed after 5 retries"); - - downloadFileMonitored(libPathURL, outLib, getByteBuffer(), - (curr, max) -> ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, - (int) Math.max((float)curr/max*100,0), R.string.mcl_launch_downloading_progress, outLib.getName(), curr/BYTE_TO_MB, max/BYTE_TO_MB) - ); - - isFileGood = (libItem.downloads.artifact.sha1 == null - || LauncherPreferences.PREF_CHECK_LIBRARY_SHA) - || Tools.compareSHA1(outLib,libItem.downloads.artifact.sha1); - - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, - isFileGood ? R.string.dl_library_sha_pass : R.string.dl_library_sha_unknown - ,outLib.getName()); - } - } catch (Throwable th) { - Log.e("AsyncMcDownloader", th.toString(), th); - if (!skipIfFailed) { - throw th; - } else { - th.printStackTrace(); - } - } - } - - public JAssets downloadIndex(JMinecraftVersionList.Version version, File output) throws IOException { - if (!output.exists()) { - output.getParentFile().mkdirs(); - DownloadUtils.downloadFile(version.assetIndex != null - ? version.assetIndex.url - : "https://s3.amazonaws.com/Minecraft.Download/indexes/" + version.assets + ".json", output); - } - - return Tools.GLOBAL_GSON.fromJson(Tools.read(output.getAbsolutePath()), JAssets.class); - } - - public void downloadVersionJson(String versionName, File verJsonDir, JMinecraftVersionList.Version verInfo) throws IOException { - if(!LauncherPreferences.PREF_CHECK_LIBRARY_SHA) Log.w("Chk","Checker is off"); - - boolean isManifestGood = verJsonDir.exists() - && (!LauncherPreferences.PREF_CHECK_LIBRARY_SHA - || verInfo.sha1 == null - || Tools.compareSHA1(verJsonDir, verInfo.sha1)); - - if(!isManifestGood) { - ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, 0, R.string.mcl_launch_downloading, versionName + ".json"); - verJsonDir.delete(); - downloadFileMonitored(verInfo.url, verJsonDir, getByteBuffer(), - (curr, max) -> ProgressLayout.setProgress(ProgressLayout.DOWNLOAD_MINECRAFT, - (int) Math.max((float)curr/max*100,0), R.string.mcl_launch_downloading_progress, versionName + ".json", curr/BYTE_TO_MB, max/BYTE_TO_MB) - ); - } - } - - public static String normalizeVersionId(String versionString) { - JMinecraftVersionList versionList = (JMinecraftVersionList) ExtraCore.getValue(ExtraConstants.RELEASE_TABLE); - if(versionList == null || versionList.versions == null) return versionString; - if("latest-release".equals(versionString)) versionString = versionList.latest.get("release"); - if("latest-snapshot".equals(versionString)) versionString = versionList.latest.get("snapshot"); - return versionString; - } - - public static JMinecraftVersionList.Version getListedVersion(String normalizedVersionString) { - JMinecraftVersionList versionList = (JMinecraftVersionList) ExtraCore.getValue(ExtraConstants.RELEASE_TABLE); - if(versionList == null || versionList.versions == null) return null; // can't have listed versions if there's no list - for(JMinecraftVersionList.Version version : versionList.versions) { - if(version.id.equals(normalizedVersionString)) return version; - } - return null; - } - - - /**@return A byte buffer bound to a thread, useful to recycle it across downloads */ - private byte[] getByteBuffer(){ - byte[] buffer = mThreadBuffers.get(Thread.currentThread()); - if (buffer == null){ - buffer = new byte[8192]; - mThreadBuffers.put(Thread.currentThread(), buffer); - } - - return buffer; - } - - - - - - public interface DoneListener{ - void onDownloadDone(); - void onDownloadFailed(Throwable throwable); - } - - private static class DownloaderException extends Exception { - public DownloaderException() {} - public DownloaderException(Throwable e) { - super(e); - } - } - -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncVersionList.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncVersionList.java deleted file mode 100644 index 0a18ac0fb..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/tasks/AsyncVersionList.java +++ /dev/null @@ -1,88 +0,0 @@ -package net.kdt.pojavlaunch.tasks; - -import static net.kdt.pojavlaunch.PojavApplication.sExecutorService; -import static net.kdt.pojavlaunch.utils.DownloadUtils.downloadString; - -import android.util.Log; - -import androidx.annotation.Nullable; - -import com.google.gson.JsonIOException; -import com.google.gson.JsonSyntaxException; -import com.google.gson.stream.JsonReader; - -import net.kdt.pojavlaunch.JMinecraftVersionList; -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; - -/** Class getting the version list, and that's all really */ -public class AsyncVersionList { - - public void getVersionList(@Nullable VersionDoneListener listener, boolean secondPass){ - sExecutorService.execute(() -> { - File versionFile = new File(Tools.DIR_DATA + "/version_list.json"); - JMinecraftVersionList versionList = null; - try{ - if(!versionFile.exists() || (System.currentTimeMillis() > versionFile.lastModified() + 86400000 )){ - versionList = downloadVersionList(LauncherPreferences.PREF_VERSION_REPOS); - } - }catch (Exception e){ - Log.e("AsyncVersionList", "Refreshing version list failed :" + e); - e.printStackTrace(); - } - - // Fallback when no network or not needed - if (versionList == null) { - try { - versionList = Tools.GLOBAL_GSON.fromJson(new JsonReader(new FileReader(versionFile)), JMinecraftVersionList.class); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (JsonIOException | JsonSyntaxException e) { - e.printStackTrace(); - versionFile.delete(); - if(!secondPass) - getVersionList(listener, true); - } - } - - if(listener != null) - listener.onVersionDone(versionList); - }); - } - - - @SuppressWarnings("SameParameterValue") - private JMinecraftVersionList downloadVersionList(String mirror){ - JMinecraftVersionList list = null; - try{ - Log.i("ExtVL", "Syncing to external: " + mirror); - String jsonString = downloadString(mirror); - list = Tools.GLOBAL_GSON.fromJson(jsonString, JMinecraftVersionList.class); - Log.i("ExtVL","Downloaded the version list, len=" + list.versions.length); - - // Then save the version list - //TODO make it not save at times ? - FileOutputStream fos = new FileOutputStream(Tools.DIR_DATA + "/version_list.json"); - fos.write(jsonString.getBytes()); - fos.close(); - - - - }catch (IOException e){ - Log.e("AsyncVersionList", e.toString()); - } - return list; - } - - /** Basic listener, acting as a callback */ - public interface VersionDoneListener{ - void onVersionDone(JMinecraftVersionList versions); - } - -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java index 27455879e..e7a926463 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/utils/JREUtils.java @@ -24,7 +24,6 @@ import net.kdt.pojavlaunch.extra.ExtraConstants; import net.kdt.pojavlaunch.extra.ExtraCore; import net.kdt.pojavlaunch.multirt.MultiRTUtils; import net.kdt.pojavlaunch.multirt.Runtime; -import net.kdt.pojavlaunch.plugins.FFmpegPlugin; import net.kdt.pojavlaunch.prefs.*; import org.lwjgl.glfw.*; @@ -145,9 +144,6 @@ public class JREUtils { String libName = is64BitsDevice() ? "lib64" : "lib"; StringBuilder ldLibraryPath = new StringBuilder(); - if(FFmpegPlugin.isAvailable) { - ldLibraryPath.append(FFmpegPlugin.libraryPath).append(":"); - } ldLibraryPath.append(jreHome) .append("/").append(Tools.DIRNAME_HOME_JRE) .append("/jli:").append(jreHome).append("/").append(Tools.DIRNAME_HOME_JRE) @@ -195,9 +191,6 @@ public class JREUtils { envMap.put("LD_LIBRARY_PATH", LD_LIBRARY_PATH); envMap.put("PATH", jreHome + "/bin:" + Os.getenv("PATH")); - if(FFmpegPlugin.isAvailable) { - envMap.put("PATH", FFmpegPlugin.libraryPath+":"+envMap.get("PATH")); - } envMap.put("REGAL_GL_VENDOR", "Android"); envMap.put("REGAL_GL_RENDERER", "Regal"); diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java deleted file mode 100644 index b014bc16e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/DependentLibrary.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.kdt.pojavlaunch.value; - -import androidx.annotation.Keep; -import net.kdt.pojavlaunch.JMinecraftVersionList.Arguments.ArgValue.ArgRules; - -@Keep -public class DependentLibrary { - public ArgRules[] rules; - public String name; - public LibraryDownloads downloads; - public String url; - - @Keep - public static class LibraryDownloads { - public final MinecraftLibraryArtifact artifact; - public LibraryDownloads(MinecraftLibraryArtifact artifact) { - this.artifact = artifact; - } - } -} - diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java deleted file mode 100644 index ae133e44f..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftAccount.java +++ /dev/null @@ -1,109 +0,0 @@ -package net.kdt.pojavlaunch.value; - - -import android.graphics.BitmapFactory; -import android.util.Log; - -import net.kdt.pojavlaunch.*; -import java.io.*; -import com.google.gson.*; -import android.graphics.Bitmap; -import android.util.Base64; - -import androidx.annotation.Keep; - -import org.apache.commons.io.IOUtils; - -@SuppressWarnings("IOStreamConstructor") -@Keep -public class MinecraftAccount { - public String accessToken = "0"; // access token - public String clientToken = "0"; // clientID: refresh and invalidate - public String profileId = "00000000-0000-0000-0000-000000000000"; // profile UUID, for obtaining skin - public String username = "Steve"; - public String selectedVersion = "1.7.10"; - public boolean isMicrosoft = false; - public String msaRefreshToken = "0"; - public String xuid; - public String skinFaceBase64; - public long expiresAt; - - void updateSkinFace(String uuid) { - try { - File skinFile = File.createTempFile("skin", ".png", new File(Tools.DIR_DATA, "cache")); - Tools.downloadFile("https://mc-heads.net/head/" + uuid + "/100", skinFile.getAbsolutePath()); - skinFaceBase64 = Base64.encodeToString(IOUtils.toByteArray(new FileInputStream(skinFile)), Base64.DEFAULT); - - Log.i("SkinLoader", "Update skin face success"); - } catch (IOException e) { - // Skin refresh limit, no internet connection, etc... - // Simply ignore updating skin face - Log.w("SkinLoader", "Could not update skin face", e); - } - } - - public boolean isLocal(){ - return accessToken.equals("0"); - } - - public void updateSkinFace() { - updateSkinFace(profileId); - } - - public String save(String outPath) throws IOException { - Tools.write(outPath, Tools.GLOBAL_GSON.toJson(this)); - return username; - } - - public String save() throws IOException { - return save(Tools.DIR_ACCOUNT_NEW + "/" + username + ".json"); - } - - public static MinecraftAccount parse(String content) throws JsonSyntaxException { - return Tools.GLOBAL_GSON.fromJson(content, MinecraftAccount.class); - } - - public static MinecraftAccount load(String name) { - if(!accountExists(name)) return null; - try { - MinecraftAccount acc = parse(Tools.read(Tools.DIR_ACCOUNT_NEW + "/" + name + ".json")); - if (acc.accessToken == null) { - acc.accessToken = "0"; - } - if (acc.clientToken == null) { - acc.clientToken = "0"; - } - if (acc.profileId == null) { - acc.profileId = "00000000-0000-0000-0000-000000000000"; - } - if (acc.username == null) { - acc.username = "0"; - } - if (acc.selectedVersion == null) { - acc.selectedVersion = "1.7.10"; - } - if (acc.msaRefreshToken == null) { - acc.msaRefreshToken = "0"; - } - if (acc.skinFaceBase64 == null) { - // acc.updateSkinFace("MHF_Steve"); - } - return acc; - } catch(IOException | JsonSyntaxException e) { - Log.e(MinecraftAccount.class.getName(), "Caught an exception while loading the profile",e); - return null; - } - } - - public Bitmap getSkinFace(){ - if(skinFaceBase64 == null){ - return null; - } - byte[] faceIconBytes = Base64.decode(skinFaceBase64, Base64.DEFAULT); - return BitmapFactory.decodeByteArray(faceIconBytes, 0, faceIconBytes.length); - } - - private static boolean accountExists(String username){ - return new File(Tools.DIR_ACCOUNT_NEW + "/" + username + ".json").exists(); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftClientInfo.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftClientInfo.java deleted file mode 100644 index 653d289ff..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftClientInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package net.kdt.pojavlaunch.value; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftClientInfo { - public String sha1; - public int size; - public String url; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftLibraryArtifact.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftLibraryArtifact.java deleted file mode 100644 index ca81364af..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/MinecraftLibraryArtifact.java +++ /dev/null @@ -1,8 +0,0 @@ -package net.kdt.pojavlaunch.value; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftLibraryArtifact extends MinecraftClientInfo { - public String path; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java deleted file mode 100644 index 7d7f826d2..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/LauncherProfiles.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import android.util.Log; - -import androidx.annotation.NonNull; - -import net.kdt.pojavlaunch.Tools; -import net.kdt.pojavlaunch.prefs.LauncherPreferences; - -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.UUID; - -public class LauncherProfiles { - public static MinecraftLauncherProfiles mainProfileJson; - public static final File launcherProfilesFile = new File(Tools.DIR_GAME_NEW, "launcher_profiles.json"); - public static MinecraftLauncherProfiles update() { - try { - if (mainProfileJson == null) { - if (launcherProfilesFile.exists()) { - mainProfileJson = Tools.GLOBAL_GSON.fromJson(Tools.read(launcherProfilesFile.getAbsolutePath()), MinecraftLauncherProfiles.class); - if(mainProfileJson.profiles == null) mainProfileJson.profiles = new HashMap<>(); - else if(LauncherProfiles.normalizeProfileIds(mainProfileJson)){ - LauncherProfiles.update(); - } - } else { - mainProfileJson = new MinecraftLauncherProfiles(); - mainProfileJson.profiles = new HashMap<>(); - } - } else { - Tools.write(launcherProfilesFile.getAbsolutePath(), mainProfileJson.toJson()); - } - - // insertMissing(); - return mainProfileJson; - } catch (Throwable th) { - throw new RuntimeException(th); - } - } - - public static @NonNull MinecraftProfile getCurrentProfile() { - if(mainProfileJson == null) LauncherProfiles.update(); - String defaultProfileName = LauncherPreferences.DEFAULT_PREF.getString(LauncherPreferences.PREF_KEY_CURRENT_PROFILE, ""); - MinecraftProfile profile = mainProfileJson.profiles.get(defaultProfileName); - if(profile == null) throw new RuntimeException("The current profile stopped existing :("); - return profile; - } - - /** - * For all keys to be UUIDs, effectively isolating profile created by installers - * This avoids certain profiles to be erased by the installer - * @return Whether some profiles have been normalized - */ - private static boolean normalizeProfileIds(MinecraftLauncherProfiles launcherProfiles){ - boolean hasNormalized = false; - ArrayList keys = new ArrayList<>(); - - // Detect denormalized keys - for(String profileKey : launcherProfiles.profiles.keySet()){ - try{ - if(!UUID.fromString(profileKey).toString().equals(profileKey)) keys.add(profileKey); - }catch (IllegalArgumentException exception){ - keys.add(profileKey); - Log.w(LauncherProfiles.class.toString(), "Illegal profile uuid: " + profileKey); - } - } - - // Swap the new keys - for(String profileKey: keys){ - String uuid = UUID.randomUUID().toString(); - while(launcherProfiles.profiles.containsKey(uuid)) { - uuid = UUID.randomUUID().toString(); - } - - launcherProfiles.profiles.put(uuid, launcherProfiles.profiles.get(profileKey)); - launcherProfiles.profiles.remove(profileKey); - hasNormalized = true; - } - - return hasNormalized; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftAuthenticationDatabase.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftAuthenticationDatabase.java deleted file mode 100644 index d1c70619e..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftAuthenticationDatabase.java +++ /dev/null @@ -1,12 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftAuthenticationDatabase { - public String accessToken; - public String displayName; - public String username; - public String uuid; - // public MinecraftProfile[] profiles; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherProfiles.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherProfiles.java deleted file mode 100644 index c9b8fcea8..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherProfiles.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; -import androidx.annotation.Keep; - -import java.util.*; -import net.kdt.pojavlaunch.*; - -@Keep -public class MinecraftLauncherProfiles { - public Map profiles = new HashMap<>(); - public boolean profilesWereMigrated; - public String clientToken; - public Map authenticationDatabase; - // public Map launcherVersion; - public MinecraftLauncherSettings settings; - // public Map analyticsToken; - public int analyticsFailcount; - public MinecraftSelectedUser selectedUser; - - public String toJson() { - return Tools.GLOBAL_GSON.toJson(this); - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherSettings.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherSettings.java deleted file mode 100644 index 14330b3e6..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftLauncherSettings.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftLauncherSettings { - public boolean enableSnapshots; - public boolean enableAdvanced; - public boolean keepLauncherOpen; - public boolean showGameLog; - public String locale; - public boolean showMenu; - public boolean enableHistorical; - public String profileSorting; - public boolean crashAssistance; - public boolean enableAnalytics; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftProfile.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftProfile.java deleted file mode 100644 index 18b4d82d4..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftProfile.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftProfile { - - public String name; - public String type; - public String created; - public String lastUsed; - public String icon; - public String lastVersionId; - public String gameDir; - public String javaDir; - public String javaArgs; - public String logConfig; - public boolean logConfigIsXML; - public String pojavRendererName; - public String controlFile; - public MinecraftResolution[] resolution; - - - public static MinecraftProfile createTemplate(){ - MinecraftProfile TEMPLATE = new MinecraftProfile(); - TEMPLATE.name = "New"; - TEMPLATE.lastVersionId = "latest-release"; - return TEMPLATE; - } - - public MinecraftProfile(){} - - public MinecraftProfile(MinecraftProfile profile){ - name = profile.name; - type = profile.type; - created = profile.created; - lastUsed = profile.lastUsed; - icon = profile.icon; - lastVersionId = profile.lastVersionId; - gameDir = profile.gameDir; - javaDir = profile.javaDir; - javaArgs = profile.javaArgs; - logConfig = profile.logConfig; - logConfigIsXML = profile.logConfigIsXML; - pojavRendererName = profile.pojavRendererName; - controlFile = profile.controlFile; - resolution = profile.resolution; - } -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftResolution.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftResolution.java deleted file mode 100644 index 33bed42b0..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftResolution.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftResolution { - public int width; - public int height; -} diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftSelectedUser.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftSelectedUser.java deleted file mode 100644 index cc92c978f..000000000 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/value/launcherprofiles/MinecraftSelectedUser.java +++ /dev/null @@ -1,9 +0,0 @@ -package net.kdt.pojavlaunch.value.launcherprofiles; - -import androidx.annotation.Keep; - -@Keep -public class MinecraftSelectedUser { - public String account; - public String profile; -} diff --git a/app_pojavlauncher/src/main/res/layout-land/activity_pojav_launcher.xml b/app_pojavlauncher/src/main/res/layout-land/activity_pojav_launcher.xml deleted file mode 100644 index f16b15206..000000000 --- a/app_pojavlauncher/src/main/res/layout-land/activity_pojav_launcher.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml b/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml deleted file mode 100644 index ec97c0358..000000000 --- a/app_pojavlauncher/src/main/res/layout-land/fragment_launcher.xml +++ /dev/null @@ -1,115 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app_pojavlauncher/src/main/res/layout/activity_import_control.xml b/app_pojavlauncher/src/main/res/layout/activity_import_control.xml deleted file mode 100644 index a6d93ff84..000000000 --- a/app_pojavlauncher/src/main/res/layout/activity_import_control.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml b/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml deleted file mode 100644 index 78a6963e0..000000000 --- a/app_pojavlauncher/src/main/res/layout/activity_pojav_launcher.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml b/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml deleted file mode 100644 index cf75586d0..000000000 --- a/app_pojavlauncher/src/main/res/layout/fragment_fabric_install.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - -