, InventoryItemFro
collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER;
// If the user changes the language this will make cards sort by the old language until they restart the game.
// This is a good tradeoff
- sortableName = InventoryItem.toSortableName(CardTranslation.getTranslatedName(rules0.getName()));
+ sortableName = TextUtil.toSortableName(CardTranslation.getTranslatedName(rules0.getName()));
}
// Want this class to be a key for HashTable
diff --git a/forge-core/src/main/java/forge/util/TextUtil.java b/forge-core/src/main/java/forge/util/TextUtil.java
index 3ae45c32e70..9496391736a 100644
--- a/forge-core/src/main/java/forge/util/TextUtil.java
+++ b/forge-core/src/main/java/forge/util/TextUtil.java
@@ -313,4 +313,51 @@ public class TextUtil {
return "mana";//fix manamorphose stack description and probably others..
return "{"+TextUtil.fastReplace(ManaProduced," ","}{")+"}";
}
+
+ /**
+ * Converts a card name to a sortable name.
+ * Trim leading quotes, then move article last, then replace characters.
+ * Because An-Havva Constable.
+ * Capitals and lowercase sorted as one: "my deck" before "Myr Retribution"
+ * Apostrophes matter, though: "D'Avenant" before "Danitha"
+ * TO DO: Commas before apostrophes: "Rakdos, Lord of Riots" before "Rakdos's Return"
+ *
+ * @param printedName The name of the card.
+ * @return A sortable name.
+ */
+ public static String toSortableName(String printedName) {
+ if (printedName.startsWith("\"")) printedName = printedName.substring(1);
+ return moveArticleToEnd(printedName).toLowerCase().replaceAll("[^\\s'0-9a-z]", "");
+ }
+
+
+ /**
+ * Article words. These words get kicked to the end of a sortable name.
+ * For localization, simply overwrite this array with appropriate words.
+ * Words in this list are used by the method String moveArticleToEnd(String), useful
+ * for alphabetizing phrases, in particular card or other inventory object names.
+ */
+ public static final String[] ARTICLE_WORDS = {
+ "A",
+ "An",
+ "The"
+ };
+
+ /**
+ * Detects whether a string begins with an article word
+ *
+ * @param str The name of the card.
+ * @return The sort-friendly name of the card. Example: "The Hive" becomes "Hive The".
+ */
+ public static String moveArticleToEnd(String str) {
+ String articleWord;
+ for (int i = 0; i < ARTICLE_WORDS.length; i++) {
+ articleWord = ARTICLE_WORDS[i];
+ if (str.startsWith(articleWord + " ")) {
+ str = str.substring(articleWord.length() + 1) + " " + articleWord;
+ return str;
+ }
+ }
+ return str;
+ }
}
diff --git a/forge-game/pom.xml b/forge-game/pom.xml
index 002607cd494..fd7c0627952 100644
--- a/forge-game/pom.xml
+++ b/forge-game/pom.xml
@@ -26,14 +26,14 @@
junit
junit
- 4.10
+ 4.13.2
test
jar
io.sentry
sentry-logback
- 1.7.30
+ 5.7.0
diff --git a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
index b2359829155..837963f5f7f 100644
--- a/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
+++ b/forge-game/src/main/java/forge/game/ability/AbilityFactory.java
@@ -35,8 +35,8 @@ import forge.game.cost.Cost;
import forge.game.spellability.*;
import forge.game.zone.ZoneType;
import forge.util.FileSection;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
/**
*
@@ -145,10 +145,12 @@ public final class AbilityFactory {
return getAbility(mapParams, type, state, sVarHolder);
} catch (Error | Exception ex) {
String msg = "AbilityFactory:getAbility: crash when trying to create ability ";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", state.getName()).withData("Ability", abString).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", state.getName());
+ bread.setData("Ability", abString);
+
+ Sentry.addBreadcrumb(bread);
throw new RuntimeException(msg + " of card: " + state.getName(), ex);
}
}
diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java
index 6a8bf99c4de..1ba0172c7a3 100644
--- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java
+++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java
@@ -73,8 +73,8 @@ import forge.util.MyRandom;
import forge.util.TextUtil;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public class AbilityUtils {
@@ -1428,11 +1428,11 @@ public class AbilityUtils {
final Card card = sa.getHostCard();
String msg = "AbilityUtils:resolveApiAbility: try to resolve API ability";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Api", sa.getApi().toString())
- .withData("Card", card.getName()).withData("SA", sa.toString()).build()
- );
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Api", sa.getApi().toString());
+ bread.setData("Card", card.getName());
+ bread.setData("SA", sa.toString());
+ Sentry.addBreadcrumb(bread);
// check conditions
if (sa.metConditions()) {
diff --git a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java
index 9c74ce0685b..59ff6322391 100644
--- a/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java
+++ b/forge-game/src/main/java/forge/game/ability/effects/ManaEffect.java
@@ -23,8 +23,8 @@ import forge.game.spellability.AbilityManaPart;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public class ManaEffect extends SpellAbilityEffect {
@@ -231,10 +231,12 @@ public class ManaEffect extends SpellAbilityEffect {
// this can happen when mana is based on criteria that didn't match
if (mana.isEmpty()) {
String msg = "AbilityFactoryMana::manaResolve() - special mana effect is empty for";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", card.getName()).withData("SA", sa.toString()).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", card.getName());
+ bread.setData("SA", sa.toString());
+ Sentry.addBreadcrumb(bread, sa);
+
continue;
}
diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java
index 8e30e5b32c5..af11ed05d38 100644
--- a/forge-game/src/main/java/forge/game/card/Card.java
+++ b/forge-game/src/main/java/forge/game/card/Card.java
@@ -70,8 +70,8 @@ import forge.trackable.Tracker;
import forge.util.*;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.tuple.Pair;
@@ -2183,10 +2183,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars {
}
} catch (Exception e) {
String msg = "Card:keywordToText: crash in Keyword parsing";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", this.getName()).withData("Keyword", keyword).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", this.getName());
+ bread.setData("Keyword", keyword);
+ Sentry.addBreadcrumb(bread, this);
throw new RuntimeException("Error in Card " + this.getName() + " with Keyword " + keyword, e);
}
@@ -2672,10 +2673,11 @@ public class Card extends GameEntity implements Comparable, IHasSVars {
}
} catch (Exception e) {
String msg = "Card:abilityTextInstantSorcery: crash in Keyword parsing";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", this.getName()).withData("Keyword", keyword).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", this.getName());
+ bread.setData("Keyword", keyword);
+ Sentry.addBreadcrumb(bread, this);
throw new RuntimeException("Error in Card " + this.getName() + " with Keyword " + keyword, e);
}
diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
index feb2f18455b..e3bc93829a9 100644
--- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
+++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
@@ -74,8 +74,8 @@ import forge.game.trigger.TriggerHandler;
import forge.game.zone.ZoneType;
import forge.util.Lang;
import forge.util.TextUtil;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
/**
*
@@ -599,10 +599,11 @@ public class CardFactoryUtil {
intrinsicAbility.setCardState(card.getCurrentState());
} catch (Exception e) {
String msg = "CardFactoryUtil:addAbilityFactoryAbilities: crash in raw Ability";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", card.getName()).withData("Ability", rawAbility).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", card.getName());
+ bread.setData("Ability", rawAbility);
+ Sentry.addBreadcrumb(bread, card);
// rethrow the exception with card Name for the user
throw new RuntimeException("crash in raw Ability, check card script of " + card.getName(), e);
diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java
index 6d267fca627..e52678f1c93 100644
--- a/forge-game/src/main/java/forge/game/card/CardState.java
+++ b/forge-game/src/main/java/forge/game/card/CardState.java
@@ -50,8 +50,8 @@ import forge.game.staticability.StaticAbility;
import forge.game.trigger.Trigger;
import forge.util.collect.FCollection;
import forge.util.collect.FCollectionView;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public class CardState extends GameObject implements IHasSVars {
private String name = "";
@@ -270,10 +270,11 @@ public class CardState extends GameObject implements IHasSVars {
inst = intrinsicKeywords.add(s);
} catch (Exception e) {
String msg = "CardState:addIntrinsicKeyword: failed to parse Keyword";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", card.getName()).withData("Keyword", s).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", card.getName());
+ bread.setData("Keyword", s);
+ Sentry.addBreadcrumb(bread, this);
//rethrow
throw new RuntimeException("Error in Keyword " + s + " for card " + card.getName(), e);
diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java
index f4187a6a66a..50641285999 100644
--- a/forge-game/src/main/java/forge/game/card/CardUtil.java
+++ b/forge-game/src/main/java/forge/game/card/CardUtil.java
@@ -46,8 +46,8 @@ import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.TextUtil;
import forge.util.collect.FCollection;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public final class CardUtil {
// disable instantiation
@@ -190,13 +190,12 @@ public final class CardUtil {
return cachedCard;
}
String msg = "CardUtil:getLKICopy copy object";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", in.getName())
- .withData("CardState", in.getCurrentStateName().toString())
- .withData("Player", in.getController().getName())
- .build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", in.getName());
+ bread.setData("CardState", in.getCurrentStateName().toString());
+ bread.setData("Player", in.getController().getName());
+ Sentry.addBreadcrumb(bread, in);
final Card newCopy = new Card(in.getId(), in.getPaperCard(), in.getGame(), null);
cachedMap.put(in.getId(), newCopy);
diff --git a/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java b/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java
index b3b20f2740d..1696cb7b20b 100644
--- a/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java
+++ b/forge-game/src/main/java/forge/game/keyword/KeywordInstance.java
@@ -16,8 +16,8 @@ import forge.game.spellability.SpellAbility;
import forge.game.staticability.StaticAbility;
import forge.game.trigger.Trigger;
import forge.util.Lang;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public abstract class KeywordInstance> implements KeywordInterface {
private Keyword keyword;
@@ -95,14 +95,15 @@ public abstract class KeywordInstance> implements K
try {
String msg = "KeywordInstance:createTraits: make Traits for Keyword";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", host.getName()).withData("Keyword", this.original).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", host.getName());
+ bread.setData("Keyword", this.original);
+ Sentry.addBreadcrumb(bread, this);
// add Extra for debugging
- Sentry.getContext().addExtra("Card", host);
- Sentry.getContext().addExtra("Keyword", this.original);
+ Sentry.setExtra("Card", host.getName());
+ Sentry.setExtra("Keyword", this.original);
CardFactoryUtil.addTriggerAbility(this, host, intrinsic);
CardFactoryUtil.addReplacementEffect(this, host.getCurrentState(), intrinsic);
@@ -110,16 +111,18 @@ public abstract class KeywordInstance> implements K
CardFactoryUtil.addStaticAbility(this, host.getCurrentState(), intrinsic);
} catch (Exception e) {
String msg = "KeywordInstance:createTraits: failed Traits for Keyword";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", host.getName()).withData("Keyword", this.original).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", host.getName());
+ bread.setData("Keyword", this.original);
+ Sentry.addBreadcrumb(bread, this);
+
//rethrow
throw new RuntimeException("Error in Keyword " + this.original + " for card " + host.getName(), e);
} finally {
// remove added extra
- Sentry.getContext().removeExtra("Card");
- Sentry.getContext().removeExtra("Keyword");
+ Sentry.removeExtra("Card");
+ Sentry.removeExtra("Keyword");
}
}
@@ -143,14 +146,15 @@ public abstract class KeywordInstance> implements K
}
try {
String msg = "KeywordInstance:createTraits: make Traits for Keyword";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Player", player.getName()).withData("Keyword", this.original).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Player", player.getName());
+ bread.setData("Keyword", this.original);
+ Sentry.addBreadcrumb(bread, this);
// add Extra for debugging
- Sentry.getContext().addExtra("Player", player);
- Sentry.getContext().addExtra("Keyword", this.original);
+ Sentry.setExtra("Player", player.getName());
+ Sentry.setExtra("Keyword", this.original);
PlayerFactoryUtil.addTriggerAbility(this, player);
PlayerFactoryUtil.addReplacementEffect(this, player);
@@ -158,16 +162,18 @@ public abstract class KeywordInstance> implements K
PlayerFactoryUtil.addStaticAbility(this, player);
} catch (Exception e) {
String msg = "KeywordInstance:createTraits: failed Traits for Keyword";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Player", player.getName()).withData("Keyword", this.original).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Player", player.getName());
+ bread.setData("Keyword", this.original);
+ Sentry.addBreadcrumb(bread, this);
+
//rethrow
throw new RuntimeException("Error in Keyword " + this.original + " for player " + player.getName(), e);
} finally {
// remove added extra
- Sentry.getContext().removeExtra("Player");
- Sentry.getContext().removeExtra("Keyword");
+ Sentry.removeExtra("Player");
+ Sentry.removeExtra("Keyword");
}
}
/*
diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java
index 3187ab21a96..bc1c8c3acd6 100644
--- a/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java
+++ b/forge-game/src/main/java/forge/game/trigger/TriggerHandler.java
@@ -40,8 +40,8 @@ import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.FileSection;
import forge.util.Visitor;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
public class TriggerHandler {
private final Set suppressedModes = Collections.synchronizedSet(EnumSet.noneOf(TriggerType.class));
@@ -127,10 +127,12 @@ public class TriggerHandler {
return TriggerHandler.parseTrigger(mapParams, host, intrinsic, sVarHolder);
} catch (Exception e) {
String msg = "TriggerHandler:parseTrigger failed to parse";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", host.getName()).withData("Trigger", trigParse).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", host.getName());
+ bread.setData("Trigger", trigParse);
+ Sentry.addBreadcrumb(bread, host);
+
//rethrow
throw new RuntimeException("Error in Trigger for Card: " + host.getName(), e);
}
@@ -153,10 +155,12 @@ public class TriggerHandler {
}
} catch (Exception e) {
String msg = "TriggerHandler:parseTrigger failed to parse";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(msg)
- .withData("Card", host.getName()).withData("Params", mapParams.toString()).build()
- );
+
+ Breadcrumb bread = new Breadcrumb(msg);
+ bread.setData("Card", host.getName());
+ bread.setData("Params", mapParams.toString());
+ Sentry.addBreadcrumb(bread, host);
+
//rethrow
throw new RuntimeException("Error in Trigger for Card: " + host.getName(), e);
}
diff --git a/forge-gui-android/AndroidManifest.xml b/forge-gui-android/AndroidManifest.xml
index 92fc4afcdcb..8237552827d 100644
--- a/forge-gui-android/AndroidManifest.xml
+++ b/forge-gui-android/AndroidManifest.xml
@@ -2,7 +2,7 @@
+ android:versionName="1.6.49" >
+
+
+
+
+
diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml
index 695751741a4..c3a8a838850 100644
--- a/forge-gui-android/pom.xml
+++ b/forge-gui-android/pom.xml
@@ -6,7 +6,7 @@
jar
-Xms1024m
-Xmx1536m
- 1.6.47.001
+ 1.6.49.001
keystore
alias
storepass
@@ -45,7 +45,6 @@
forge-android-${alpha-version}
-
com.google.android
@@ -104,7 +103,69 @@
io.sentry
sentry-android
- 1.7.30
+ 5.7.0
+ aar
+
+
+ io.sentry
+ sentry-android-core
+
+
+ io.sentry
+ sentry-android-ndk
+
+
+
+
+
+ io.sentry
+ sentry-android-core
+ 5.7.0
+ aar
+
+
+ androidx.lifecycle
+ lifecycle-process
+
+
+ androidx.lifecycle
+ lifecycle-common-java8
+
+
+ androidx.core
+ core
+
+
+
+
+ io.sentry
+ sentry-android-ndk
+ 5.7.0
+ aar
+
+
+ io.sentry
+ sentry-android-core
+
+
+ androidx.lifecycle
+ lifecycle-process
+
+
+ androidx.lifecycle
+ lifecycle-common-java8
+
+
+ androidx.core
+ core
+
+
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.5
@@ -119,7 +180,19 @@
com.simpligility.maven.plugins
android-maven-plugin
- 4.2.1
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
+
+ net.sf.proguard
+ proguard-base
+ 6.2.2
+
+
+ 4.6.0
true
@@ -139,11 +212,21 @@
${project.basedir}/proguard.cfg
true
-
+ d8
+
+ 26
${build.min.memory}
${build.max.memory}
+
+
+ true
+
+ ${build.min.memory}
+ ${build.max.memory}
+
+ --min-sdk-version=26
@@ -160,7 +243,19 @@
com.simpligility.maven.plugins
android-maven-plugin
- 4.2.1
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
+
+ net.sf.proguard
+ proguard-base
+ 6.2.2
+
+
+ 4.6.0
true
@@ -183,11 +278,21 @@
${project.basedir}/proguard.cfg
true
-
+ d8
+
+ 26
${build.min.memory}
${build.max.memory}
+
+
+ true
+
+ ${build.min.memory}
+ ${build.max.memory}
+
+ --min-sdk-version=26
@@ -238,7 +343,19 @@
com.simpligility.maven.plugins
android-maven-plugin
- 4.2.1
+
+
+ javax.xml.bind
+ jaxb-api
+ 2.3.1
+
+
+ net.sf.proguard
+ proguard-base
+ 6.2.2
+
+
+ 4.6.0
true
diff --git a/forge-gui-android/proguard.cfg b/forge-gui-android/proguard.cfg
index b5365a37c33..5b4a814d1f6 100644
--- a/forge-gui-android/proguard.cfg
+++ b/forge-gui-android/proguard.cfg
@@ -6,9 +6,13 @@
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable
+-android
+
## Uncomment the line below and set it to the location of rt.jar in JDK if the Proguard step fails to find the libraries
## and spits out a thousand-something Class Not Found errors
##-libraryjars /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar
+##-libraryjars /jmods/java.base.jmod(!**.jar;!module-info.class)
+##-libraryjars /jmods/jdk.xml.dom.jmod(!**.jar;!module-info.class)
-dontwarn afu.org.checkerframework.**
-dontwarn io.netty.**
@@ -16,32 +20,55 @@
-dontwarn com.thoughtworks.xstream.**
-dontwarn com.badlogic.gdx.**
-dontwarn org.apache.commons.**
+-dontwarn org.apache.http.**
-dontwarn com.google.guava.**
-dontwarn com.google.common.**
+-dontwarn com.google.gson.**
-dontwarn org.checkerframework.**
-dontwarn org.xmlpull.**
-dontwarn org.apache.log4j.**
-dontwarn org.fourthline.cling.**
-dontwarn org.seamless.http.**
+-dontwarn org.seamless.xhtml.**
+-dontwarn org.seamless.xml.**
-dontwarn org.seamless.util.**
-dontwarn org.seamless.swing.**
-dontwarn java.lang.management.**
-dontwarn java.awt.**
-dontwarn java.util.**
-dontwarn java.lang.**
+-dontwarn java.net.**
+-dontwarn java.nio.**
+-dontwarn java.io.**
-dontwarn org.slf4j.**
+-dontwarn ch.qos.logback.**
-dontwarn javax.**
-dontwarn org.apache.logging.log4j.**
-dontwarn module-info
+-dontwarn io.sentry.logback.*
+-dontwarn io.sentry.**
+-dontwarn net.jpountz.**
## Support library
--dontwarn android.support.**
+-dontwarn android.**
+-dontwarn androidx.**
+
+-dontwarn forge.**
-keep class forge.** { *; }
-keep class com.thoughtworks.xstream.** { *; }
-keep class org.apache.commons.lang3.** { *; }
-keep class com.google.guava.** { *; }
-keep class com.google.common.** { *; }
+-keep class com.google.gson.GsonBuilder
-keep class io.sentry.event.Event { *; }
+-keep class io.sentry.android.core.SentryAndroidOptions
+-keep class io.sentry.android.core.SentryAndroid
+
+-keep class io.sentry.android.core.SentryInitProvider
+-keep class io.sentry.android.core.SentryPerformanceProvider
+
+-keep class io.sentry.android.ndk.SentryNdk
+-keep class io.sentry.Sentry
-keep class io.netty.util.internal.logging.** { *; }
-keep class net.jpountz.** { *; }
-keep class com.ray3k.** { *; }
diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java
index 7a47506f544..d21b6f3d725 100644
--- a/forge-gui-android/src/forge/app/Main.java
+++ b/forge-gui-android/src/forge/app/Main.java
@@ -53,9 +53,9 @@ import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
import forge.util.FileUtil;
import forge.util.ThreadUtil;
+import io.sentry.Breadcrumb;
import io.sentry.Sentry;
-import io.sentry.android.AndroidSentryClientFactory;
-import io.sentry.event.BreadcrumbBuilder;
+//import io.sentry.android.core.SentryAndroid;
public class Main extends AndroidApplication {
AndroidAdapter Gadapter;
@@ -63,10 +63,10 @@ public class Main extends AndroidApplication {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- Context ctx = this.getApplicationContext();
- String sentryDsn = "https://a0b8dbad9b8a49cfa51bf65d462e8dae:b3f27d7461224cb8836eb5c6050c666c@sentry.cardforge.org/2?buffer.enabled=false";
+
//init Sentry
- Sentry.init(sentryDsn, new AndroidSentryClientFactory(ctx));
+ //SentryAndroid.init(this);
+
//get total device RAM in mb
ActivityManager actManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo memInfo = new ActivityManager.MemoryInfo();
@@ -217,9 +217,7 @@ public class Main extends AndroidApplication {
//fake init for error message
//set current orientation
String message = getDeviceName()+"\n"+"Android "+AndroidRelease+"\n"+"RAM "+ totalRAM+"MB" +"\n"+"LibGDX "+ Version.VERSION+"\n"+"Can't access external storage";
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(message).build()
- );
+ Sentry.addBreadcrumb(new Breadcrumb(message));
Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation);
initialize(Forge.getApp(new AndroidClipboard(), adapter, "", false, true, totalRAM, isTabletDevice, AndroidAPI, AndroidRelease, getDeviceName()));
displayMessage(adapter, true, message);
@@ -232,9 +230,7 @@ public class Main extends AndroidApplication {
//fake init for error message
//set current orientation
String message = getDeviceName()+"\n"+"Android "+AndroidRelease+"\n"+"RAM "+ totalRAM+"MB" +"\n"+"LibGDX "+ Version.VERSION+"\n"+"Can't access external storage\nPath: " + assetsDir;
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(message).build()
- );
+ Sentry.addBreadcrumb(new Breadcrumb(message));
Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation);
initialize(Forge.getApp(new AndroidClipboard(), adapter, "", false, true, totalRAM, isTabletDevice, AndroidAPI, AndroidRelease, getDeviceName()));
displayMessage(adapter, true, message);
diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml
index 8ba58c34c3a..2bce22e23c4 100644
--- a/forge-gui-desktop/pom.xml
+++ b/forge-gui-desktop/pom.xml
@@ -139,12 +139,6 @@
java-image-scaling
0.8.5
-
- org.testng
- testng
- 6.9.10
- test
-
org.powermock
powermock-module-testng-common
@@ -184,30 +178,30 @@
org.mockito
mockito-core
- 3.3.3
+ 3.12.4
test
net.bytebuddy
byte-buddy
- 1.10.5
+ 1.12.3
net.bytebuddy
byte-buddy-agent
- 1.10.5
+ 1.12.3
test
org.objenesis
objenesis
- 2.6
+ 3.2
test
org.freemarker
freemarker
- 2.3.20
+ 2.3.31
com.googlecode.soundlibs
@@ -240,7 +234,7 @@
com.akathist.maven.plugins.launch4j
launch4j-maven-plugin
- 1.7.25
+ 2.1.2
l4j-gui
@@ -405,7 +399,7 @@
com.akathist.maven.plugins.launch4j
launch4j-maven-plugin
- 1.7.25
+ 2.1.2
l4j-gui
diff --git a/forge-gui-desktop/src/main/java/forge/view/Main.java b/forge-gui-desktop/src/main/java/forge/view/Main.java
index 0a9fb687588..2f6824ff4ea 100644
--- a/forge-gui-desktop/src/main/java/forge/view/Main.java
+++ b/forge-gui-desktop/src/main/java/forge/view/Main.java
@@ -24,7 +24,6 @@ import forge.gui.GuiBase;
import forge.gui.card.CardReaderExperiments;
import forge.util.BuildInfo;
import io.sentry.Sentry;
-import io.sentry.SentryClient;
/**
* Main class for Forge's swing application view.
@@ -34,11 +33,13 @@ public final class Main {
* Main entry point for Forge
*/
public static void main(final String[] args) {
- Sentry.init();
- SentryClient sentryClient = Sentry.getStoredClient();
- sentryClient.setRelease(BuildInfo.getVersionString());
- sentryClient.setEnvironment(System.getProperty("os.name"));
- sentryClient.addTag("Java Version", System.getProperty("java.version"));
+
+ Sentry.init(options -> {
+ options.setEnableExternalConfiguration(true);
+ options.setRelease(BuildInfo.getVersionString());
+ options.setEnvironment(System.getProperty("os.name"));
+ options.setTag("Java Version", System.getProperty("java.version"));
+ }, true);
// HACK - temporary solution to "Comparison method violates it's general contract!" crash
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
diff --git a/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java b/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java
index 14fb057c191..c73da4db0a0 100644
--- a/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java
+++ b/forge-gui-desktop/src/test/java/forge/card/ForgeCardMockTestCase.java
@@ -14,6 +14,7 @@ import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.powermock.modules.testng.PowerMockTestCase;
@@ -33,6 +34,7 @@ import java.util.ResourceBundle;
ImageCache.class, ImageIO.class, ImageKeys.class,
ForgeConstants.class, Localizer.class})
@SuppressStaticInitializationFor({"forge.ImageCache", "forge.localinstance.properties.ForgeConstants"})
+@PowerMockIgnore({"javax.xml.*", "org.xml.sax.*", "com.sun.org.apache.xerces.*", "org.w3c.dom.*", "org.springframework.context.*", "org.apache.log4j.*"})
public class ForgeCardMockTestCase extends PowerMockTestCase {
public static final String MOCKED_LOCALISED_STRING = "any localised string";
diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/BaseGameSimulationTest.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/BaseGameSimulationTest.java
index eb4e64ccf23..50c85a362ea 100644
--- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/BaseGameSimulationTest.java
+++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/BaseGameSimulationTest.java
@@ -14,8 +14,8 @@ import forge.model.FModel;
import forge.util.Lang;
import forge.util.Localizer;
import io.sentry.Sentry;
-import io.sentry.context.Context;
import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
import org.testng.Assert;
@@ -28,6 +28,7 @@ import java.util.ResourceBundle;
ImageCache.class, ImageIO.class, ImageKeys.class,
ForgeConstants.class, Localizer.class, Sentry.class, GameLogFormatter.class})
@SuppressStaticInitializationFor({"forge.ImageCache", "forge.localinstance.properties.ForgeConstants"})
+@PowerMockIgnore({"javax.xml.*", "org.xml.sax.*", "com.sun.org.apache.xerces.*", "org.w3c.dom.*", "org.springframework.context.*", "org.apache.log4j.*"})
public class BaseGameSimulationTest extends ForgeCardMockTestCase {
@BeforeMethod
@@ -36,7 +37,7 @@ public class BaseGameSimulationTest extends ForgeCardMockTestCase {
super.initMocks();
PowerMockito.mockStatic(Sentry.class);
PowerMockito.mockStatic(GameLogFormatter.class);
- PowerMockito.when(Sentry.getContext()).thenReturn(new Context());
+ //PowerMockito.when(Sentry.getContext()).thenReturn(new Context());
Lang.createInstance("en-US");
}
diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java
index 1d77a76c637..8b758a854e3 100644
--- a/forge-gui-mobile/src/forge/Forge.java
+++ b/forge-gui-mobile/src/forge/Forge.java
@@ -59,7 +59,7 @@ import java.util.List;
import java.util.Map;
public class Forge implements ApplicationListener {
- public static final String CURRENT_VERSION = "1.6.47.001";
+ public static final String CURRENT_VERSION = "1.6.49.001";
private static ApplicationListener app = null;
static Scene currentScene = null;
diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml
index 1c7f5297ba9..148b265e81c 100644
--- a/forge-gui/pom.xml
+++ b/forge-gui/pom.xml
@@ -43,23 +43,23 @@
com.thoughtworks.xstream
xstream
- 1.4.18
+ 1.4.19
io.netty
netty-all
- 4.1.48.Final
+ 4.1.71.Final
compile
org.fourthline.cling
cling-support
- 2.0.1
+ 2.1.2
org.lz4
lz4-java
- 1.7.1
+ 1.8.0
com.github.raeleus.TenPatch
diff --git a/forge-gui/src/main/java/forge/gui/error/BugReporter.java b/forge-gui/src/main/java/forge/gui/error/BugReporter.java
index b3965239ad9..7d751505529 100644
--- a/forge-gui/src/main/java/forge/gui/error/BugReporter.java
+++ b/forge-gui/src/main/java/forge/gui/error/BugReporter.java
@@ -31,7 +31,6 @@ import forge.localinstance.properties.ForgePreferences;
import forge.model.FModel;
import forge.util.Localizer;
import io.sentry.Sentry;
-import io.sentry.event.BreadcrumbBuilder;
/**
* The class ErrorViewer. Enables showing and saving error messages that
@@ -71,9 +70,7 @@ public class BugReporter {
final StringBuilder sb = new StringBuilder();
if (null != message && !message.isEmpty()) {
- Sentry.getContext().recordBreadcrumb(
- new BreadcrumbBuilder().setMessage(message).build()
- );
+ Sentry.addBreadcrumb(message);
sb.append(FThreads.debugGetCurrThreadId()).append(" > ").append(message).append("\n");
}
@@ -156,9 +153,9 @@ public class BugReporter {
public static void sendSentry() {
if (exception != null) {
- Sentry.capture(exception);
+ Sentry.captureException(exception);
} else if (message !=null) {
- Sentry.capture(message);
+ Sentry.captureMessage(message);
}
}
diff --git a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java
index 41a5287fa78..e21669c0ea4 100644
--- a/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java
+++ b/forge-gui/src/main/java/forge/itemmanager/ColumnDef.java
@@ -34,6 +34,8 @@ import forge.itemmanager.ItemColumnConfig.SortState;
import forge.model.FModel;
import forge.util.CardTranslation;
import forge.util.Localizer;
+import forge.util.TextUtil;
+
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
@@ -68,9 +70,9 @@ public enum ColumnDef {
public Comparable> apply(final Entry from) {
if (from.getKey() instanceof PaperCard) {
String sortableName = ((PaperCard)from.getKey()).getSortableName();
- return sortableName == null ? InventoryItem.toSortableName(from.getKey().getName()) : sortableName;
+ return sortableName == null ? TextUtil.toSortableName(from.getKey().getName()) : sortableName;
}
- return InventoryItem.toSortableName(from.getKey().getName());
+ return TextUtil.toSortableName(from.getKey().getName());
}
},
new Function, Object>() {
diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java
index 5223ec868f1..ff106a7f5aa 100644
--- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java
+++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java
@@ -638,8 +638,8 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
public List chooseEntitiesForEffect(final FCollectionView optionList, final int min, final int max,
final DelayedReveal delayedReveal, final SpellAbility sa, final String title, final Player targetedPlayer, Map params) {
// useful details for debugging problems with the mass select logic
- Sentry.getContext().addExtra("Card", sa.getCardView().toString());
- Sentry.getContext().addExtra("SpellAbility", sa.toString());
+ Sentry.setExtra("Card", sa.getCardView().toString());
+ Sentry.setExtra("SpellAbility", sa.toString());
// Human is supposed to read the message and understand from it what to choose
if (optionList.isEmpty()) {
diff --git a/pom.xml b/pom.xml
index 5b4c4d59d39..c67adff9217 100644
--- a/pom.xml
+++ b/pom.xml
@@ -317,12 +317,12 @@
ch.qos.logback
logback-classic
- 1.2.9
+ 1.2.11
ch.qos.logback
logback-core
- 1.2.9
+ 1.2.11