diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 16ec6662f0d..5d67cdbd938 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -984,7 +984,7 @@ public class GameAction { for (final Card c : game.getCardsIn(ZoneType.Battlefield)) { if (c.isCreature()) { // Rule 704.5f - Put into grave (no regeneration) for toughness <= 0 - if (c.getNetToughness() <= 0) { + if (c.getLethal() <= 0) { if (noRegCreats == null) { noRegCreats = new CardCollection(); } @@ -992,7 +992,7 @@ public class GameAction { checkAgain = true; } else if (c.hasKeyword("CARDNAME can't be destroyed by lethal damage unless lethal damage dealt by a single source is marked on it.")) { for (final Integer dmg : c.getReceivedDamageFromThisTurn().values()) { - if (c.getNetToughness() <= dmg.intValue()) { + if (c.getLethal() <= dmg.intValue()) { if (desCreats == null) { desCreats = new CardCollection(); } @@ -1004,7 +1004,7 @@ public class GameAction { } // Rule 704.5g - Destroy due to lethal damage // Rule 704.5h - Destroy due to deathtouch - else if (c.getNetToughness() <= c.getDamage() || c.hasBeenDealtDeathtouchDamage()) { + else if (c.getLethal() <= c.getDamage() || c.hasBeenDealtDeathtouchDamage()) { if (desCreats == null) { desCreats = new CardCollection(); } 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 f2ab81b38b9..d89ebcdaaf7 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -4731,9 +4731,21 @@ public class Card extends GameEntity implements Comparable { return false; } + // this is the amount of damage a creature needs to receive before it dies + public final int getLethal() { + if (getAmountOfKeyword("Lethal damage dealt to CARDNAME is determined by its power rather than its toughness.") % 2 !=0) { + return getNetPower(); } + else { + return getNetToughness(); } + } + // this is the minimal damage a trampling creature has to assign to a blocker public final int getLethalDamage() { - return getNetToughness() - getDamage() - getTotalAssignedDamage(); + if (getAmountOfKeyword("Lethal damage dealt to CARDNAME is determined by its power rather than its toughness.") % 2 !=0) { + return getNetPower() - getDamage() - getTotalAssignedDamage(); + } + else { + return getNetToughness() - getDamage() - getTotalAssignedDamage();} } public final int getDamage() { diff --git a/forge-gui-android/AndroidManifest.xml b/forge-gui-android/AndroidManifest.xml index 9a984611ed7..1f2dc8ae144 100644 --- a/forge-gui-android/AndroidManifest.xml +++ b/forge-gui-android/AndroidManifest.xml @@ -7,6 +7,7 @@ + diff --git a/forge-gui-android/libs/android-support-v4.jar b/forge-gui-android/libs/android-support-v4.jar index 187bdf48b1d..653cb767665 100644 Binary files a/forge-gui-android/libs/android-support-v4.jar and b/forge-gui-android/libs/android-support-v4.jar differ diff --git a/forge-gui-android/libs/gdx-backend-android-sources.jar b/forge-gui-android/libs/gdx-backend-android-sources.jar index 414fa961cfd..d328206fb3a 100644 Binary files a/forge-gui-android/libs/gdx-backend-android-sources.jar and b/forge-gui-android/libs/gdx-backend-android-sources.jar differ diff --git a/forge-gui-android/libs/gdx-backend-android.jar b/forge-gui-android/libs/gdx-backend-android.jar index d780673aa6b..40af9131f01 100644 Binary files a/forge-gui-android/libs/gdx-backend-android.jar and b/forge-gui-android/libs/gdx-backend-android.jar differ diff --git a/forge-gui-android/libs/gdx-freetype.jar b/forge-gui-android/libs/gdx-freetype.jar index eda8b39b168..3181586a666 100644 Binary files a/forge-gui-android/libs/gdx-freetype.jar and b/forge-gui-android/libs/gdx-freetype.jar differ diff --git a/forge-gui-android/libs/gdx-sources.jar b/forge-gui-android/libs/gdx-sources.jar index 798fee80a7b..74b5aadb926 100644 Binary files a/forge-gui-android/libs/gdx-sources.jar and b/forge-gui-android/libs/gdx-sources.jar differ diff --git a/forge-gui-android/libs/gdx.jar b/forge-gui-android/libs/gdx.jar index 0ba4a3f2bb4..2c603b032c5 100644 Binary files a/forge-gui-android/libs/gdx.jar and b/forge-gui-android/libs/gdx.jar differ diff --git a/forge-gui-android/pom.xml b/forge-gui-android/pom.xml index 3067cde2874..194d8786a2c 100644 --- a/forge-gui-android/pom.xml +++ b/forge-gui-android/pom.xml @@ -105,22 +105,11 @@ 1.9.10 - org.cache2k - cache2k-base-bom - 1.2.4.Final - pom - - - org.cache2k - cache2k-core - 1.2.4.Final - compile - - - org.cache2k - cache2k-api - 1.2.4.Final - compile + com.android.support + support-v4 + 23.1.1 + system + ${pom.basedir}/libs/android-support-v4.jar diff --git a/forge-gui-android/proguard.cfg b/forge-gui-android/proguard.cfg index 57fa2061f4d..8ed1f08d7f1 100644 --- a/forge-gui-android/proguard.cfg +++ b/forge-gui-android/proguard.cfg @@ -29,20 +29,8 @@ -dontwarn javax.** -dontwarn org.apache.logging.log4j.** -dontwarn module-info - -# mandatory proguard rules for cache2k to keep the core implementation --dontwarn org.cache2k.impl.xmlConfiguration.** --dontwarn org.cache2k.impl.serverSide.** --keep interface org.cache2k.spi.Cache2kCoreProvider --keep public class * extends org.cache2k.spi.Cache2kCoreProvider -# optional proguard rules for cache2k, to keep XML configuration code -# if only programmatic configuration is used, these rules may be ommitted --keep interface org.cache2k.core.spi.CacheConfigurationProvider --keep public class * extends org.cache2k.core.spi.CacheConfigurationProvider --keepclassmembers public class * extends org.cache2k.configuration.ConfigurationBean { - public void set*(...); - public ** get*(); -} +## Support library +-dontwarn android.support.** -keep class forge.** { *; } -keep class com.thoughtworks.xstream.** { *; } diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java index 70aa9389704..3d3fbb5135a 100644 --- a/forge-gui-android/src/forge/app/Main.java +++ b/forge-gui-android/src/forge/app/Main.java @@ -1,16 +1,22 @@ package forge.app; import android.app.AlarmManager; +import android.app.AlertDialog; import android.app.PendingIntent; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.Color; +import android.graphics.Typeface; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.StateListDrawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; @@ -18,8 +24,18 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.PowerManager; +import android.provider.Settings; +import android.support.v4.content.ContextCompat; +import android.text.SpannableString; +import android.text.style.StyleSpan; +import android.view.Gravity; +import android.view.View; import android.view.WindowManager; import android.webkit.MimeTypeMap; +import android.widget.Button; +import android.widget.TableLayout; +import android.widget.TableRow; +import android.widget.TextView; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.backends.android.AndroidApplication; import forge.Forge; @@ -35,13 +51,136 @@ import java.io.OutputStream; import java.util.concurrent.Callable; public class Main extends AndroidApplication { + AndroidAdapter Gadapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - AndroidAdapter adapter = new AndroidAdapter(this.getContext()); + boolean permissiongranted = checkPermission(); + Gadapter = new AndroidAdapter(this.getContext()); + initForge(Gadapter, permissiongranted); + //permission + if(!permissiongranted){ + //requestPermission(); + displayMessage(Gadapter); + } + } + + private void displayMessage(AndroidAdapter adapter){ + TableLayout TL = new TableLayout(this); + TableRow row = new TableRow(this); + TableRow row2 = new TableRow(this); + TextView text = new TextView(this); + text.setGravity(Gravity.LEFT); + text.setTypeface(Typeface.SERIF); + + String title="Forge needs Storage Permission to run properly...\n" + + "Follow this simple steps below:\n\n"; + String steps = " 1) Tap \"Open App Details\" Button.\n" + + " 2) Tap Permissions\n"+ + " 3) Turn on the Storage Permission.\n\n"+ + "(You can tap anywhere to exit and restart the app)\n\n"; + + SpannableString ss1= new SpannableString(title); + ss1.setSpan(new StyleSpan(Typeface.BOLD), 0, ss1.length(), 0); + text.append(ss1); + text.append(steps); + row.addView(text); + row.setGravity(Gravity.CENTER); + + int[] colors = {Color.TRANSPARENT,Color.TRANSPARENT}; + int[] pressed = {Color.GREEN,Color.GREEN}; + GradientDrawable gd = new GradientDrawable( + GradientDrawable.Orientation.TOP_BOTTOM, colors); + gd.setStroke(3, Color.DKGRAY); + gd.setCornerRadius(100); + + GradientDrawable gd2 = new GradientDrawable( + GradientDrawable.Orientation.TOP_BOTTOM, pressed); + gd2.setStroke(3, Color.DKGRAY); + gd2.setCornerRadius(100); + + Button button = new Button(this); + button.setText("Open App Details"); + + StateListDrawable states = new StateListDrawable(); + + states.addState(new int[] {android.R.attr.state_pressed}, gd2); + states.addState(new int[] { }, gd); + + button.setBackground(states); + + button.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + Uri uri = Uri.fromParts("package", getPackageName(), null); + intent.setData(uri); + startActivity(intent); + } + }); + + row2.addView(button); + row2.setGravity(Gravity.CENTER); + + TL.addView(row, new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT)); + TL.addView(row2, new TableLayout.LayoutParams(TableLayout.LayoutParams.WRAP_CONTENT, TableLayout.LayoutParams.WRAP_CONTENT)); + TL.setGravity(Gravity.CENTER); + TL.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + adapter.exit(); + } + }); + setContentView(TL); + } + @Override + public void onBackPressed() { + if (Gadapter!=null) + Gadapter.exit(); + + super.onBackPressed(); + } + private boolean checkPermission() { + int result = ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); + if (result == PackageManager.PERMISSION_GRANTED) { + return true; + } else { + return false; + } + } + private void requestPermission() { + //Show Information about why you need the permission + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Storage Permission Denied..."); + builder.setMessage("This app needs storage permission to run properly.\n\n\n\n"); + builder.setPositiveButton("Open App Details", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + //ActivityCompat crashes... maybe it needs the appcompat v7??? + //ActivityCompat.requestPermissions(Main.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); + } + }); + /*builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.cancel(); + } + }); + builder.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + + } + });*/ + builder.show(); + } + + private void initForge(AndroidAdapter adapter, boolean permissiongranted){ //establish assets directory if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { Gdx.app.error("Forge", "Can't access external storage"); @@ -65,15 +204,22 @@ public class Main extends AndroidApplication { //enforce orientation based on whether device is a tablet and user preference adapter.switchOrientationFile = assetsDir + "switch_orientation.ini"; boolean landscapeMode = adapter.isTablet == !FileUtil.doesFileExist(adapter.switchOrientationFile); - if (landscapeMode) { - Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } - else { - Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + if (permissiongranted){ + if (landscapeMode) { + Main.this.setRequestedOrientation(Build.VERSION.SDK_INT >= 26 ? + ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE : //Oreo and above has virtual back/menu buttons + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + } else { + Main.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + } + } else { + //set current orientation + Main.this.setRequestedOrientation(Main.this.getResources().getConfiguration().orientation); } - boolean value = Build.VERSION.SDK_INT >= 26; - initialize(Forge.getApp(new AndroidClipboard(), adapter, assetsDir, value)); + ForgePreferences prefs = FModel.getPreferences(); + boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_USE_ELSA); + initialize(Forge.getApp(new AndroidClipboard(), adapter, assetsDir, propertyConfig)); } /*@Override diff --git a/forge-gui-desktop/src/main/java/forge/control/FControl.java b/forge-gui-desktop/src/main/java/forge/control/FControl.java index 4f951641eb5..2b29279d4e7 100644 --- a/forge-gui-desktop/src/main/java/forge/control/FControl.java +++ b/forge-gui-desktop/src/main/java/forge/control/FControl.java @@ -40,6 +40,7 @@ import javax.swing.WindowConstants; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import forge.GuiBase; import forge.ImageCache; import forge.LobbyPlayer; import forge.Singletons; @@ -219,6 +220,10 @@ public enum FControl implements KeyEventDispatcher { final ForgePreferences prefs = FModel.getPreferences(); + //set ElsaSerializer from preference + boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_USE_ELSA); + GuiBase.enablePropertyConfig(propertyConfig); + closeAction = CloseAction.valueOf(prefs.getPref(FPref.UI_CLOSE_ACTION)); final Localizer localizer = Localizer.getInstance(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java index 10e52139fc1..ef151e4c515 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java @@ -115,6 +115,7 @@ public enum CSubmenuPreferences implements ICDoc { lstControls.add(Pair.of(view.getCbSingletons(), FPref.DECKGEN_SINGLETONS)); lstControls.add(Pair.of(view.getCbEnableAICheats(), FPref.UI_ENABLE_AI_CHEATS)); lstControls.add(Pair.of(view.getCbEnableUnknownCards(), FPref.UI_LOAD_UNKNOWN_CARDS)); + lstControls.add(Pair.of(view.getCbUseElsa(), FPref.UI_USE_ELSA)); lstControls.add(Pair.of(view.getCbImageFetcher(), FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER)); lstControls.add(Pair.of(view.getCbDisplayFoil(), FPref.UI_OVERLAY_FOIL_EFFECT)); lstControls.add(Pair.of(view.getCbRandomFoil(), FPref.UI_RANDOM_FOIL)); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java index 0f07863377a..93576237c34 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java @@ -108,6 +108,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final JCheckBox cbRemindOnPriority = new OptionsCheckBox(localizer.getMessage("cbRemindOnPriority")); private final JCheckBox cbUseSentry = new OptionsCheckBox(localizer.getMessage("cbUseSentry")); private final JCheckBox cbEnableUnknownCards = new OptionsCheckBox(localizer.getMessage("lblEnableUnknownCards")); + private final JCheckBox cbUseElsa = new OptionsCheckBox("Use ELSA Serializer"); private final Map shortcutFields = new HashMap<>(); @@ -291,6 +292,9 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbEnableUnknownCards, titleConstraints); pnlPrefs.add(new NoteLabel(localizer.getMessage("nlEnableUnknownCards")), descriptionConstraints); + /*pnlPrefs.add(cbUseElsa, titleConstraints); + pnlPrefs.add(new NoteLabel("Use ELSA Serializer for Network (EXPERIMENTAL Option, Requires restart)"), descriptionConstraints);*/ + // Graphic Options pnlPrefs.add(new SectionLabel(localizer.getMessage("GraphicOptions")), sectionConstraints + ", gaptop 2%"); @@ -589,6 +593,11 @@ public enum VSubmenuPreferences implements IVSubmenu { return cbEnableUnknownCards; } + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbUseElsa() { + return cbUseElsa; + } + /** @return {@link javax.swing.JCheckBox} */ public JCheckBox getCbImageFetcher() { return cbImageFetcher; 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 de1bc65aafa..9a7424bc7e7 100644 --- a/forge-gui-desktop/src/main/java/forge/view/Main.java +++ b/forge-gui-desktop/src/main/java/forge/view/Main.java @@ -49,9 +49,6 @@ public final class Main { //setup GUI interface GuiBase.setInterface(new GuiDesktop()); - //set PropertyConfig log4j to true - GuiBase.enablePropertyConfig(true); - //install our error handler ExceptionHandler.registerErrorHandling(); diff --git a/forge-gui-ios/libs/gdx-backend-robovm-sources.jar b/forge-gui-ios/libs/gdx-backend-robovm-sources.jar index 1ed5c6f5486..7169ae4579b 100644 Binary files a/forge-gui-ios/libs/gdx-backend-robovm-sources.jar and b/forge-gui-ios/libs/gdx-backend-robovm-sources.jar differ diff --git a/forge-gui-ios/libs/gdx-backend-robovm.jar b/forge-gui-ios/libs/gdx-backend-robovm.jar index cbf789dd7b1..10cfefb0768 100644 Binary files a/forge-gui-ios/libs/gdx-backend-robovm.jar and b/forge-gui-ios/libs/gdx-backend-robovm.jar differ diff --git a/forge-gui-ios/libs/gdx-sources.jar b/forge-gui-ios/libs/gdx-sources.jar index 798fee80a7b..74b5aadb926 100644 Binary files a/forge-gui-ios/libs/gdx-sources.jar and b/forge-gui-ios/libs/gdx-sources.jar differ diff --git a/forge-gui-ios/libs/gdx.jar b/forge-gui-ios/libs/gdx.jar index 0ba4a3f2bb4..2c603b032c5 100644 Binary files a/forge-gui-ios/libs/gdx.jar and b/forge-gui-ios/libs/gdx.jar differ diff --git a/forge-gui-ios/libs/libObjectAL.a b/forge-gui-ios/libs/libObjectAL.a index 6113d44ffc9..289fd6ff6fb 100644 Binary files a/forge-gui-ios/libs/libObjectAL.a and b/forge-gui-ios/libs/libObjectAL.a differ diff --git a/forge-gui-ios/libs/libgdx-freetype.a b/forge-gui-ios/libs/libgdx-freetype.a index 67ed332cb29..371a1daee46 100644 Binary files a/forge-gui-ios/libs/libgdx-freetype.a and b/forge-gui-ios/libs/libgdx-freetype.a differ diff --git a/forge-gui-ios/libs/libgdx.a b/forge-gui-ios/libs/libgdx.a index 038693b6c84..82be25afbf9 100644 Binary files a/forge-gui-ios/libs/libgdx.a and b/forge-gui-ios/libs/libgdx.a differ diff --git a/forge-gui-ios/pom.xml b/forge-gui-ios/pom.xml index a36586a1536..a597b8484a0 100644 --- a/forge-gui-ios/pom.xml +++ b/forge-gui-ios/pom.xml @@ -75,23 +75,5 @@ gdx-backend-robovm 1.9.10 - - org.cache2k - cache2k-base-bom - 1.2.4.Final - pom - - - org.cache2k - cache2k-core - 1.2.4.Final - compile - - - org.cache2k - cache2k-api - 1.2.4.Final - compile - diff --git a/forge-gui-ios/src/forge/ios/Main.java b/forge-gui-ios/src/forge/ios/Main.java index 689e07d6fa7..74679a68360 100644 --- a/forge-gui-ios/src/forge/ios/Main.java +++ b/forge-gui-ios/src/forge/ios/Main.java @@ -8,6 +8,8 @@ import com.badlogic.gdx.backends.iosrobovm.IOSFiles; import forge.Forge; import forge.assets.AssetsDownloader; import forge.interfaces.IDeviceAdapter; +import forge.model.FModel; +import forge.properties.ForgePreferences; import forge.util.FileUtil; import org.robovm.apple.foundation.NSAutoreleasePool; import org.robovm.apple.uikit.UIApplication; @@ -29,7 +31,9 @@ public class Main extends IOSApplication.Delegate { final IOSApplicationConfiguration config = new IOSApplicationConfiguration(); config.useAccelerometer = false; config.useCompass = false; - final ApplicationListener app = Forge.getApp(new IOSClipboard(), new IOSAdapter(), assetsDir, false); + ForgePreferences prefs = FModel.getPreferences(); + boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_USE_ELSA); + final ApplicationListener app = Forge.getApp(new IOSClipboard(), new IOSAdapter(), assetsDir, propertyConfig); final IOSApplication iosApp = new IOSApplication(app, config); return iosApp; } diff --git a/forge-gui-mobile-dev/libs/gdx-backend-lwjgl-sources.jar b/forge-gui-mobile-dev/libs/gdx-backend-lwjgl-sources.jar index f736a822dd8..45f4e0fdbd0 100644 Binary files a/forge-gui-mobile-dev/libs/gdx-backend-lwjgl-sources.jar and b/forge-gui-mobile-dev/libs/gdx-backend-lwjgl-sources.jar differ diff --git a/forge-gui-mobile-dev/libs/gdx-backend-lwjgl.jar b/forge-gui-mobile-dev/libs/gdx-backend-lwjgl.jar index d1699805b6d..96f39d65c17 100644 Binary files a/forge-gui-mobile-dev/libs/gdx-backend-lwjgl.jar and b/forge-gui-mobile-dev/libs/gdx-backend-lwjgl.jar differ diff --git a/forge-gui-mobile-dev/libs/gdx-freetype-natives.jar b/forge-gui-mobile-dev/libs/gdx-freetype-natives.jar index 025707e2973..74481284775 100644 Binary files a/forge-gui-mobile-dev/libs/gdx-freetype-natives.jar and b/forge-gui-mobile-dev/libs/gdx-freetype-natives.jar differ diff --git a/forge-gui-mobile-dev/libs/gdx-natives.jar b/forge-gui-mobile-dev/libs/gdx-natives.jar index 18f0fbc3dcf..cbd60119618 100644 Binary files a/forge-gui-mobile-dev/libs/gdx-natives.jar and b/forge-gui-mobile-dev/libs/gdx-natives.jar differ diff --git a/forge-gui-mobile-dev/pom.xml b/forge-gui-mobile-dev/pom.xml index 68270592ec9..0deaa787ba2 100644 --- a/forge-gui-mobile-dev/pom.xml +++ b/forge-gui-mobile-dev/pom.xml @@ -80,23 +80,5 @@ commons-cli 1.4 - - org.cache2k - cache2k-base-bom - 1.2.4.Final - pom - - - org.cache2k - cache2k-core - 1.2.4.Final - compile - - - org.cache2k - cache2k-api - 1.2.4.Final - compile - diff --git a/forge-gui-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index 8f2de339592..cbac0f09d8e 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -7,6 +7,8 @@ import com.badlogic.gdx.backends.lwjgl.LwjglClipboard; import forge.Forge; import forge.assets.AssetsDownloader; import forge.interfaces.IDeviceAdapter; +import forge.model.FModel; +import forge.properties.ForgePreferences; import forge.util.FileUtil; import forge.util.OperatingSystem; import forge.util.RestartUtil; @@ -92,8 +94,10 @@ public class Main { config.title = "Forge"; config.useHDPI = desktopMode; // enable HiDPI on Mac OS + ForgePreferences prefs = FModel.getPreferences(); + boolean propertyConfig = prefs != null && prefs.getPrefBoolean(ForgePreferences.FPref.UI_USE_ELSA); new LwjglApplication(Forge.getApp(new LwjglClipboard(), new DesktopAdapter(switchOrientationFile), - desktopMode ? desktopModeAssetsDir : assetsDir, true), config); + desktopMode ? desktopModeAssetsDir : assetsDir, propertyConfig), config); } private static class DesktopAdapter implements IDeviceAdapter { diff --git a/forge-gui-mobile/libs/gdx-freetype.jar b/forge-gui-mobile/libs/gdx-freetype.jar index eda8b39b168..3181586a666 100644 Binary files a/forge-gui-mobile/libs/gdx-freetype.jar and b/forge-gui-mobile/libs/gdx-freetype.jar differ diff --git a/forge-gui-mobile/libs/gdx-sources.jar b/forge-gui-mobile/libs/gdx-sources.jar index 798fee80a7b..74b5aadb926 100644 Binary files a/forge-gui-mobile/libs/gdx-sources.jar and b/forge-gui-mobile/libs/gdx-sources.jar differ diff --git a/forge-gui-mobile/libs/gdx.jar b/forge-gui-mobile/libs/gdx.jar index 0ba4a3f2bb4..2c603b032c5 100644 Binary files a/forge-gui-mobile/libs/gdx.jar and b/forge-gui-mobile/libs/gdx.jar differ diff --git a/forge-gui-mobile/pom.xml b/forge-gui-mobile/pom.xml index 9062150762e..60029bb033b 100644 --- a/forge-gui-mobile/pom.xml +++ b/forge-gui-mobile/pom.xml @@ -70,24 +70,6 @@ gdx-freetype 1.9.10 - - org.cache2k - cache2k-base-bom - 1.2.4.Final - pom - - - org.cache2k - cache2k-core - 1.2.4.Final - compile - - - org.cache2k - cache2k-api - 1.2.4.Final - compile - diff --git a/forge-gui-mobile/src/forge/assets/ImageCache.java b/forge-gui-mobile/src/forge/assets/ImageCache.java index 70919ec452b..5d472e6e1aa 100644 --- a/forge-gui-mobile/src/forge/assets/ImageCache.java +++ b/forge-gui-mobile/src/forge/assets/ImageCache.java @@ -22,6 +22,8 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.Pixmap.Format; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.TextureRegion; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.LoadingCache; import forge.ImageKeys; import forge.card.CardEdition; import forge.game.card.CardView; @@ -32,11 +34,11 @@ import forge.model.FModel; import forge.properties.ForgeConstants; import forge.util.ImageUtil; import org.apache.commons.lang3.StringUtils; -import org.cache2k.Cache; -import org.cache2k.Cache2kBuilder; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; /** * This class stores ALL card images in a cache with soft values. this means @@ -56,13 +58,10 @@ public class ImageCache { // short prefixes to save memory private static final Set missingIconKeys = new HashSet<>(); - private static final Cache cache = new Cache2kBuilder() {} - .name("cache") - .eternal(true) - .permitNullValues(true) - .disableStatistics(true) - .loader(new ImageLoader()) - .build(); + private static final LoadingCache cache = CacheBuilder.newBuilder() + .maximumSize(400) + .expireAfterAccess(15, TimeUnit.MINUTES) + .build(new ImageLoader()); public static final Texture defaultImage; public static FImage BlackBorder = FSkinImage.IMG_BORDER_BLACK; public static FImage WhiteBorder = FSkinImage.IMG_BORDER_WHITE; @@ -85,7 +84,7 @@ public class ImageCache { } public static void clear() { - cache.clear(); + cache.invalidateAll(); missingIconKeys.clear(); } @@ -134,7 +133,7 @@ public class ImageCache { Texture image; if (useDefaultIfNotFound) { // Load from file and add to cache if not found in cache initially. - image = cache.get(imageKey); + image = cache.getIfPresent(imageKey); if (image != null) { return image; } @@ -165,7 +164,11 @@ public class ImageCache { return image; } public static void preloadCache(Iterable keys) { - cache.getAll(keys); + try { + cache.getAll(keys); + } catch (ExecutionException e) { + e.printStackTrace(); + } } public static TextureRegion croppedBorderImage(Texture image, boolean fullborder) { if (!fullborder) diff --git a/forge-gui-mobile/src/forge/assets/ImageLoader.java b/forge-gui-mobile/src/forge/assets/ImageLoader.java index 5f33d4c44c9..0137daa9f5e 100644 --- a/forge-gui-mobile/src/forge/assets/ImageLoader.java +++ b/forge-gui-mobile/src/forge/assets/ImageLoader.java @@ -8,8 +8,8 @@ import com.badlogic.gdx.graphics.Pixmap; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.TextureData; import com.badlogic.gdx.graphics.glutils.PixmapTextureData; +import com.google.common.cache.CacheLoader; import forge.FThreads; -import org.cache2k.integration.CacheLoader; import forge.Forge; import forge.ImageKeys; diff --git a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java index e6b015feeb1..00a80dd2fbd 100644 --- a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java +++ b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java @@ -232,6 +232,14 @@ public class SettingsPage extends TabPage { localizer.getMessage("cbLoadHistoricFormats"), localizer.getMessage("nlLoadHistoricFormats")), 3); + lstSettings.addItem(new BooleanSetting(FPref.UI_LOAD_UNKNOWN_CARDS, + localizer.getMessage("lblEnableUnknownCards"), + localizer.getMessage("nlEnableUnknownCards")), + 3); + /*lstSettings.addItem(new BooleanSetting(FPref.UI_USE_ELSA, + "Use ELSA Serializer", + "Use ELSA Serializer for Network (EXPERIMENTAL Option, Requires restart)"), + 3);*/ //Graphic Options lstSettings.addItem(new BooleanSetting(FPref.UI_ENABLE_ONLINE_IMAGE_FETCHER, @@ -331,10 +339,6 @@ public class SettingsPage extends TabPage { Forge.showFPS = FModel.getPreferences().getPrefBoolean(FPref.UI_SHOW_FPS); } },4); - lstSettings.addItem(new BooleanSetting(FPref.UI_LOAD_UNKNOWN_CARDS, - localizer.getMessage("lblEnableUnknownCards"), - localizer.getMessage("nlEnableUnknownCards")), - 4); lstSettings.addItem(new CustomSelectSetting(FPref.UI_CARD_COUNTER_DISPLAY_TYPE, localizer.getMessage("cbpCounterDisplayType"), localizer.getMessage("nlCounterDisplayType"), diff --git a/forge-gui/pom.xml b/forge-gui/pom.xml index 5a33c84805e..98f0a976c45 100644 --- a/forge-gui/pom.xml +++ b/forge-gui/pom.xml @@ -54,7 +54,7 @@ io.netty netty-all - 4.1.43.Final + 4.1.48.Final compile diff --git a/forge-gui/res/cardsfolder/upcoming/colossification.txt b/forge-gui/res/cardsfolder/upcoming/colossification.txt new file mode 100755 index 00000000000..3ebd87ad154 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/colossification.txt @@ -0,0 +1,9 @@ +Name:Colossification +ManaCost:5 G G +Types:Enchantment Aura +K:Enchant creature +A:SP$ Attach | Cost$ 5 G G | ValidTgts$ Creature | AILogic$ Pump +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigTap | TriggerDescription$ When CARDNAME enters the battlefield, tap enchanted creature. +SVar:TrigTap:DB$ Tap | Defined$ Enchanted +S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 20 | AddToughness$ 20 | Description$ Enchanted creature gets +20/+20. +Oracle:Enchant creature\nWhen Colossification enters the battlefield, tap enchanted creature.\nEnchanted creature gets +20/+20. diff --git a/forge-gui/res/cardsfolder/upcoming/drannith_stinger.txt b/forge-gui/res/cardsfolder/upcoming/drannith_stinger.txt new file mode 100755 index 00000000000..3dfa1fd988d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/drannith_stinger.txt @@ -0,0 +1,8 @@ +Name:Drannith Stinger +ManaCost:1 R +Types:Creature Human Wizard +PT:2/2 +T:Mode$ Cycled | ValidCard$ Card.Other+YouOwn | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ Whenever you cycle another card, CARDNAME deals 1 damage to each opponent. +SVar:TrigDamage:DB$ DealDamage | Defined$ Player.Opponent | NumDmg$ 1 +K:Cycling:1 +Oracle:Whenever you cycle another card, Drannith Stinger deals 1 damage to each opponent.\nCycling {1} ({1}, Discard this card: Draw a card.) diff --git a/forge-gui/res/cardsfolder/upcoming/gloom_pangolin.txt b/forge-gui/res/cardsfolder/upcoming/gloom_pangolin.txt new file mode 100755 index 00000000000..2e495da70b0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/gloom_pangolin.txt @@ -0,0 +1,5 @@ +Name:Gloom Pangolin +ManaCost:2 B +Types:Creature Nightmare Pangolin +PT:1/5 +Oracle: diff --git a/forge-gui/res/cardsfolder/upcoming/kogla_the_titan_ape.txt b/forge-gui/res/cardsfolder/upcoming/kogla_the_titan_ape.txt new file mode 100644 index 00000000000..5f368e332b8 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/kogla_the_titan_ape.txt @@ -0,0 +1,11 @@ +Name:Kogla, the Titan Ape +ManaCost:3 G G G +Types:Legendary Creature Ape +PT:7/6 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigFight | TriggerDescription$ When CARDNAME enters the battlefield, it fights up to one target creature you don't control. +SVar:TrigFight:DB$ Fight | Defined$ TriggeredCardLKICopy | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Choose target creature you don't control | TargetMin$ 0 | TargetMax$ 1 +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigDestroy | TriggerDescription$ Whenever CARDNAME attacks, destroy target artifact or enchantment defending player controls. +SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.DefenderCtrl,Enchantment.DefenderCtrl | TgtPrompt$ Select target artifact or enchantment defending player controls +A:AB$ ChangeZone | Cost$ 1 G | ValidTgts$ Human.YouCtrl | TgtPrompt$ Choose target Human you control | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBPump | SpellDescription$ Return target Human you control to its owner's hand. CARDNAME gains indestructible until end of turn. +SVar:DBPump:DB$ Pump | Defined$ Self | KW$ Indestructible +Oracle:When Kogla, the Titan Ape enters the battlefield, it fights up to one target creature you don't control.\nWhenever Kogla attacks, destroy target artifact or enchantment defending player controls.\n{1}{G}: Return target Human you control to its owner's hand. Kogla gains indestructible until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/labyrinth_raptor.txt b/forge-gui/res/cardsfolder/upcoming/labyrinth_raptor.txt new file mode 100755 index 00000000000..663387e9577 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/labyrinth_raptor.txt @@ -0,0 +1,10 @@ +Name:Labyrinth Raptor +ManaCost:B R +Types:Creature Nightmare Dinosaur +PT:2/2 +K:Menace +T:Mode$ AttackerBlocked | ValidCard$ Creature.YouCtrl+withMenace | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ Whenever a creature you control with menace becomes blocked, defending player sacrifices a creature blocking it. +SVar:TrigSac:DB$ Sacrifice | Defined$ DefendingPlayer | SacValid$ Creature.blockingSource | ChangeNum$ 1 +A:AB$ PumpAll | Cost$ B R | ValidCards$ Creature.YouCtrl+withMenace | NumAtt$ 1 | SpellDescription$ Creatures you control with menace get +1/+0 until end of turn. +SVar:PlayMain1:TRUE +Oracle:Menace\nWhenever a creature you control with menace becomes blocked, defending player sacrifices a creature blocking it.\n{B}{R}: Creatures you control with menace get +1/+0 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/mosscoat_goriak.txt b/forge-gui/res/cardsfolder/upcoming/mosscoat_goriak.txt new file mode 100755 index 00000000000..c13b33335f6 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/mosscoat_goriak.txt @@ -0,0 +1,6 @@ +Name:Mosscoat Goriak +ManaCost:2 G +Types:Creature Beast +PT:2/4 +K:Vigilance +Oracle:Vigilance diff --git a/forge-gui/res/cardsfolder/upcoming/primal_empathy.txt b/forge-gui/res/cardsfolder/upcoming/primal_empathy.txt new file mode 100755 index 00000000000..1d2bfd4f62d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/primal_empathy.txt @@ -0,0 +1,13 @@ +Name:Primal Empathy +ManaCost:1 G U +Types:Enchantment +T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ At the beginning of your upkeep, draw a card if you control a creature with the greatest power among creatures on the battlefield. Otherwise, put a +1/+1 counter on a creature you control. +SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | ConditionPresent$ Creature | ConditionCompare$ GE1 | ConditionPresent$ Creature | ConditionCompare$ GE1 | ConditionCheckSVar$ Z | ConditionSVarCompare$ GEY | References$ Y,Z | RememberDrawn$ True | SubAbility$ DBChoose +SVar:DBChoose:DB$ ChooseCard | Defined$ You | Choices$ Creature.YouCtrl | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ0 | References$ X | SubAbility$ DBPutCounter +SVar:DBPutCounter:DB$ PutCounter | Defined$ ChosenCard | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True +SVar:X:Count$RememberedSize +SVar:Y:Count$GreatestPower_Creature.YouDontCtrl +SVar:Z:Count$GreatestPower_Creature.YouCtrl +DeckHas:Ability$Counters +Oracle:At the beginning of your upkeep, draw a card if you control a creature with the greatest power among creatures on the battlefield. Otherwise, put a +1/+1 counter on a creature you control. diff --git a/forge-gui/res/cardsfolder/upcoming/sprite_dragon.txt b/forge-gui/res/cardsfolder/upcoming/sprite_dragon.txt new file mode 100755 index 00000000000..5cf45681438 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/sprite_dragon.txt @@ -0,0 +1,10 @@ +Name:Sprite Dragon +ManaCost:U R +Types:Creature Faerie Dragon +PT:1/1 +K:Flying +K:Haste +T:Mode$ SpellCast | ValidCard$ Card.nonCreature | ValidActivatingPlayer$ You | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a noncreature spell, put a +1/+1 counter on CARDNAME. +SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 +SVar:BuffedBy:nonCreature +Oracle:Flying, haste\nWhenever you cast a noncreature spell, put a +1/+1 counter on Sprite Dragon. diff --git a/forge-gui/res/cardsfolder/upcoming/zilortha_strength_incarnate.txt b/forge-gui/res/cardsfolder/upcoming/zilortha_strength_incarnate.txt new file mode 100644 index 00000000000..37a13f585de --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zilortha_strength_incarnate.txt @@ -0,0 +1,7 @@ +Name:Zilortha, Strength Incarnate +ManaCost:3 R G +Types:Legendary Creature Dinosaur +K:Trample +PT:7/3 +S:Mode$ Continuous | Affected$ Creature.YouCtrl | AddHiddenKeyword$ Lethal damage dealt to CARDNAME is determined by its power rather than its toughness. | Description$ Lethal damage dealt to creatures you control is determined by their power rather than their toughness. +Oracle:Trample\nLethal damage dealt to creatures you control is determined by their power rather than their toughness. diff --git a/forge-gui/src/main/java/forge/net/client/FGameClient.java b/forge-gui/src/main/java/forge/net/client/FGameClient.java index 148118df536..44a1a7d79d5 100644 --- a/forge-gui/src/main/java/forge/net/client/FGameClient.java +++ b/forge-gui/src/main/java/forge/net/client/FGameClient.java @@ -1,7 +1,5 @@ package forge.net.client; -import forge.net.CustomObjectDecoder; -import forge.net.CustomObjectEncoder; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; @@ -28,6 +26,8 @@ import forge.net.event.IdentifiableNetEvent; import forge.net.event.LobbyUpdateEvent; import forge.net.event.MessageEvent; import forge.net.event.NetEvent; +import io.netty.handler.codec.serialization.ObjectDecoder; +import io.netty.handler.codec.serialization.ObjectEncoder; public class FGameClient implements IToServer { @@ -58,8 +58,8 @@ public class FGameClient implements IToServer { public void initChannel(final SocketChannel ch) throws Exception { final ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast( - new CustomObjectEncoder(), - new CustomObjectDecoder(CustomObjectDecoder.maxObjectsize, ClassResolvers.cacheDisabled(null)), + new ObjectEncoder(), + new ObjectDecoder(9766*1024, ClassResolvers.cacheDisabled(null)), new MessageHandler(), new LobbyUpdateHandler(), new GameClientHandler(FGameClient.this)); diff --git a/forge-gui/src/main/java/forge/net/server/FServerManager.java b/forge-gui/src/main/java/forge/net/server/FServerManager.java index beb3887d4c2..68e4f7d1bbd 100644 --- a/forge-gui/src/main/java/forge/net/server/FServerManager.java +++ b/forge-gui/src/main/java/forge/net/server/FServerManager.java @@ -6,8 +6,6 @@ import forge.interfaces.IGuiGame; import forge.interfaces.ILobbyListener; import forge.match.LobbySlot; import forge.match.LobbySlotType; -import forge.net.CustomObjectDecoder; -import forge.net.CustomObjectEncoder; import forge.net.event.LobbyUpdateEvent; import forge.net.event.LoginEvent; import forge.net.event.LogoutEvent; @@ -26,6 +24,8 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.serialization.ClassResolvers; +import io.netty.handler.codec.serialization.ObjectDecoder; +import io.netty.handler.codec.serialization.ObjectEncoder; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; @@ -99,8 +99,8 @@ public final class FServerManager { public final void initChannel(final SocketChannel ch) throws Exception { final ChannelPipeline p = ch.pipeline(); p.addLast( - new CustomObjectEncoder(), - new CustomObjectDecoder(CustomObjectDecoder.maxObjectsize, ClassResolvers.cacheDisabled(null)), + new ObjectEncoder(), + new ObjectDecoder(9766*1024, ClassResolvers.cacheDisabled(null)), new MessageHandler(), new RegisterClientHandler(), new LobbyInputHandler(), diff --git a/forge-gui/src/main/java/forge/properties/ForgePreferences.java b/forge-gui/src/main/java/forge/properties/ForgePreferences.java index 78aa7f65ed2..c18a316c30a 100644 --- a/forge-gui/src/main/java/forge/properties/ForgePreferences.java +++ b/forge-gui/src/main/java/forge/properties/ForgePreferences.java @@ -139,6 +139,7 @@ public class ForgePreferences extends PreferencesStore { UI_ENABLE_PRELOAD_EXTENDED_ART("false"), UI_ENABLE_BORDER_MASKING("false"), UI_SHOW_FPS("false"), + UI_USE_ELSA("false"), UI_LOAD_UNKNOWN_CARDS("true"), UI_ALLOW_ORDER_GRAVEYARD_WHEN_NEEDED ("Never"), UI_DEFAULT_FONT_SIZE("12"),