mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-14 07:05:40 -04:00
Feat[modloader]: quilt support
This commit is contained in:
parent
67213c09b8
commit
da3079d30c
@ -1,282 +1,24 @@
|
||||
package net.kdt.pojavlaunch.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import net.kdt.pojavlaunch.PojavApplication;
|
||||
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.FabricVersion;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy;
|
||||
import net.kdt.pojavlaunch.modloaders.modpacks.SelfReferencingFuture;
|
||||
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
public class FabricInstallFragment extends FabriclikeInstallFragment {
|
||||
|
||||
public class FabricInstallFragment extends Fragment implements ModloaderDownloadListener, CompoundButton.OnCheckedChangeListener {
|
||||
public static final String TAG = "FabricInstallTarget";
|
||||
public static final String TAG = "FabricInstallFragment";
|
||||
private static ModloaderListenerProxy sTaskProxy;
|
||||
private Spinner mGameVersionSpinner;
|
||||
private FabricVersion[] mGameVersionArray;
|
||||
private Future<?> mGameVersionFuture;
|
||||
private String mSelectedGameVersion;
|
||||
private Spinner mLoaderVersionSpinner;
|
||||
private FabricVersion[] mLoaderVersionArray;
|
||||
private Future<?> mLoaderVersionFuture;
|
||||
private String mSelectedLoaderVersion;
|
||||
private ProgressBar mProgressBar;
|
||||
private Button mStartButton;
|
||||
private View mRetryView;
|
||||
private CheckBox mOnlyStableCheckbox;
|
||||
|
||||
public FabricInstallFragment() {
|
||||
super(R.layout.fragment_fabric_install);
|
||||
super(FabriclikeUtils.FABRIC_UTILS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
protected ModloaderListenerProxy getListenerProxy() {
|
||||
return sTaskProxy;
|
||||
}
|
||||
|
||||
@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);
|
||||
mGameVersionSpinner = view.findViewById(R.id.fabric_installer_game_ver_spinner);
|
||||
mGameVersionSpinner.setOnItemSelectedListener(new GameVersionSelectedListener());
|
||||
mLoaderVersionSpinner = view.findViewById(R.id.fabric_installer_loader_ver_spinner);
|
||||
mLoaderVersionSpinner.setOnItemSelectedListener(new LoaderVersionSelectedListener());
|
||||
mProgressBar = view.findViewById(R.id.fabric_installer_progress_bar);
|
||||
mRetryView = view.findViewById(R.id.fabric_installer_retry_layout);
|
||||
mOnlyStableCheckbox = view.findViewById(R.id.fabric_installer_only_stable_checkbox);
|
||||
mOnlyStableCheckbox.setOnCheckedChangeListener(this);
|
||||
view.findViewById(R.id.fabric_installer_retry_button).setOnClickListener(this::onClickRetry);
|
||||
if(sTaskProxy != null) {
|
||||
mStartButton.setEnabled(false);
|
||||
sTaskProxy.attachListener(this);
|
||||
}
|
||||
updateGameVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
cancelFutureChecked(mGameVersionFuture);
|
||||
cancelFutureChecked(mLoaderVersionFuture);
|
||||
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, mSelectedGameVersion, mSelectedLoaderVersion, true);
|
||||
sTaskProxy.attachListener(this);
|
||||
mStartButton.setEnabled(false);
|
||||
new Thread(fabricDownloadTask).start();
|
||||
}
|
||||
|
||||
private void onClickRetry(View v) {
|
||||
mStartButton.setEnabled(false);
|
||||
mRetryView.setVisibility(View.GONE);
|
||||
mLoaderVersionSpinner.setAdapter(null);
|
||||
if(mGameVersionArray == null) {
|
||||
mGameVersionSpinner.setAdapter(null);
|
||||
updateGameVersions();
|
||||
return;
|
||||
}
|
||||
updateLoaderVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFinished(File downloadedFile) {
|
||||
Tools.runOnUiThread(()->{
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
|
||||
@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);
|
||||
});
|
||||
}
|
||||
|
||||
private void cancelFutureChecked(Future<?> future) {
|
||||
if(future != null && !future.isCancelled()) future.cancel(true);
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
mStartButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void stopLoading() {
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
// The "visibility on" is managed by the spinners
|
||||
}
|
||||
|
||||
private ArrayAdapter<FabricVersion> createAdapter(FabricVersion[] fabricVersions, boolean onlyStable) {
|
||||
ArrayList<FabricVersion> filteredVersions = new ArrayList<>(fabricVersions.length);
|
||||
for(FabricVersion fabricVersion : fabricVersions) {
|
||||
if(!onlyStable || fabricVersion.stable) filteredVersions.add(fabricVersion);
|
||||
}
|
||||
filteredVersions.trimToSize();
|
||||
return new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_dropdown_item, filteredVersions);
|
||||
}
|
||||
|
||||
private void onException(Future<?> myFuture, Exception e) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
Tools.showError(requireContext(), e);
|
||||
mRetryView.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
updateGameSpinner();
|
||||
updateLoaderSpinner();
|
||||
}
|
||||
|
||||
class LoaderVersionSelectedListener implements AdapterView.OnItemSelectedListener {
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
mSelectedLoaderVersion = ((FabricVersion) adapterView.getAdapter().getItem(i)).version;
|
||||
mStartButton.setEnabled(mSelectedGameVersion != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
mSelectedLoaderVersion = null;
|
||||
mStartButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
class LoadLoaderVersionsTask implements SelfReferencingFuture.FutureInterface {
|
||||
@Override
|
||||
public void run(Future<?> myFuture) {
|
||||
Log.i("LoadLoaderVersions", "Starting...");
|
||||
try {
|
||||
mLoaderVersionArray = FabricUtils.downloadLoaderVersions(mSelectedGameVersion);
|
||||
onFinished(myFuture);
|
||||
}catch (IOException e) {
|
||||
onException(myFuture, e);
|
||||
}
|
||||
}
|
||||
private void onFinished(Future<?> myFuture) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
updateLoaderSpinner();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoaderVersions() {
|
||||
startLoading();
|
||||
mLoaderVersionFuture = new SelfReferencingFuture(new LoadLoaderVersionsTask()).startOnExecutor(PojavApplication.sExecutorService);
|
||||
}
|
||||
|
||||
private void updateLoaderSpinner() {
|
||||
mLoaderVersionSpinner.setAdapter(createAdapter(mLoaderVersionArray, mOnlyStableCheckbox.isChecked()));
|
||||
}
|
||||
|
||||
class GameVersionSelectedListener implements AdapterView.OnItemSelectedListener {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
mSelectedGameVersion = ((FabricVersion) adapterView.getAdapter().getItem(i)).version;
|
||||
cancelFutureChecked(mLoaderVersionFuture);
|
||||
updateLoaderVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
mSelectedGameVersion = null;
|
||||
if(mLoaderVersionFuture != null) mLoaderVersionFuture.cancel(true);
|
||||
adapterView.setAdapter(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LoadGameVersionsTask implements SelfReferencingFuture.FutureInterface {
|
||||
@Override
|
||||
public void run(Future<?> myFuture) {
|
||||
try {
|
||||
mGameVersionArray = FabricUtils.downloadGameVersions();
|
||||
onFinished(myFuture);
|
||||
}catch (IOException e) {
|
||||
onException(myFuture, e);
|
||||
}
|
||||
}
|
||||
private void onFinished(Future<?> myFuture) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
updateGameSpinner();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateGameVersions() {
|
||||
startLoading();
|
||||
mGameVersionFuture = new SelfReferencingFuture(new LoadGameVersionsTask()).startOnExecutor(PojavApplication.sExecutorService);
|
||||
}
|
||||
|
||||
private void updateGameSpinner() {
|
||||
mGameVersionSpinner.setAdapter(createAdapter(mGameVersionArray, mOnlyStableCheckbox.isChecked()));
|
||||
protected void setListenerProxy(ModloaderListenerProxy listenerProxy) {
|
||||
sTaskProxy = listenerProxy;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,293 @@
|
||||
package net.kdt.pojavlaunch.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
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 net.kdt.pojavlaunch.PojavApplication;
|
||||
import net.kdt.pojavlaunch.R;
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeDownloadTask;
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.FabricVersion;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy;
|
||||
import net.kdt.pojavlaunch.modloaders.modpacks.SelfReferencingFuture;
|
||||
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public abstract class FabriclikeInstallFragment extends Fragment implements ModloaderDownloadListener, CompoundButton.OnCheckedChangeListener {
|
||||
private final FabriclikeUtils mFabriclikeUtils;
|
||||
private Spinner mGameVersionSpinner;
|
||||
private FabricVersion[] mGameVersionArray;
|
||||
private Future<?> mGameVersionFuture;
|
||||
private String mSelectedGameVersion;
|
||||
private Spinner mLoaderVersionSpinner;
|
||||
private FabricVersion[] mLoaderVersionArray;
|
||||
private Future<?> mLoaderVersionFuture;
|
||||
private String mSelectedLoaderVersion;
|
||||
private ProgressBar mProgressBar;
|
||||
private Button mStartButton;
|
||||
private View mRetryView;
|
||||
private CheckBox mOnlyStableCheckbox;
|
||||
protected FabriclikeInstallFragment(FabriclikeUtils mFabriclikeUtils) {
|
||||
super(R.layout.fragment_fabric_install);
|
||||
this.mFabriclikeUtils = mFabriclikeUtils;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(@NonNull Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@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);
|
||||
mGameVersionSpinner = view.findViewById(R.id.fabric_installer_game_ver_spinner);
|
||||
mGameVersionSpinner.setOnItemSelectedListener(new GameVersionSelectedListener());
|
||||
mLoaderVersionSpinner = view.findViewById(R.id.fabric_installer_loader_ver_spinner);
|
||||
mLoaderVersionSpinner.setOnItemSelectedListener(new LoaderVersionSelectedListener());
|
||||
mProgressBar = view.findViewById(R.id.fabric_installer_progress_bar);
|
||||
mRetryView = view.findViewById(R.id.fabric_installer_retry_layout);
|
||||
mOnlyStableCheckbox = view.findViewById(R.id.fabric_installer_only_stable_checkbox);
|
||||
mOnlyStableCheckbox.setOnCheckedChangeListener(this);
|
||||
view.findViewById(R.id.fabric_installer_retry_button).setOnClickListener(this::onClickRetry);
|
||||
((TextView)view.findViewById(R.id.fabric_installer_label_loader_ver)).setText(getString(R.string.fabric_dl_loader_version, mFabriclikeUtils.getName()));
|
||||
ModloaderListenerProxy proxy = getListenerProxy();
|
||||
if(proxy != null) {
|
||||
mStartButton.setEnabled(false);
|
||||
proxy.attachListener(this);
|
||||
}
|
||||
updateGameVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
cancelFutureChecked(mGameVersionFuture);
|
||||
cancelFutureChecked(mLoaderVersionFuture);
|
||||
ModloaderListenerProxy proxy = getListenerProxy();
|
||||
if(proxy != null) {
|
||||
proxy.detachListener();
|
||||
}
|
||||
}
|
||||
|
||||
private void onClickStart(View v) {
|
||||
if(ProgressKeeper.hasOngoingTasks()) {
|
||||
Toast.makeText(v.getContext(), R.string.tasks_ongoing, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
ModloaderListenerProxy proxy = new ModloaderListenerProxy();
|
||||
FabriclikeDownloadTask fabricDownloadTask = new FabriclikeDownloadTask(proxy, mFabriclikeUtils,
|
||||
mSelectedGameVersion, mSelectedLoaderVersion, true);
|
||||
proxy.attachListener(this);
|
||||
setListenerProxy(proxy);
|
||||
mStartButton.setEnabled(false);
|
||||
new Thread(fabricDownloadTask).start();
|
||||
}
|
||||
|
||||
private void onClickRetry(View v) {
|
||||
mStartButton.setEnabled(false);
|
||||
mRetryView.setVisibility(View.GONE);
|
||||
mLoaderVersionSpinner.setAdapter(null);
|
||||
if(mGameVersionArray == null) {
|
||||
mGameVersionSpinner.setAdapter(null);
|
||||
updateGameVersions();
|
||||
return;
|
||||
}
|
||||
updateLoaderVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadFinished(File downloadedFile) {
|
||||
Tools.runOnUiThread(()->{
|
||||
|
||||
getListenerProxy().detachListener();
|
||||
setListenerProxy(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();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataNotAvailable() {
|
||||
Tools.runOnUiThread(()->{
|
||||
Context context = requireContext();
|
||||
getListenerProxy().detachListener();
|
||||
setListenerProxy(null);
|
||||
mStartButton.setEnabled(true);
|
||||
Tools.dialog(context,
|
||||
context.getString(R.string.global_error),
|
||||
context.getString(R.string.fabric_dl_cant_read_meta, mFabriclikeUtils.getName()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(Exception e) {
|
||||
Tools.runOnUiThread(()-> {
|
||||
Context context = requireContext();
|
||||
getListenerProxy().detachListener();
|
||||
setListenerProxy(null);
|
||||
mStartButton.setEnabled(true);
|
||||
Tools.showError(context, e);
|
||||
});
|
||||
}
|
||||
|
||||
private void cancelFutureChecked(Future<?> future) {
|
||||
if(future != null && !future.isCancelled()) future.cancel(true);
|
||||
}
|
||||
|
||||
private void startLoading() {
|
||||
mProgressBar.setVisibility(View.VISIBLE);
|
||||
mStartButton.setEnabled(false);
|
||||
}
|
||||
|
||||
private void stopLoading() {
|
||||
mProgressBar.setVisibility(View.GONE);
|
||||
// The "visibility on" is managed by the spinners
|
||||
}
|
||||
|
||||
private ArrayAdapter<FabricVersion> createAdapter(FabricVersion[] fabricVersions, boolean onlyStable) {
|
||||
ArrayList<FabricVersion> filteredVersions = new ArrayList<>(fabricVersions.length);
|
||||
for(FabricVersion fabricVersion : fabricVersions) {
|
||||
if(!onlyStable || fabricVersion.stable) filteredVersions.add(fabricVersion);
|
||||
}
|
||||
filteredVersions.trimToSize();
|
||||
return new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_dropdown_item, filteredVersions);
|
||||
}
|
||||
|
||||
private void onException(Future<?> myFuture, Exception e) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
if(e != null) Tools.showError(requireContext(), e);
|
||||
mRetryView.setVisibility(View.VISIBLE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
|
||||
updateGameSpinner();
|
||||
updateLoaderSpinner();
|
||||
}
|
||||
|
||||
class LoaderVersionSelectedListener implements AdapterView.OnItemSelectedListener {
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
mSelectedLoaderVersion = ((FabricVersion) adapterView.getAdapter().getItem(i)).version;
|
||||
mStartButton.setEnabled(mSelectedGameVersion != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
mSelectedLoaderVersion = null;
|
||||
mStartButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
class LoadLoaderVersionsTask implements SelfReferencingFuture.FutureInterface {
|
||||
@Override
|
||||
public void run(Future<?> myFuture) {
|
||||
Log.i("LoadLoaderVersions", "Starting...");
|
||||
try {
|
||||
mLoaderVersionArray = mFabriclikeUtils.downloadLoaderVersions(mSelectedGameVersion);
|
||||
if(mLoaderVersionArray != null) onFinished(myFuture);
|
||||
else onException(myFuture, null);
|
||||
}catch (IOException e) {
|
||||
onException(myFuture, e);
|
||||
}
|
||||
}
|
||||
private void onFinished(Future<?> myFuture) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
updateLoaderSpinner();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoaderVersions() {
|
||||
startLoading();
|
||||
mLoaderVersionFuture = new SelfReferencingFuture(new LoadLoaderVersionsTask()).startOnExecutor(PojavApplication.sExecutorService);
|
||||
}
|
||||
|
||||
private void updateLoaderSpinner() {
|
||||
mLoaderVersionSpinner.setAdapter(createAdapter(mLoaderVersionArray, mOnlyStableCheckbox.isChecked()));
|
||||
}
|
||||
|
||||
class GameVersionSelectedListener implements AdapterView.OnItemSelectedListener {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||
mSelectedGameVersion = ((FabricVersion) adapterView.getAdapter().getItem(i)).version;
|
||||
cancelFutureChecked(mLoaderVersionFuture);
|
||||
updateLoaderVersions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
mSelectedGameVersion = null;
|
||||
if(mLoaderVersionFuture != null) mLoaderVersionFuture.cancel(true);
|
||||
adapterView.setAdapter(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LoadGameVersionsTask implements SelfReferencingFuture.FutureInterface {
|
||||
@Override
|
||||
public void run(Future<?> myFuture) {
|
||||
try {
|
||||
mGameVersionArray = mFabriclikeUtils.downloadGameVersions();
|
||||
if(mGameVersionArray != null) onFinished(myFuture);
|
||||
else onException(myFuture, null);
|
||||
}catch (IOException e) {
|
||||
onException(myFuture, e);
|
||||
}
|
||||
}
|
||||
private void onFinished(Future<?> myFuture) {
|
||||
Tools.runOnUiThread(()->{
|
||||
if(myFuture.isCancelled()) return;
|
||||
stopLoading();
|
||||
updateGameSpinner();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void updateGameVersions() {
|
||||
startLoading();
|
||||
mGameVersionFuture = new SelfReferencingFuture(new LoadGameVersionsTask()).startOnExecutor(PojavApplication.sExecutorService);
|
||||
}
|
||||
|
||||
private void updateGameSpinner() {
|
||||
mGameVersionSpinner.setAdapter(createAdapter(mGameVersionArray, mOnlyStableCheckbox.isChecked()));
|
||||
}
|
||||
|
||||
protected abstract ModloaderListenerProxy getListenerProxy();
|
||||
protected abstract void setListenerProxy(ModloaderListenerProxy listenerProxy);
|
||||
}
|
@ -33,5 +33,7 @@ public class ProfileTypeSelectFragment extends Fragment {
|
||||
Tools.swapFragment(requireActivity(), ForgeInstallFragment.class, ForgeInstallFragment.TAG, false, null));
|
||||
view.findViewById(R.id.modded_profile_modpack).setOnClickListener((v)->
|
||||
Tools.swapFragment(requireActivity(), SearchModFragment.class, SearchModFragment.TAG, false, null));
|
||||
view.findViewById(R.id.modded_profile_quilt).setOnClickListener((v)->
|
||||
Tools.swapFragment(requireActivity(), QuiltInstallFragment.class, QuiltInstallFragment.TAG, false, null));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package net.kdt.pojavlaunch.fragments;
|
||||
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy;
|
||||
|
||||
public class QuiltInstallFragment extends FabriclikeInstallFragment {
|
||||
|
||||
public static final String TAG = "QuiltInstallFragment";
|
||||
private static ModloaderListenerProxy sTaskProxy;
|
||||
|
||||
public QuiltInstallFragment() {
|
||||
super(FabriclikeUtils.QUILT_UTILS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ModloaderListenerProxy getListenerProxy() {
|
||||
return sTaskProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setListenerProxy(ModloaderListenerProxy listenerProxy) {
|
||||
sTaskProxy = listenerProxy;
|
||||
}
|
||||
}
|
@ -15,13 +15,15 @@ import org.json.JSONObject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||
public class FabriclikeDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||
private final ModloaderDownloadListener mModloaderDownloadListener;
|
||||
private final FabriclikeUtils mUtils;
|
||||
private final String mGameVersion;
|
||||
private final String mLoaderVersion;
|
||||
private final boolean mCreateProfile;
|
||||
public FabricDownloadTask(ModloaderDownloadListener modloaderDownloadListener, String mGameVersion, String mLoaderVersion, boolean mCreateProfile) {
|
||||
public FabriclikeDownloadTask(ModloaderDownloadListener modloaderDownloadListener, FabriclikeUtils utils, String mGameVersion, String mLoaderVersion, boolean mCreateProfile) {
|
||||
this.mModloaderDownloadListener = modloaderDownloadListener;
|
||||
this.mUtils = utils;
|
||||
this.mGameVersion = mGameVersion;
|
||||
this.mLoaderVersion = mLoaderVersion;
|
||||
this.mCreateProfile = mCreateProfile;
|
||||
@ -40,7 +42,7 @@ public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||
}
|
||||
|
||||
private boolean runCatching() throws IOException{
|
||||
String fabricJson = DownloadUtils.downloadString(FabricUtils.createJsonDownloadUrl(mGameVersion, mLoaderVersion));
|
||||
String fabricJson = DownloadUtils.downloadString(mUtils.createJsonDownloadUrl(mGameVersion, mLoaderVersion));
|
||||
String versionId;
|
||||
try {
|
||||
JSONObject fabricJsonObject = new JSONObject(fabricJson);
|
||||
@ -58,7 +60,7 @@ public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||
LauncherProfiles.load();
|
||||
MinecraftProfile fabricProfile = new MinecraftProfile();
|
||||
fabricProfile.lastVersionId = versionId;
|
||||
fabricProfile.name = "Minecraft " + mGameVersion + " with Fabric " + mLoaderVersion;
|
||||
fabricProfile.name = "Minecraft " + mGameVersion + " with " + mUtils.getName()+ " " + mLoaderVersion;
|
||||
LauncherProfiles.insertMinecraftProfile(fabricProfile);
|
||||
LauncherProfiles.write();
|
||||
}
|
||||
@ -68,6 +70,6 @@ public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||
@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);
|
||||
ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, progress100, R.string.fabric_dl_progress, mUtils.getName());
|
||||
}
|
||||
}
|
@ -1,7 +1,5 @@
|
||||
package net.kdt.pojavlaunch.modloaders;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import net.kdt.pojavlaunch.Tools;
|
||||
@ -11,31 +9,44 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class FabricUtils {
|
||||
private static final String FABRIC_LOADER_METADATA_URL = "https://meta.fabricmc.net/v2/versions/loader/%s";
|
||||
private static final String FABRIC_GAME_METADATA_URL = "https://meta.fabricmc.net/v2/versions/game";
|
||||
public class FabriclikeUtils {
|
||||
|
||||
private static final String FABRIC_JSON_DOWNLOAD_URL = "https://meta.fabricmc.net/v2/versions/loader/%s/%s/profile/json";
|
||||
public static final FabriclikeUtils FABRIC_UTILS = new FabriclikeUtils("https://meta.fabricmc.net/v2", "fabric", "Fabric");
|
||||
public static final FabriclikeUtils QUILT_UTILS = new FabriclikeUtils("https://meta.quiltmc.org/v3", "quilt", "Quilt");
|
||||
|
||||
public static FabricVersion[] downloadGameVersions() throws IOException{
|
||||
private static final String LOADER_METADATA_URL = "%s/versions/loader/%s";
|
||||
private static final String GAME_METADATA_URL = "%s/versions/game";
|
||||
|
||||
private static final String JSON_DOWNLOAD_URL = "%s/versions/loader/%s/%s/profile/json";
|
||||
|
||||
private final String mApiUrl;
|
||||
private final String mCachePrefix;
|
||||
private final String mName;
|
||||
|
||||
private FabriclikeUtils(String mApiUrl, String cachePrefix, String mName) {
|
||||
this.mApiUrl = mApiUrl;
|
||||
this.mCachePrefix = cachePrefix;
|
||||
this.mName = mName;
|
||||
}
|
||||
|
||||
public FabricVersion[] downloadGameVersions() throws IOException{
|
||||
try {
|
||||
return DownloadUtils.downloadStringCached(FABRIC_GAME_METADATA_URL, "fabric_game_versions",
|
||||
FabricUtils::deserializeRawVersions
|
||||
return DownloadUtils.downloadStringCached(String.format(GAME_METADATA_URL, mApiUrl), mCachePrefix+"_game_versions",
|
||||
FabriclikeUtils::deserializeRawVersions
|
||||
);
|
||||
}catch (DownloadUtils.ParseException ignored) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FabricVersion[] downloadLoaderVersions(String gameVersion) throws IOException{
|
||||
public FabricVersion[] downloadLoaderVersions(String gameVersion) throws IOException{
|
||||
try {
|
||||
String urlEncodedGameVersion = URLEncoder.encode(gameVersion, "UTF-8");
|
||||
return DownloadUtils.downloadStringCached(String.format(FABRIC_LOADER_METADATA_URL, urlEncodedGameVersion),
|
||||
"fabric_loader_versions."+urlEncodedGameVersion,
|
||||
return DownloadUtils.downloadStringCached(String.format(LOADER_METADATA_URL, mApiUrl, urlEncodedGameVersion),
|
||||
mCachePrefix+"_loader_versions."+urlEncodedGameVersion,
|
||||
(input)->{ try {
|
||||
return deserializeLoaderVersions(input);
|
||||
}catch (JSONException e) {
|
||||
@ -48,14 +59,18 @@ public class FabricUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String createJsonDownloadUrl(String gameVersion, String loaderVersion) {
|
||||
public String createJsonDownloadUrl(String gameVersion, String loaderVersion) {
|
||||
try {
|
||||
gameVersion = URLEncoder.encode(gameVersion, "UTF-8");
|
||||
loaderVersion = URLEncoder.encode(loaderVersion, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return String.format(FABRIC_JSON_DOWNLOAD_URL, gameVersion, loaderVersion);
|
||||
return String.format(JSON_DOWNLOAD_URL, mApiUrl, gameVersion, loaderVersion);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
private static FabricVersion[] deserializeLoaderVersions(String input) throws JSONException {
|
||||
@ -65,7 +80,12 @@ public class FabricUtils {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i).getJSONObject("loader");
|
||||
FabricVersion fabricVersion = new FabricVersion();
|
||||
fabricVersion.version = jsonObject.getString("version");
|
||||
fabricVersion.stable = jsonObject.getBoolean("stable");
|
||||
//Quilt has a skill issue and does not say which versions are stable or not
|
||||
if(jsonObject.has("stable")) {
|
||||
fabricVersion.stable = jsonObject.getBoolean("stable");
|
||||
} else {
|
||||
fabricVersion.stable = !fabricVersion.version.contains("beta");
|
||||
}
|
||||
fabricVersions[i] = fabricVersion;
|
||||
}
|
||||
return fabricVersions;
|
||||
@ -79,15 +99,4 @@ public class FabricUtils {
|
||||
throw new DownloadUtils.ParseException(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);
|
||||
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import net.kdt.pojavlaunch.JavaGUILauncherActivity;
|
||||
import net.kdt.pojavlaunch.modloaders.FabricDownloadTask;
|
||||
import net.kdt.pojavlaunch.modloaders.FabricUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeDownloadTask;
|
||||
import net.kdt.pojavlaunch.modloaders.FabriclikeUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.ForgeDownloadTask;
|
||||
import net.kdt.pojavlaunch.modloaders.ForgeUtils;
|
||||
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||
@ -37,7 +37,7 @@ public class ModLoader {
|
||||
case MOD_LOADER_FABRIC:
|
||||
return "fabric-loader-"+modLoaderVersion+"-"+minecraftVersion;
|
||||
case MOD_LOADER_QUILT:
|
||||
throw new RuntimeException("Quilt is not supported");
|
||||
return "quilt-loader-"+modLoaderVersion+"-"+minecraftVersion;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -54,9 +54,9 @@ public class ModLoader {
|
||||
case MOD_LOADER_FORGE:
|
||||
return new ForgeDownloadTask(listener, minecraftVersion, modLoaderVersion);
|
||||
case MOD_LOADER_FABRIC:
|
||||
return new FabricDownloadTask(listener, minecraftVersion, modLoaderVersion, false);
|
||||
return createFabriclikeTask(listener, FabriclikeUtils.FABRIC_UTILS);
|
||||
case MOD_LOADER_QUILT:
|
||||
throw new RuntimeException("Quilt is not supported");
|
||||
return createFabriclikeTask(listener, FabriclikeUtils.QUILT_UTILS);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@ -99,4 +99,8 @@ public class ModLoader {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private FabriclikeDownloadTask createFabriclikeTask(ModloaderDownloadListener modloaderDownloadListener, FabriclikeUtils utils) {
|
||||
return new FabriclikeDownloadTask(modloaderDownloadListener, utils, minecraftVersion, modLoaderVersion, false);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.kdt.DefocusableScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.kdt.DefocusableScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/background_app"
|
||||
>
|
||||
android:background="@color/background_app">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -88,9 +85,15 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/padding_large"
|
||||
android:layout_marginTop="@dimen/padding_large"
|
||||
android:text="@string/modloader_dl_install_fabric"
|
||||
app:layout_constraintTop_toBottomOf="@+id/view_modded"
|
||||
tools:layout_editor_absoluteX="50dp" />
|
||||
android:text="@string/modloader_dl_install_fabric" />
|
||||
|
||||
<com.kdt.mcgui.MineButton
|
||||
android:id="@+id/modded_profile_quilt"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/padding_large"
|
||||
android:layout_marginTop="@dimen/padding_large"
|
||||
android:text="@string/modloader_dl_install_quilt" />
|
||||
|
||||
<com.kdt.mcgui.MineButton
|
||||
android:id="@+id/modded_profile_forge"
|
||||
@ -98,10 +101,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/padding_large"
|
||||
android:layout_marginTop="@dimen/padding_large"
|
||||
|
||||
android:text="@string/modloader_dl_install_forge"
|
||||
|
||||
app:layout_constraintTop_toBottomOf="@+id/modded_profile_fabric" />
|
||||
android:text="@string/modloader_dl_install_forge" />
|
||||
|
||||
<com.kdt.mcgui.MineButton
|
||||
android:id="@+id/modded_profile_modpack"
|
||||
|
@ -388,12 +388,13 @@
|
||||
<string name="modloader_dl_failed_to_load_list">Failed to load the version list!</string>
|
||||
<string name="forge_dl_no_installer">Sorry, but this version of Forge does not have an installer, which is not yet supported.</string>
|
||||
<string name="forge_dl_select_version">Select Forge version</string>
|
||||
<string name="fabric_dl_progress">Downloading Fabric installer</string>
|
||||
<string name="fabric_dl_loader_version">Fabric loader version</string>
|
||||
<string name="fabric_dl_progress">Downloading %s loader metadata</string>
|
||||
<string name="fabric_dl_loader_version">%s loader version</string>
|
||||
<string name="fabric_dl_game_version">Minecraft version</string>
|
||||
<string name="fabric_dl_install">Install</string>
|
||||
<string name="fabric_dl_cant_read_meta">Failed to read Fabric metadata. Please try again later.</string>
|
||||
<string name="fabric_dl_cant_read_meta">Failed to read %s loader metadata. Please try again later.</string>
|
||||
<string name="modloader_dl_install_fabric">Create Fabric profile</string>
|
||||
<string name="modloader_dl_install_quilt">Create Quilt profile</string>
|
||||
<string name="modloader_dl_install_forge">Create Forge profile</string>
|
||||
<string name="create_profile_vanilla">Create vanilla profile</string>
|
||||
<string name="create_profile_vanilla_like_versions">Vanilla-like versions</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user