Android: Add Gecko code downloading
This commit is contained in:
parent
47efd3317d
commit
53ae1a0725
|
@ -29,7 +29,8 @@ public class GamePropertiesDialog extends DialogFragment
|
||||||
{
|
{
|
||||||
public static final String TAG = "GamePropertiesDialog";
|
public static final String TAG = "GamePropertiesDialog";
|
||||||
private static final String ARG_PATH = "path";
|
private static final String ARG_PATH = "path";
|
||||||
private static final String ARG_GAMEID = "game_id";
|
private static final String ARG_GAME_ID = "game_id";
|
||||||
|
private static final String ARG_GAMETDB_ID = "gametdb_id";
|
||||||
public static final String ARG_REVISION = "revision";
|
public static final String ARG_REVISION = "revision";
|
||||||
private static final String ARG_PLATFORM = "platform";
|
private static final String ARG_PLATFORM = "platform";
|
||||||
private static final String ARG_SHOULD_ALLOW_CONVERSION = "should_allow_conversion";
|
private static final String ARG_SHOULD_ALLOW_CONVERSION = "should_allow_conversion";
|
||||||
|
@ -40,7 +41,8 @@ public class GamePropertiesDialog extends DialogFragment
|
||||||
|
|
||||||
Bundle arguments = new Bundle();
|
Bundle arguments = new Bundle();
|
||||||
arguments.putString(ARG_PATH, gameFile.getPath());
|
arguments.putString(ARG_PATH, gameFile.getPath());
|
||||||
arguments.putString(ARG_GAMEID, gameFile.getGameId());
|
arguments.putString(ARG_GAME_ID, gameFile.getGameId());
|
||||||
|
arguments.putString(ARG_GAMETDB_ID, gameFile.getGameTdbId());
|
||||||
arguments.putInt(ARG_REVISION, gameFile.getRevision());
|
arguments.putInt(ARG_REVISION, gameFile.getRevision());
|
||||||
arguments.putInt(ARG_PLATFORM, gameFile.getPlatform());
|
arguments.putInt(ARG_PLATFORM, gameFile.getPlatform());
|
||||||
arguments.putBoolean(ARG_SHOULD_ALLOW_CONVERSION, gameFile.shouldAllowConversion());
|
arguments.putBoolean(ARG_SHOULD_ALLOW_CONVERSION, gameFile.shouldAllowConversion());
|
||||||
|
@ -54,7 +56,8 @@ public class GamePropertiesDialog extends DialogFragment
|
||||||
public Dialog onCreateDialog(Bundle savedInstanceState)
|
public Dialog onCreateDialog(Bundle savedInstanceState)
|
||||||
{
|
{
|
||||||
final String path = requireArguments().getString(ARG_PATH);
|
final String path = requireArguments().getString(ARG_PATH);
|
||||||
final String gameId = requireArguments().getString(ARG_GAMEID);
|
final String gameId = requireArguments().getString(ARG_GAME_ID);
|
||||||
|
final String gameTdbId = requireArguments().getString(ARG_GAMETDB_ID);
|
||||||
final int revision = requireArguments().getInt(ARG_REVISION);
|
final int revision = requireArguments().getInt(ARG_REVISION);
|
||||||
final int platform = requireArguments().getInt(ARG_PLATFORM);
|
final int platform = requireArguments().getInt(ARG_PLATFORM);
|
||||||
final boolean shouldAllowConversion =
|
final boolean shouldAllowConversion =
|
||||||
|
@ -93,7 +96,7 @@ public class GamePropertiesDialog extends DialogFragment
|
||||||
SettingsActivity.launch(getContext(), MenuTag.SETTINGS, gameId, revision, isWii));
|
SettingsActivity.launch(getContext(), MenuTag.SETTINGS, gameId, revision, isWii));
|
||||||
|
|
||||||
itemsBuilder.add(R.string.properties_edit_cheats, (dialog, i) ->
|
itemsBuilder.add(R.string.properties_edit_cheats, (dialog, i) ->
|
||||||
CheatsActivity.launch(getContext(), gameId, revision, isWii));
|
CheatsActivity.launch(getContext(), gameId, gameTdbId, revision, isWii));
|
||||||
|
|
||||||
itemsBuilder.add(R.string.properties_clear_game_settings, (dialog, i) ->
|
itemsBuilder.add(R.string.properties_clear_game_settings, (dialog, i) ->
|
||||||
clearGameSettings(gameId));
|
clearGameSettings(gameId));
|
||||||
|
|
|
@ -21,6 +21,7 @@ public class CheatsViewModel extends ViewModel
|
||||||
private final MutableLiveData<Integer> mCheatAddedEvent = new MutableLiveData<>(null);
|
private final MutableLiveData<Integer> mCheatAddedEvent = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<Integer> mCheatChangedEvent = new MutableLiveData<>(null);
|
private final MutableLiveData<Integer> mCheatChangedEvent = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<Integer> mCheatDeletedEvent = new MutableLiveData<>(null);
|
private final MutableLiveData<Integer> mCheatDeletedEvent = new MutableLiveData<>(null);
|
||||||
|
private final MutableLiveData<Integer> mGeckoCheatsDownloadedEvent = new MutableLiveData<>(null);
|
||||||
private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false);
|
private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false);
|
||||||
|
|
||||||
private ArrayList<PatchCheat> mPatchCheats;
|
private ArrayList<PatchCheat> mPatchCheats;
|
||||||
|
@ -236,6 +237,38 @@ public class CheatsViewModel extends ViewModel
|
||||||
mCheatDeletedEvent.setValue(null);
|
mCheatDeletedEvent.setValue(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When Gecko cheats are downloaded, the integer stored in the returned LiveData
|
||||||
|
* changes to the number of cheats added, then changes back to null.
|
||||||
|
*/
|
||||||
|
public LiveData<Integer> getGeckoCheatsDownloadedEvent()
|
||||||
|
{
|
||||||
|
return mGeckoCheatsDownloadedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int addDownloadedGeckoCodes(GeckoCheat[] cheats)
|
||||||
|
{
|
||||||
|
int cheatsAdded = 0;
|
||||||
|
|
||||||
|
for (GeckoCheat cheat : cheats)
|
||||||
|
{
|
||||||
|
if (!mGeckoCheats.contains(cheat))
|
||||||
|
{
|
||||||
|
mGeckoCheats.add(cheat);
|
||||||
|
cheatsAdded++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cheatsAdded != 0)
|
||||||
|
{
|
||||||
|
mGeckoCheatsNeedSaving = true;
|
||||||
|
mGeckoCheatsDownloadedEvent.setValue(cheatsAdded);
|
||||||
|
mGeckoCheatsDownloadedEvent.setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cheatsAdded;
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<Boolean> getOpenDetailsViewEvent()
|
public LiveData<Boolean> getOpenDetailsViewEvent()
|
||||||
{
|
{
|
||||||
return mOpenDetailsViewEvent;
|
return mOpenDetailsViewEvent;
|
||||||
|
|
|
@ -4,6 +4,7 @@ package org.dolphinemu.dolphinemu.features.cheats.model;
|
||||||
|
|
||||||
import androidx.annotation.Keep;
|
import androidx.annotation.Keep;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public class GeckoCheat extends AbstractCheat
|
public class GeckoCheat extends AbstractCheat
|
||||||
{
|
{
|
||||||
|
@ -26,6 +27,12 @@ public class GeckoCheat extends AbstractCheat
|
||||||
|
|
||||||
private native long createNew();
|
private native long createNew();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj)
|
||||||
|
{
|
||||||
|
return obj != null && getClass() == obj.getClass() && equalsImpl((GeckoCheat) obj);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean supportsCreator()
|
public boolean supportsCreator()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -52,6 +59,8 @@ public class GeckoCheat extends AbstractCheat
|
||||||
|
|
||||||
public native boolean getEnabled();
|
public native boolean getEnabled();
|
||||||
|
|
||||||
|
public native boolean equalsImpl(@NonNull GeckoCheat other);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected native int trySetImpl(@NonNull String name, @NonNull String creator,
|
protected native int trySetImpl(@NonNull String name, @NonNull String creator,
|
||||||
@NonNull String notes, @NonNull String code);
|
@NonNull String notes, @NonNull String code);
|
||||||
|
@ -63,4 +72,7 @@ public class GeckoCheat extends AbstractCheat
|
||||||
public static native GeckoCheat[] loadCodes(String gameId, int revision);
|
public static native GeckoCheat[] loadCodes(String gameId, int revision);
|
||||||
|
|
||||||
public static native void saveCodes(String gameId, int revision, GeckoCheat[] codes);
|
public static native void saveCodes(String gameId, int revision, GeckoCheat[] codes);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static native GeckoCheat[] downloadCodes(String gameTdbId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.view.View;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat;
|
import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat;
|
||||||
|
@ -17,6 +18,7 @@ public class ActionViewHolder extends CheatItemViewHolder implements View.OnClic
|
||||||
{
|
{
|
||||||
private final TextView mName;
|
private final TextView mName;
|
||||||
|
|
||||||
|
private CheatsActivity mActivity;
|
||||||
private CheatsViewModel mViewModel;
|
private CheatsViewModel mViewModel;
|
||||||
private int mString;
|
private int mString;
|
||||||
private int mPosition;
|
private int mPosition;
|
||||||
|
@ -30,9 +32,10 @@ public class ActionViewHolder extends CheatItemViewHolder implements View.OnClic
|
||||||
itemView.setOnClickListener(this);
|
itemView.setOnClickListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(CheatsViewModel viewModel, CheatItem item, int position)
|
public void bind(CheatsActivity activity, CheatItem item, int position)
|
||||||
{
|
{
|
||||||
mViewModel = viewModel;
|
mActivity = activity;
|
||||||
|
mViewModel = new ViewModelProvider(activity).get(CheatsViewModel.class);
|
||||||
mString = item.getString();
|
mString = item.getString();
|
||||||
mPosition = position;
|
mPosition = position;
|
||||||
|
|
||||||
|
@ -56,5 +59,9 @@ public class ActionViewHolder extends CheatItemViewHolder implements View.OnClic
|
||||||
mViewModel.startAddingCheat(new PatchCheat(), mPosition);
|
mViewModel.startAddingCheat(new PatchCheat(), mPosition);
|
||||||
mViewModel.openDetailsView();
|
mViewModel.openDetailsView();
|
||||||
}
|
}
|
||||||
|
else if (mString == R.string.cheats_download_gecko)
|
||||||
|
{
|
||||||
|
mActivity.downloadGeckoCodes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,5 +16,5 @@ public abstract class CheatItemViewHolder extends RecyclerView.ViewHolder
|
||||||
super(itemView);
|
super(itemView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void bind(CheatsViewModel viewModel, CheatItem item, int position);
|
public abstract void bind(CheatsActivity activity, CheatItem item, int position);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import android.widget.CompoundButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
@ -34,11 +35,11 @@ public class CheatViewHolder extends CheatItemViewHolder
|
||||||
mCheckbox = itemView.findViewById(R.id.checkbox);
|
mCheckbox = itemView.findViewById(R.id.checkbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(CheatsViewModel viewModel, CheatItem item, int position)
|
public void bind(CheatsActivity activity, CheatItem item, int position)
|
||||||
{
|
{
|
||||||
mCheckbox.setOnCheckedChangeListener(null);
|
mCheckbox.setOnCheckedChangeListener(null);
|
||||||
|
|
||||||
mViewModel = viewModel;
|
mViewModel = new ViewModelProvider(activity).get(CheatsViewModel.class);
|
||||||
mCheat = item.getCheat();
|
mCheat = item.getCheat();
|
||||||
mPosition = position;
|
mPosition = position;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.view.ViewCompat;
|
import androidx.core.view.ViewCompat;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
@ -17,6 +18,7 @@ import androidx.slidingpanelayout.widget.SlidingPaneLayout;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
|
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
|
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
|
||||||
|
import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat;
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
||||||
import org.dolphinemu.dolphinemu.ui.TwoPaneOnBackPressedCallback;
|
import org.dolphinemu.dolphinemu.ui.TwoPaneOnBackPressedCallback;
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
||||||
|
@ -25,10 +27,12 @@ public class CheatsActivity extends AppCompatActivity
|
||||||
implements SlidingPaneLayout.PanelSlideListener
|
implements SlidingPaneLayout.PanelSlideListener
|
||||||
{
|
{
|
||||||
private static final String ARG_GAME_ID = "game_id";
|
private static final String ARG_GAME_ID = "game_id";
|
||||||
|
private static final String ARG_GAMETDB_ID = "gametdb_id";
|
||||||
private static final String ARG_REVISION = "revision";
|
private static final String ARG_REVISION = "revision";
|
||||||
private static final String ARG_IS_WII = "is_wii";
|
private static final String ARG_IS_WII = "is_wii";
|
||||||
|
|
||||||
private String mGameId;
|
private String mGameId;
|
||||||
|
private String mGameTdbId;
|
||||||
private int mRevision;
|
private int mRevision;
|
||||||
private boolean mIsWii;
|
private boolean mIsWii;
|
||||||
private CheatsViewModel mViewModel;
|
private CheatsViewModel mViewModel;
|
||||||
|
@ -40,10 +44,12 @@ public class CheatsActivity extends AppCompatActivity
|
||||||
private View mCheatListLastFocus;
|
private View mCheatListLastFocus;
|
||||||
private View mCheatDetailsLastFocus;
|
private View mCheatDetailsLastFocus;
|
||||||
|
|
||||||
public static void launch(Context context, String gameId, int revision, boolean isWii)
|
public static void launch(Context context, String gameId, String gameTdbId, int revision,
|
||||||
|
boolean isWii)
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(context, CheatsActivity.class);
|
Intent intent = new Intent(context, CheatsActivity.class);
|
||||||
intent.putExtra(ARG_GAME_ID, gameId);
|
intent.putExtra(ARG_GAME_ID, gameId);
|
||||||
|
intent.putExtra(ARG_GAMETDB_ID, gameTdbId);
|
||||||
intent.putExtra(ARG_REVISION, revision);
|
intent.putExtra(ARG_REVISION, revision);
|
||||||
intent.putExtra(ARG_IS_WII, isWii);
|
intent.putExtra(ARG_IS_WII, isWii);
|
||||||
context.startActivity(intent);
|
context.startActivity(intent);
|
||||||
|
@ -58,6 +64,7 @@ public class CheatsActivity extends AppCompatActivity
|
||||||
|
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
mGameId = intent.getStringExtra(ARG_GAME_ID);
|
mGameId = intent.getStringExtra(ARG_GAME_ID);
|
||||||
|
mGameTdbId = intent.getStringExtra(ARG_GAMETDB_ID);
|
||||||
mRevision = intent.getIntExtra(ARG_REVISION, 0);
|
mRevision = intent.getIntExtra(ARG_REVISION, 0);
|
||||||
mIsWii = intent.getBooleanExtra(ARG_IS_WII, true);
|
mIsWii = intent.getBooleanExtra(ARG_IS_WII, true);
|
||||||
|
|
||||||
|
@ -161,6 +168,49 @@ public class CheatsActivity extends AppCompatActivity
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void downloadGeckoCodes()
|
||||||
|
{
|
||||||
|
AlertDialog progressDialog = new AlertDialog.Builder(this, R.style.DolphinDialogBase).create();
|
||||||
|
progressDialog.setTitle(R.string.cheats_downloading);
|
||||||
|
progressDialog.setCancelable(false);
|
||||||
|
progressDialog.show();
|
||||||
|
|
||||||
|
new Thread(() ->
|
||||||
|
{
|
||||||
|
GeckoCheat[] codes = GeckoCheat.downloadCodes(mGameTdbId);
|
||||||
|
|
||||||
|
runOnUiThread(() ->
|
||||||
|
{
|
||||||
|
progressDialog.dismiss();
|
||||||
|
|
||||||
|
if (codes == null)
|
||||||
|
{
|
||||||
|
new AlertDialog.Builder(this, R.style.DolphinDialogBase)
|
||||||
|
.setMessage(getString(R.string.cheats_download_failed))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
else if (codes.length == 0)
|
||||||
|
{
|
||||||
|
new AlertDialog.Builder(this, R.style.DolphinDialogBase)
|
||||||
|
.setMessage(getString(R.string.cheats_download_empty))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int cheatsAdded = mViewModel.addDownloadedGeckoCodes(codes);
|
||||||
|
String message = getString(R.string.cheats_download_succeeded, codes.length, cheatsAdded);
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this, R.style.DolphinDialogBase)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
public static void setOnFocusChangeListenerRecursively(@NonNull View view,
|
public static void setOnFocusChangeListenerRecursively(@NonNull View view,
|
||||||
View.OnFocusChangeListener listener)
|
View.OnFocusChangeListener listener)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,16 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
|
||||||
if (position != null)
|
if (position != null)
|
||||||
notifyItemRemoved(position);
|
notifyItemRemoved(position);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mViewModel.getGeckoCheatsDownloadedEvent().observe(activity, (cheatsAdded) ->
|
||||||
|
{
|
||||||
|
if (cheatsAdded != null)
|
||||||
|
{
|
||||||
|
int positionEnd = getItemCount() - 2; // Skip "Add Gecko Code" and "Download Gecko Codes"
|
||||||
|
int positionStart = positionEnd - cheatsAdded;
|
||||||
|
notifyItemRangeInserted(positionStart, cheatsAdded);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
@ -75,14 +85,14 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull CheatItemViewHolder holder, int position)
|
public void onBindViewHolder(@NonNull CheatItemViewHolder holder, int position)
|
||||||
{
|
{
|
||||||
holder.bind(mViewModel, getItemAt(position), position);
|
holder.bind(mActivity, getItemAt(position), position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount()
|
public int getItemCount()
|
||||||
{
|
{
|
||||||
return mViewModel.getARCheats().size() + mViewModel.getGeckoCheats().size() +
|
return mViewModel.getARCheats().size() + mViewModel.getGeckoCheats().size() +
|
||||||
mViewModel.getPatchCheats().size() + 6;
|
mViewModel.getPatchCheats().size() + 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,6 +154,9 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
|
||||||
return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_gecko);
|
return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_gecko);
|
||||||
position -= 1;
|
position -= 1;
|
||||||
|
|
||||||
|
if (position == 0)
|
||||||
|
return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_download_gecko);
|
||||||
|
|
||||||
throw new IndexOutOfBoundsException();
|
throw new IndexOutOfBoundsException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class HeaderViewHolder extends CheatItemViewHolder
|
||||||
mHeaderName = itemView.findViewById(R.id.text_header_name);
|
mHeaderName = itemView.findViewById(R.id.text_header_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(CheatsViewModel viewModel, CheatItem item, int position)
|
public void bind(CheatsActivity activity, CheatItem item, int position)
|
||||||
{
|
{
|
||||||
mHeaderName.setText(item.getString());
|
mHeaderName.setText(item.getString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,6 +395,7 @@
|
||||||
<string name="cheats_add_ar">Add New AR Code</string>
|
<string name="cheats_add_ar">Add New AR Code</string>
|
||||||
<string name="cheats_add_gecko">Add New Gecko Code</string>
|
<string name="cheats_add_gecko">Add New Gecko Code</string>
|
||||||
<string name="cheats_add_patch">Add New Patch</string>
|
<string name="cheats_add_patch">Add New Patch</string>
|
||||||
|
<string name="cheats_download_gecko">Download Gecko Codes</string>
|
||||||
<string name="cheats_name">Name</string>
|
<string name="cheats_name">Name</string>
|
||||||
<string name="cheats_creator">Creator</string>
|
<string name="cheats_creator">Creator</string>
|
||||||
<string name="cheats_notes">Notes</string>
|
<string name="cheats_notes">Notes</string>
|
||||||
|
@ -406,6 +407,10 @@
|
||||||
<string name="cheats_error_no_code_lines">Code can\'t be empty</string>
|
<string name="cheats_error_no_code_lines">Code can\'t be empty</string>
|
||||||
<string name="cheats_error_on_line">Error on line %1$d</string>
|
<string name="cheats_error_on_line">Error on line %1$d</string>
|
||||||
<string name="cheats_error_mixed_encryption">Lines must either be all encrypted or all decrypted</string>
|
<string name="cheats_error_mixed_encryption">Lines must either be all encrypted or all decrypted</string>
|
||||||
|
<string name="cheats_downloading">Downloading...</string>
|
||||||
|
<string name="cheats_download_failed">Failed to download codes.</string>
|
||||||
|
<string name="cheats_download_empty">File contained no codes.</string>
|
||||||
|
<string name="cheats_download_succeeded">Downloaded %1$d codes. (added %2$d)</string>
|
||||||
<string name="cheats_disabled_warning">Dolphin\'s cheat system is currently disabled.</string>
|
<string name="cheats_disabled_warning">Dolphin\'s cheat system is currently disabled.</string>
|
||||||
<string name="cheats_open_settings">Settings</string>
|
<string name="cheats_open_settings">Settings</string>
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,13 @@ Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_getEnabled(JNIEn
|
||||||
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
|
return static_cast<jboolean>(GetPointer(env, obj)->enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_equalsImpl(JNIEnv* env, jobject obj,
|
||||||
|
jobject other)
|
||||||
|
{
|
||||||
|
return *GetPointer(env, obj) == *GetPointer(env, other);
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_trySetImpl(
|
JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_trySetImpl(
|
||||||
JNIEnv* env, jobject obj, jstring name, jstring creator, jstring notes, jstring code_string)
|
JNIEnv* env, jobject obj, jstring name, jstring creator, jstring notes, jstring code_string)
|
||||||
{
|
{
|
||||||
|
@ -180,4 +187,26 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_cheats_model_Geck
|
||||||
Gecko::SaveCodes(game_ini_local, vector);
|
Gecko::SaveCodes(game_ini_local, vector);
|
||||||
game_ini_local.Save(ini_path);
|
game_ini_local.Save(ini_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_cheats_model_GeckoCheat_downloadCodes(JNIEnv* env, jclass,
|
||||||
|
jstring jGameTdbId)
|
||||||
|
{
|
||||||
|
const std::string gametdb_id = GetJString(env, jGameTdbId);
|
||||||
|
|
||||||
|
bool success = true;
|
||||||
|
const std::vector<Gecko::GeckoCode> codes = Gecko::DownloadCodes(gametdb_id, &success, false);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const jobjectArray array =
|
||||||
|
env->NewObjectArray(static_cast<jsize>(codes.size()), IDCache::GetGeckoCheatClass(), nullptr);
|
||||||
|
|
||||||
|
jsize i = 0;
|
||||||
|
for (const Gecko::GeckoCode& code : codes)
|
||||||
|
env->SetObjectArrayElement(array, i++, GeckoCheatToJava(env, code));
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
|
|
||||||
namespace Gecko
|
namespace Gecko
|
||||||
{
|
{
|
||||||
std::vector<GeckoCode> DownloadCodes(std::string gametdb_id, bool* succeeded)
|
std::vector<GeckoCode> DownloadCodes(std::string gametdb_id, bool* succeeded, bool use_https)
|
||||||
{
|
{
|
||||||
|
// TODO: Fix https://bugs.dolphin-emu.org/issues/11772 so we don't need this workaround
|
||||||
|
const std::string protocol = use_https ? "https://" : "http://";
|
||||||
|
|
||||||
// codes.rc24.xyz is a mirror of the now defunct geckocodes.org.
|
// codes.rc24.xyz is a mirror of the now defunct geckocodes.org.
|
||||||
std::string endpoint{"https://codes.rc24.xyz/txt.php?txt=" + gametdb_id};
|
std::string endpoint{protocol + "codes.rc24.xyz/txt.php?txt=" + gametdb_id};
|
||||||
Common::HttpRequest http;
|
Common::HttpRequest http;
|
||||||
|
|
||||||
// The server always redirects once to the same location.
|
// The server always redirects once to the same location.
|
||||||
|
|
|
@ -14,7 +14,8 @@ class IniFile;
|
||||||
namespace Gecko
|
namespace Gecko
|
||||||
{
|
{
|
||||||
std::vector<GeckoCode> LoadCodes(const IniFile& globalIni, const IniFile& localIni);
|
std::vector<GeckoCode> LoadCodes(const IniFile& globalIni, const IniFile& localIni);
|
||||||
std::vector<GeckoCode> DownloadCodes(std::string gametdb_id, bool* succeeded);
|
std::vector<GeckoCode> DownloadCodes(std::string gametdb_id, bool* succeeded,
|
||||||
|
bool use_https = true);
|
||||||
void SaveCodes(IniFile& inifile, const std::vector<GeckoCode>& gcodes);
|
void SaveCodes(IniFile& inifile, const std::vector<GeckoCode>& gcodes);
|
||||||
|
|
||||||
std::optional<GeckoCode::Code> DeserializeLine(const std::string& line);
|
std::optional<GeckoCode::Code> DeserializeLine(const std::string& line);
|
||||||
|
|
Loading…
Reference in New Issue