diff --git a/main/src/main/java/cgeo/geocaching/utils/SystemInformation.java b/main/src/main/java/cgeo/geocaching/utils/SystemInformation.java index c1af8123acc..8ddcded6fcf 100644 --- a/main/src/main/java/cgeo/geocaching/utils/SystemInformation.java +++ b/main/src/main/java/cgeo/geocaching/utils/SystemInformation.java @@ -25,6 +25,9 @@ import cgeo.geocaching.storage.PersistableFolder; import cgeo.geocaching.storage.PersistableUri; import cgeo.geocaching.utils.html.HtmlUtils; +import cgeo.geocaching.wherigo.WherigoGame; +import cgeo.geocaching.wherigo.WherigoSavegameInfo; +import cgeo.geocaching.wherigo.WherigoThingType; import android.app.ActivityManager; import android.content.Context; @@ -42,6 +45,7 @@ import androidx.core.util.Pair; import java.io.File; +import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Locale; @@ -136,6 +140,8 @@ public static String getSystemInformation(@NonNull final Context context) { appendPermissions(context, body); + appendWherigo(body); + body.append("\n") .append("\nPaths") .append("\n-------"); @@ -323,6 +329,24 @@ private static void appendPermissions(final Context context, final StringBuilder } } + private static void appendWherigo(final StringBuilder body) { + final WherigoGame game = WherigoGame.get(); + final ContentStorage.FileInformation cartridgeFileInfo = game.getCartridgeInfo() == null ? null : game.getCartridgeInfo().getFileInfo(); + final CharSequence loadFileInfo = TextUtils.join(WherigoSavegameInfo.getAllSaveFiles(cartridgeFileInfo), sd -> sd.toShortString(), ", "); + final CharSequence visibleThingsCounts = TextUtils.join(Arrays.asList(WherigoThingType.values()), tt -> tt.name() + ":" + tt.getThingsForUserDisplay().size(), ", "); + body.append("\n") + .append("\nWherigo") + .append("\n-------") + .append("\n- playing:").append(game.isPlaying() + ", debug:" + game.isDebugMode() + ", debugFC:" + game.isDebugModeForCartridge()) + .append("\n- Name: " + game.getCartridgeName() + " (" + game.getCGuid() + ")") + .append("\n- Cache context: " + game.getContextGeocacheName()) + .append("\n- Last Error: " + game.getLastError()) + .append("\n- Last Played: " + game.getLastPlayedCGuid() + " / " + game.getLastSetContextGeocode()) + .append("\n- Visible things: " + visibleThingsCounts) + .append("\n- Cartridge File: " + cartridgeFileInfo) + .append("\n- Load Slots: " + loadFileInfo); + } + private static void appendGooglePlayServicesVersion(final Context context, final StringBuilder body) { final boolean googlePlayServicesAvailable = GooglePlayServices.isAvailable(); body.append("\n- Google Play services: ").append(googlePlayServicesAvailable ? (Settings.useGooglePlayServices() ? "enabled" : "disabled") : "unavailable"); diff --git a/main/src/main/java/cgeo/geocaching/wherigo/WherigoCartridgeInfo.java b/main/src/main/java/cgeo/geocaching/wherigo/WherigoCartridgeInfo.java index 6ed87b452a7..58608ad9db6 100644 --- a/main/src/main/java/cgeo/geocaching/wherigo/WherigoCartridgeInfo.java +++ b/main/src/main/java/cgeo/geocaching/wherigo/WherigoCartridgeInfo.java @@ -129,7 +129,7 @@ public String getName() { @NonNull @Override public String toString() { - return "CGuid:" + cguid + "/File:" + fileInfo; + return "CGuid:" + cguid + ", File:[" + fileInfo + "]"; } public static Folder getCartridgeFolder() { diff --git a/main/src/main/java/cgeo/geocaching/wherigo/WherigoErrorDialogProvider.java b/main/src/main/java/cgeo/geocaching/wherigo/WherigoErrorDialogProvider.java index fd69bc86a9e..f8e3ea76ea5 100644 --- a/main/src/main/java/cgeo/geocaching/wherigo/WherigoErrorDialogProvider.java +++ b/main/src/main/java/cgeo/geocaching/wherigo/WherigoErrorDialogProvider.java @@ -15,15 +15,22 @@ public class WherigoErrorDialogProvider implements IWherigoDialogProvider { public Dialog createAndShowDialog(final Activity activity, final IWherigoDialogControl dialogControl) { final String lastError = WherigoGame.get().getLastError(); - final String errorMessage = lastError == null ? LocalizationUtils.getString(R.string.wherigo_error_game_noerror) : LocalizationUtils.getString(R.string.wherigo_error_game_error, lastError); + final String errorMessage = lastError == null ? LocalizationUtils.getString(R.string.wherigo_error_game_noerror) : + (LocalizationUtils.getString(R.string.wherigo_error_game_error, lastError) + + "\n\n" + LocalizationUtils.getString(R.string.wherigo_error_game_error_addinfo)); + final String errorMessageEmail = lastError == null ? LocalizationUtils.getString(R.string.wherigo_error_game_noerror) : LocalizationUtils.getString(R.string.wherigo_error_game_error, lastError); + final SimpleDialog dialog = SimpleDialog.of(activity) .setTitle(TextParam.id(R.string.wherigo_error_title)) .setMessage(TextParam.text(errorMessage)) - .setPositiveButton(TextParam.id(R.string.about_system_info_send_button)); + .setPositiveButton(TextParam.id(R.string.about_system_info_send_button)) + .setNegativeButton(TextParam.id(R.string.close)); - dialog.input(null, text -> { - final String emailMessage = LocalizationUtils.getString(R.string.wherigo_error_email, errorMessage, String.valueOf(WherigoGame.get()), text); + dialog.confirm(() -> { + final String emailMessage = LocalizationUtils.getString(R.string.wherigo_error_email, + errorMessageEmail, + WherigoGame.get().getCartridgeName() + " (" + WherigoGame.get().getCGuid() + ")ยด"); DebugUtils.createLogcatHelper(activity, false, true, emailMessage); }); diff --git a/main/src/main/java/cgeo/geocaching/wherigo/WherigoGame.java b/main/src/main/java/cgeo/geocaching/wherigo/WherigoGame.java index 97c8479dbde..eb5bb7fee0f 100644 --- a/main/src/main/java/cgeo/geocaching/wherigo/WherigoGame.java +++ b/main/src/main/java/cgeo/geocaching/wherigo/WherigoGame.java @@ -31,9 +31,12 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; @@ -55,6 +58,11 @@ public class WherigoGame implements UI { private static final String LOG_PRAEFIX = "WHERIGOGAME: "; + private static final Set OPENWIG_ENGINE_ERROR_PREFIXES = new HashSet<>(Arrays.asList( + "You hit a bug! Please report this to whereyougo@cgeo.org with a screenshot of this message.".toLowerCase(Locale.ROOT), + "You hit a bug! please report at openwig.googlecode.com and i'll fix it for you!".toLowerCase(Locale.ROOT) + )); + public static final GeopointConverter GP_CONVERTER = new GeopointConverter<>( gc -> new ZonePoint(gc.getLatitude(), gc.getLongitude(), 0), ll -> new Geopoint(ll.latitude, ll.longitude) @@ -65,9 +73,8 @@ public enum NotifyType { } //filled overall (independent from current game) - private String contextGeocode; - private String contextGeocacheName; private String lastPlayedCGuid; + private String lastSetContextGeocode; //filled on new/loadGame private CartridgeFile cartridgeFile; @@ -76,6 +83,8 @@ public enum NotifyType { private File cartridgeCacheDir; private HtmlImage htmlImageGetter; private String lastError; + private String contextGeocode; + private String contextGeocacheName; //filled on game start private boolean isPlaying = false; @@ -131,16 +140,21 @@ public void loadGame(@NonNull final ContentStorage.FileInformation cartridgeFile final boolean loadGame = saveGame != null && saveGame.isExistingSavefile(); if (loadGame) { WherigoSaveFileHandler.get().initLoad(saveGame); - if (saveGame.geocode != null) { - setContextGeocode(saveGame.geocode); - } } + this.cartridgeFile = WherigoUtils.readCartridge(cartridgeFileInfo.uri); this.cartridgeInfo = new WherigoCartridgeInfo(cartridgeFileInfo, true, false); setCGuidAndDependentThings(this.cartridgeInfo.getCGuid()); this.lastError = null; - this.lastPlayedCGuid = getCGuid(); + //try to restore context geocache + if (loadGame && saveGame.geocode != null) { + setContextGeocode(saveGame.geocode); + } else if (Objects.equals(lastPlayedCGuid, getCGuid()) && this.lastSetContextGeocode != null) { + setContextGeocode(this.lastSetContextGeocode); + } + + this.lastPlayedCGuid = getCGuid(); final Engine engine = Engine.newInstance(this.cartridgeFile, null, this, WherigoLocationProvider.get()); if (loadGame) { @@ -235,7 +249,11 @@ public List getItems() { WherigoUtils.getListFromContainer(cartridge.currentThings(), Thing.class, null); } + @Nullable public Player getPlayer() { + if (!isPlaying()) { + return null; + } return Engine.instance.player; } @@ -254,6 +272,11 @@ public String getLastPlayedCGuid() { return lastPlayedCGuid; } + @Nullable + public String getLastSetContextGeocode() { + return lastSetContextGeocode; + } + public void notifyListeners(final NotifyType type) { final Collection> listenerCopy; synchronized (listeners) { @@ -268,9 +291,14 @@ public void notifyListeners(final NotifyType type) { } public void setContextGeocode(final String geocode) { + setContextGeocodeInternal(geocode); + this.lastSetContextGeocode = geocode; + notifyListeners(NotifyType.REFRESH); + } + + private void setContextGeocodeInternal(final String geocode) { this.contextGeocode = geocode; this.contextGeocacheName = WherigoUtils.findGeocacheNameForGeocode(geocode); - notifyListeners(NotifyType.REFRESH); } private void runOnUi(final Runnable r) { @@ -313,12 +341,24 @@ private void freeResources() { setCGuidAndDependentThings(null); WherigoGameService.stopService(); WherigoLocationProvider.get().disconnect(); + setContextGeocodeInternal(null); } @Override - public void showError(final String s) { - Log.w(LOG_PRAEFIX + "ERROR: " + s); - this.lastError = s; + public void showError(final String errorMessage) { + Log.w(LOG_PRAEFIX + "ERROR: " + errorMessage); + + if (errorMessage != null) { + //Remove common prefixed + String errorMsg = errorMessage; + for (String commonPrefix : OPENWIG_ENGINE_ERROR_PREFIXES) { + if (errorMsg.toLowerCase(Locale.ROOT).startsWith(commonPrefix)) { + errorMsg = "OpenWIG error: " + errorMsg.substring(commonPrefix.length()); + break; + } + } + this.lastError = errorMsg; + } WherigoDialogManager.get().display(new WherigoErrorDialogProvider()); } @@ -451,6 +491,6 @@ public boolean isDebugMode() { @NonNull @Override public String toString() { - return "Playing:" + isPlaying + " / name:" + getCartridgeName() + " / Details:" + cartridgeInfo; + return "isPlaying:" + isPlaying + ", name:" + getCartridgeName() + ", cguid:" + getCGuid() + ", context: " + getContextGeocacheName(); } } diff --git a/main/src/main/java/cgeo/geocaching/wherigo/WherigoSavegameInfo.java b/main/src/main/java/cgeo/geocaching/wherigo/WherigoSavegameInfo.java index 44053cb34d6..e7134f80fb2 100644 --- a/main/src/main/java/cgeo/geocaching/wherigo/WherigoSavegameInfo.java +++ b/main/src/main/java/cgeo/geocaching/wherigo/WherigoSavegameInfo.java @@ -134,6 +134,12 @@ public static List getLoadableSavegames(final ContentStorag return list; } + public static List getAllSaveFiles(final ContentStorage.FileInformation cartridgeFileInfo) { + final List list = new ArrayList<>(getAvailableSaveFiles(cartridgeFileInfo)); + list.sort(WherigoSavegameInfo.DEFAULT_COMPARATOR); + return list; + } + public static List getSavegameSlots(final ContentStorage.FileInformation cartridgeFileInfo) { final int[] maxExistingSlot = new int[] {0}; final List list = getAvailableSaveFiles(cartridgeFileInfo).stream() @@ -238,10 +244,14 @@ public String getUserDisplayableSaveDate() { return Formatter.formatDateTime(saveDate.getTime()); } + public String toShortString() { + return nameId + "-" + nameCustom + ":" + (saveDate == null ? "-" : Formatter.formatShortDateTime(saveDate.getTime())); + } + @NonNull @Override public String toString() { - return "Savegame: " + nameId + "-" + nameCustom + "/File:" + fileInfo; + return "Savegame:" + nameId + "-" + nameCustom + "/File:" + fileInfo; } } diff --git a/main/src/main/res/layout/simple_dialog_title_view.xml b/main/src/main/res/layout/simple_dialog_title_view.xml index 3ba89216762..956b81cdcae 100644 --- a/main/src/main/res/layout/simple_dialog_title_view.xml +++ b/main/src/main/res/layout/simple_dialog_title_view.xml @@ -9,6 +9,7 @@ android:id="@+id/dialog_title" style="?android:attr/windowTitleStyle" android:layout_alignParentLeft="true" + android:textIsSelectable="true" android:layout_toLeftOf="@id/dialog_search_icon" android:layout_width="wrap_content" android:layout_height="wrap_content" diff --git a/main/src/main/res/layout/simple_dialog_view.xml b/main/src/main/res/layout/simple_dialog_view.xml index 7b17504abfc..d640a55f8d4 100644 --- a/main/src/main/res/layout/simple_dialog_view.xml +++ b/main/src/main/res/layout/simple_dialog_view.xml @@ -13,6 +13,7 @@ style="@style/TextAppearance.AppCompat.Subhead" android:layout_width="match_parent" android:layout_height="wrap_content" + android:textIsSelectable="true" android:paddingHorizontal="24dp" android:paddingTop="10dp" android:paddingBottom="5dp" /> diff --git a/main/src/main/res/layout/wherigo_cartridge_details.xml b/main/src/main/res/layout/wherigo_cartridge_details.xml index 4a54f8ff50e..23bad159430 100644 --- a/main/src/main/res/layout/wherigo_cartridge_details.xml +++ b/main/src/main/res/layout/wherigo_cartridge_details.xml @@ -18,6 +18,7 @@ diff --git a/main/src/main/res/layout/wherigo_thing_details.xml b/main/src/main/res/layout/wherigo_thing_details.xml index 28951c1b49d..15e67792315 100644 --- a/main/src/main/res/layout/wherigo_thing_details.xml +++ b/main/src/main/res/layout/wherigo_thing_details.xml @@ -19,6 +19,7 @@ android:id="@+id/headerInformation" android:textSize="@dimen/textSize_headingSecondary" android:visibility="gone" + android:textIsSelectable="true" android:layout_width="fill_parent" android:layout_height="wrap_content" /> diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml index 356636078f4..0bcdde495e7 100644 --- a/main/src/main/res/values/strings.xml +++ b/main/src/main/res/values/strings.xml @@ -2954,10 +2954,11 @@ Download started Downloaded %1$s / %2$s (%3$s %%) - Wherigo Error - No error reported by game - Error reported by game: %1$s - Problem playing a Wherigo\n\nError: %1$s\n\nWherigo Info: %2$s\n\nAdditional Info: %3$s + Wherigo Problem report + No error reported by Wherigo Engine + Error in Wherigo Engine: %1$s + You may try to continue your running game despite of this error.\n\nIf possible, please report the error to our support team via e-mail. + Wherigo Problem report\n\nError: %1$s\n\nWherigo Info: %2$s Stop running Wherigo Game A game is currently running for \"%s\". Do you want to stop this game? diff --git a/main/src/main/res/values/styles.xml b/main/src/main/res/values/styles.xml index 989b7701aef..073ddbd525c 100644 --- a/main/src/main/res/values/styles.xml +++ b/main/src/main/res/values/styles.xml @@ -6,6 +6,7 @@