diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtil.java b/forge-ai/src/main/java/forge/ai/ComputerUtil.java index 3af26c3358f..0d83d91aefe 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtil.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtil.java @@ -1626,7 +1626,7 @@ public class ComputerUtil { for (final Card c : all) { // check if card is at least available to be played // further improvements might consider if AI has options to steal the spell by making it playable first - if (c.getZone().getPlayer() != null && c.getZone().getPlayer() != defender && c.mayPlay(defender).isEmpty()) { + if (c.getZone() != null && c.getZone().getPlayer() != null && c.getZone().getPlayer() != defender && c.mayPlay(defender).isEmpty()) { continue; } for (final SpellAbility sa : c.getSpellAbilities()) { diff --git a/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java b/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java index f35c873f368..2f507a41dda 100644 --- a/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java +++ b/forge-ai/src/main/java/forge/ai/CreatureEvaluator.java @@ -26,6 +26,9 @@ public class CreatureEvaluator implements Function { return evaluateCreature(c, true, true); } public int evaluateCreature(final Card c, final boolean considerPT, final boolean considerCMC) { + //Card shouldn't be null and AI shouldn't crash since this is just score + if (c == null) + return 0; int value = 80; if (!c.isToken()) { value += addValue(20, "non-token"); // tokens should be worth less than actual cards diff --git a/forge-core/pom.xml b/forge-core/pom.xml index be599bca945..63df4b28ad2 100644 --- a/forge-core/pom.xml +++ b/forge-core/pom.xml @@ -34,6 +34,11 @@ + + com.apptasticsoftware + rssreader + 3.6.0 + diff --git a/forge-gui-desktop/src/main/java/forge/util/RSSReader.java b/forge-core/src/main/java/forge/util/RSSReader.java similarity index 85% rename from forge-gui-desktop/src/main/java/forge/util/RSSReader.java rename to forge-core/src/main/java/forge/util/RSSReader.java index bbc6f2b1c26..8db2d8e2f29 100644 --- a/forge-gui-desktop/src/main/java/forge/util/RSSReader.java +++ b/forge-core/src/main/java/forge/util/RSSReader.java @@ -12,11 +12,9 @@ import java.util.Date; import java.util.List; public class RSSReader { - public static String getCommitLog(Date buildDateOriginal, SimpleDateFormat dateFormat, Date max) { + public static String getCommitLog(Date buildDateOriginal, Date maxDate) { String message = ""; - SimpleDateFormat simpleDate = dateFormat; - if (simpleDate == null) - simpleDate = new SimpleDateFormat("E, MMM dd, yyyy - hh:mm:ss a"); + SimpleDateFormat simpleDate = TextUtil.getSimpleDate(); try { RssReader reader = new RssReader(); URL url = new URL("https://github.com/Card-Forge/forge/commits/master.atom"); @@ -36,7 +34,7 @@ public class RSSReader { Date feedDate = Date.from(zonedDateTime.toInstant()); if (buildDateOriginal != null && feedDate.before(buildDateOriginal)) continue; - if (max != null && feedDate.after(max)) + if (maxDate != null && feedDate.after(maxDate)) continue; logs.append(simpleDate.format(feedDate)).append(" | ").append(StringEscapeUtils.unescapeXml(title).replace("\n", "").replace(" ", "")).append("\n\n"); if (c >= 15) diff --git a/forge-core/src/main/java/forge/util/TextUtil.java b/forge-core/src/main/java/forge/util/TextUtil.java index 82a4394308e..775cfdbec05 100644 --- a/forge-core/src/main/java/forge/util/TextUtil.java +++ b/forge-core/src/main/java/forge/util/TextUtil.java @@ -29,6 +29,7 @@ import forge.item.PaperCard; */ public class TextUtil { private static final StringBuilder changes = new StringBuilder(); + private static SimpleDateFormat simpleDate; static ImmutableSortedMap romanMap = ImmutableSortedMap.naturalOrder() .put(1000, "M").put(900, "CM") @@ -392,6 +393,11 @@ public class TextUtil { } return out.toString(); } + public static SimpleDateFormat getSimpleDate() { + if (simpleDate == null) + simpleDate = new SimpleDateFormat("E, MMM dd, yyyy - hh:mm:ss a"); + return simpleDate; + } //format changelog public static String getFormattedChangelog(File changelog, String defaultLog) { if (!changelog.exists()) @@ -400,30 +406,9 @@ public class TextUtil { try { Calendar calendar = Calendar.getInstance(); SimpleDateFormat original = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - SimpleDateFormat formatted = new SimpleDateFormat("E, MMM dd, yyyy - hh:mm:ss a"); + SimpleDateFormat formatted = getSimpleDate(); String offset = " GMT " + OffsetDateTime.now().getOffset(); List toformat = FileUtil.readAllLines(changelog, false); - /*for (String line : toformat) { - if (line.isEmpty() || line.startsWith("#") || line.length() < 4) - continue; - if (line.startsWith("[")) { - String datestring = line.substring(line.lastIndexOf(" *")+1).replace("*", ""); - try { - original.setTimeZone(TimeZone.getTimeZone("UTC")); - Date toDate = original.parse(datestring); - calendar.setTime(toDate); - formatted.setTimeZone(TimeZone.getDefault()); - changes += "\n(" + formatted.format(calendar.getTime()) + offset + ")\n\n"; - } catch (Exception e2) { - changes += "\n(" + datestring + ")\n\n"; - } - } else { - if (line.startsWith(" * ")) - changes += "\n"+ StringEscapeUtils.unescapeXml(line); - else - changes += StringEscapeUtils.unescapeXml(line); - } - }*/ boolean skip = false; int count = 0; for (String line : toformat) { diff --git a/forge-gui-android/src/forge/app/AtomReader.java b/forge-gui-android/src/forge/app/AtomReader.java new file mode 100644 index 00000000000..1ac470e5939 --- /dev/null +++ b/forge-gui-android/src/forge/app/AtomReader.java @@ -0,0 +1,113 @@ +package forge.app; + +import android.util.Xml; +import org.xmlpull.v1.XmlPullParser; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class AtomReader { + private static final String ns = null; + + public List parse(InputStream in) throws Exception { + try { + XmlPullParser parser = Xml.newPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false); + parser.setInput(in, "UTF-8"); + parser.nextTag(); + return readFeed(parser); + } finally { + in.close(); + } + } + + private List readFeed(XmlPullParser parser) throws Exception { + List entries = new ArrayList<>(); + + parser.require(XmlPullParser.START_TAG, ns, "feed"); + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; + } + String name = parser.getName(); + // Starts by looking for the entry tag. + if (name.equals("entry")) { + entries.add(readEntry(parser)); + } else { + skip(parser); + } + } + return entries; + } + + private void skip(XmlPullParser parser) throws Exception { + if (parser.getEventType() != XmlPullParser.START_TAG) { + throw new IllegalStateException(); + } + int depth = 1; + while (depth != 0) { + switch (parser.next()) { + case XmlPullParser.END_TAG: + depth--; + break; + case XmlPullParser.START_TAG: + depth++; + break; + } + } + } + + public static class Entry { + public final String title; + public final String updated; + + private Entry(String title, String updated) { + this.title = title; + this.updated = updated; + } + } + + private Entry readEntry(XmlPullParser parser) throws Exception { + parser.require(XmlPullParser.START_TAG, ns, "entry"); + String title = null; + String updated = null; + while (parser.next() != XmlPullParser.END_TAG) { + if (parser.getEventType() != XmlPullParser.START_TAG) { + continue; + } + String name = parser.getName(); + if (name.equals("title")) { + title = readTitle(parser); + } else if (name.equals("updated")) { + updated = readUpdated(parser); + } else { + skip(parser); + } + } + return new Entry(title, updated); + } + + private String readTitle(XmlPullParser parser) throws Exception { + parser.require(XmlPullParser.START_TAG, ns, "title"); + String title = readText(parser); + parser.require(XmlPullParser.END_TAG, ns, "title"); + return title; + } + + private String readUpdated(XmlPullParser parser) throws Exception { + parser.require(XmlPullParser.START_TAG, ns, "updated"); + String updated = readText(parser); + parser.require(XmlPullParser.END_TAG, ns, "updated"); + return updated; + } + + private String readText(XmlPullParser parser) throws Exception { + String result = ""; + if (parser.next() == XmlPullParser.TEXT) { + result = parser.getText(); + parser.nextTag(); + } + return result; + } +} diff --git a/forge-gui-android/src/forge/app/GitLogs.java b/forge-gui-android/src/forge/app/GitLogs.java new file mode 100644 index 00000000000..e1bef125bf1 --- /dev/null +++ b/forge-gui-android/src/forge/app/GitLogs.java @@ -0,0 +1,49 @@ +package forge.app; + +import forge.util.TextUtil; +import org.apache.commons.text.StringEscapeUtils; + +import java.io.InputStream; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +public class GitLogs { + public String getLatest(Date buildDateOriginal, Date maxDate) { + String message = ""; + try { + URL url = new URL("https://github.com/Card-Forge/forge/commits/master.atom"); + InputStream inputStream = url.openStream(); + List entries = new AtomReader().parse(inputStream); + StringBuilder logs = new StringBuilder(); + SimpleDateFormat simpleDate = TextUtil.getSimpleDate(); + SimpleDateFormat atomDate = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss"); + int c = 0; + for (AtomReader.Entry entry : entries) { + if (entry.title == null) + continue; + String title = TextUtil.stripNonValidXMLCharacters(entry.title); + if (title.contains("Merge")) + continue; + if (entry.updated == null) + continue; + Date feedDate = atomDate.parse(entry.updated); + if (buildDateOriginal != null && feedDate.before(buildDateOriginal)) + continue; + if (maxDate != null && feedDate.after(maxDate)) + continue; + logs.append(simpleDate.format(feedDate)).append(" | ").append(StringEscapeUtils.unescapeXml(title).replace("\n", "").replace(" ", "")).append("\n\n"); + if (c >= 15) + break; + c++; + } + if (logs.length() > 0) + message += ("\n\nLatest Changes:\n\n" + logs); + inputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return message; + } +} diff --git a/forge-gui-android/src/forge/app/Main.java b/forge-gui-android/src/forge/app/Main.java index 1456dd14155..526c416a09c 100644 --- a/forge-gui-android/src/forge/app/Main.java +++ b/forge-gui-android/src/forge/app/Main.java @@ -71,6 +71,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.text.Normalizer; import java.util.ArrayList; +import java.util.Date; public class Main extends ForgeAndroidApplication { private AndroidAdapter Gadapter; @@ -633,6 +634,11 @@ public class Main extends ForgeAndroidApplication { return versionString; } + @Override + public String getLatestChanges(Date buildDateOriginal, Date maxDate) { + return new GitLogs().getLatest(buildDateOriginal, maxDate); + } + @Override public boolean openFile(String filename) { try { diff --git a/forge-gui-desktop/pom.xml b/forge-gui-desktop/pom.xml index e21edf991fb..1aeb7a74877 100644 --- a/forge-gui-desktop/pom.xml +++ b/forge-gui-desktop/pom.xml @@ -436,11 +436,6 @@ imageio-jpeg 3.12.0 - - com.apptasticsoftware - rssreader - 3.6.0 - diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java index fbcfd338406..4d912a51c50 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuDownloaders.java @@ -30,7 +30,7 @@ public enum CSubmenuDownloaders implements ICDoc { SINGLETON_INSTANCE; private final UiCommand cmdLicensing = VSubmenuDownloaders.SINGLETON_INSTANCE::showLicensing; - private final UiCommand cmdCheckForUpdates = () -> new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(null, null, null))); + private final UiCommand cmdCheckForUpdates = () -> new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(null, null))); private final UiCommand cmdPicDownload = () -> new GuiDownloader(new GuiDownloadPicturesLQ()).show(); private final UiCommand cmdPicDownloadHQ = () -> new GuiDownloader(new GuiDownloadPicturesHQ()).show(); diff --git a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java index 16e80ea4022..67a4283eb77 100644 --- a/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java +++ b/forge-gui-desktop/src/main/java/forge/view/FTitleBarBase.java @@ -420,7 +420,7 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { } } public class UpdaterButton extends TitleBarButton { - final int MARQUEE_SPEED_DIV = 25; + final int MARQUEE_SPEED_DIV = 15; final int REPAINT_WITHIN_MS = 25; final String displayText = FControl.instance.compareVersion(BuildInfo.getVersionString()); private UpdaterButton() { @@ -431,7 +431,7 @@ public abstract class FTitleBarBase extends SkinnedMenuBar { @Override protected void onClick() { try { - new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(null, null, null))); + new AutoUpdater(false).attemptToUpdate(CompletableFuture.supplyAsync(() -> RSSReader.getCommitLog(null, null))); } catch (Exception e) { e.printStackTrace(); } diff --git a/forge-gui-ios/src/forge/ios/Main.java b/forge-gui-ios/src/forge/ios/Main.java index fc452ca70ba..aed7668f801 100644 --- a/forge-gui-ios/src/forge/ios/Main.java +++ b/forge-gui-ios/src/forge/ios/Main.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Date; import org.apache.commons.lang3.tuple.Pair; import org.robovm.apple.foundation.NSAutoreleasePool; @@ -78,6 +79,11 @@ public class Main extends IOSApplication.Delegate { return "0.0"; } + @Override + public String getLatestChanges(Date buildDateOriginal, Date maxDate) { + return ""; + } + @Override public boolean openFile(final String filename) { return new IOSFiles().local(filename).exists(); diff --git a/forge-gui-mobile-dev/src/forge/app/GameLauncher.java b/forge-gui-mobile-dev/src/forge/app/GameLauncher.java index 83d8560dffc..046c6c126ba 100644 --- a/forge-gui-mobile-dev/src/forge/app/GameLauncher.java +++ b/forge-gui-mobile-dev/src/forge/app/GameLauncher.java @@ -9,8 +9,6 @@ import com.badlogic.gdx.graphics.glutils.HdpiMode; import com.badlogic.gdx.utils.SharedLibraryLoader; import forge.Forge; import forge.adventure.util.Config; -import forge.assets.AssetsDownloader; -import forge.util.FileUtil; import org.lwjgl.system.Configuration; import java.nio.file.Files; @@ -28,16 +26,9 @@ public class GameLauncher { if (!Files.exists(Paths.get(desktopModeAssetsDir + "res"))) desktopModeAssetsDir = "../forge-gui/";//try IDE run - // Assets directory used when the game fully emulates smartphone/tablet mode (desktopMode = false), useful when debugging from IDE - String assetsDir; - if (!AssetsDownloader.SHARE_DESKTOP_ASSETS) { - assetsDir = "testAssets/"; - FileUtil.ensureDirectoryExists(assetsDir); - } else { - assetsDir = "./"; - if (!Files.exists(Paths.get(assetsDir + "res"))) - assetsDir = "../forge-gui/"; - } + String assetsDir = "./"; + if (!Files.exists(Paths.get(assetsDir + "res"))) + assetsDir = "../forge-gui/"; // Place the file "switch_orientation.ini" to your assets folder to make the game switch to landscape orientation (unless desktopMode = true) String switchOrientationFile = assetsDir + "switch_orientation.ini"; diff --git a/forge-gui-mobile-dev/src/forge/app/Main.java b/forge-gui-mobile-dev/src/forge/app/Main.java index 040e0c28f8b..492b74f7247 100644 --- a/forge-gui-mobile-dev/src/forge/app/Main.java +++ b/forge-gui-mobile-dev/src/forge/app/Main.java @@ -2,10 +2,7 @@ package forge.app; import com.badlogic.gdx.Gdx; import forge.interfaces.IDeviceAdapter; -import forge.util.BuildInfo; -import forge.util.FileUtil; -import forge.util.OperatingSystem; -import forge.util.RestartUtil; +import forge.util.*; import org.apache.commons.lang3.tuple.Pair; import javax.imageio.ImageIO; @@ -17,6 +14,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Date; import java.util.Optional; public class Main { @@ -53,10 +51,23 @@ public class Main { return versionString; } + @Override + public String getLatestChanges(Date buildDateOriginal, Date max) { + return RSSReader.getCommitLog(buildDateOriginal, max); + } + @Override public boolean openFile(String filename) { try { - Desktop.getDesktop().open(new File(filename)); + File installer = new File(filename); + if (installer.exists()) { + if (filename.endsWith(".jar")) { + installer.setExecutable(true, false); + Desktop.getDesktop().open(installer); + } else { + Desktop.getDesktop().open(installer.getParentFile()); + } + } return true; } catch (IOException e) { e.printStackTrace(); diff --git a/forge-gui-mobile/libs/gdx-natives.jar b/forge-gui-mobile/libs/gdx-natives.jar new file mode 100644 index 00000000000..15c0b61ffe5 Binary files /dev/null and b/forge-gui-mobile/libs/gdx-natives.jar differ diff --git a/forge-gui-mobile/src/forge/Forge.java b/forge-gui-mobile/src/forge/Forge.java index 4636aa2b07a..73502b18914 100644 --- a/forge-gui-mobile/src/forge/Forge.java +++ b/forge-gui-mobile/src/forge/Forge.java @@ -76,7 +76,7 @@ public class Forge implements ApplicationListener { protected static ClosingScreen closingScreen; protected static TransitionScreen transitionScreen; public static KeyInputAdapter keyInputAdapter; - private static boolean exited; + private static boolean exited, initialized; public boolean needsUpdate = false; public static boolean advStartup = false; public static boolean safeToClose = true; @@ -199,7 +199,8 @@ public class Forge implements ApplicationListener { } else { skinName = "default"; //use default skin if preferences file doesn't exist yet } - FSkin.loadLight(skinName, splashScreen); + if (!initialized) + FSkin.loadLight(skinName, getSplashScreen()); textureFiltering = getForgePreferences().getPrefBoolean(FPref.UI_LIBGDX_TEXTURE_FILTERING); showFPS = getForgePreferences().getPrefBoolean(FPref.UI_SHOW_FPS); @@ -223,49 +224,45 @@ public class Forge implements ApplicationListener { if (totalDeviceRAM > 5000) //devices with more than 10GB RAM will have 600 Cache size, 400 Cache size for morethan 5GB RAM cacheSize = totalDeviceRAM > 10000 ? 600 : 400; } - //init cache - ImageCache.initCache(cacheSize); + if (!initialized) { + initialized = true; - //load model on background thread (using progress bar to report progress) - FThreads.invokeInBackgroundThread(() -> { + Runnable runnable = () -> { + safeToClose = false; + ImageKeys.setIsLibGDXPort(GuiBase.getInterface().isLibgdxPort()); + FModel.initialize(getSplashScreen().getProgressBar(), null); + + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblLoadingFonts")); + FSkinFont.preloadAll(locale); + + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblLoadingCardTranslations")); + CardTranslation.preloadTranslation(locale, ForgeConstants.LANG_DIR); + + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup")); + + //add reminder to preload + if (enablePreloadExtendedArt) { + if (autoCache) + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblPreloadExtendedArt") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); + else + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblPreloadExtendedArt")); + } else { + if (autoCache) + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); + else + getSplashScreen().getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup")); + } + + Gdx.app.postRunnable(() -> { + afterDbLoaded(); + /* call preloadExtendedArt here, if we put it above we will * + * get error: No OpenGL context found in the current thread. */ + preloadExtendedArt(); + }); + }; //see if app or assets need updating - AssetsDownloader.checkForUpdates(splashScreen); - if (exited) { - return; - } //don't continue if user chose to exit or couldn't download required assets - - safeToClose = false; - ImageKeys.setIsLibGDXPort(GuiBase.getInterface().isLibgdxPort()); - FModel.initialize(splashScreen.getProgressBar(), null); - - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblLoadingFonts")); - FSkinFont.preloadAll(locale); - - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblLoadingCardTranslations")); - CardTranslation.preloadTranslation(locale, ForgeConstants.LANG_DIR); - - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup")); - - //add reminder to preload - if (enablePreloadExtendedArt) { - if (autoCache) - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblPreloadExtendedArt") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); - else - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblPreloadExtendedArt")); - } else { - if (autoCache) - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup") + "\nDetected RAM: " + totalDeviceRAM + "MB. Cache size: " + cacheSize); - else - splashScreen.getProgressBar().setDescription(getLocalizer().getMessage("lblFinishingStartup")); - } - - Gdx.app.postRunnable(() -> { - afterDbLoaded(); - /* call preloadExtendedArt here, if we put it above we will * - * get error: No OpenGL context found in the current thread. */ - preloadExtendedArt(); - }); - }); + FThreads.invokeInBackgroundThread(() -> AssetsDownloader.checkForUpdates(exited, runnable)); + } } public static boolean hasGamepad() { //Classic Mode Various Screen GUI are not yet supported, needs control mapping for each screens @@ -282,6 +279,11 @@ public class Forge implements ApplicationListener { public static Graphics getGraphics() { return graphics; } + public static SplashScreen getSplashScreen() { + if (splashScreen == null) + splashScreen = new SplashScreen(); + return splashScreen; + } public static Scene getCurrentScene() { return currentScene; @@ -447,10 +449,10 @@ public class Forge implements ApplicationListener { String path = "skin/cursor" + name + ".png"; Pixmap pm = new Pixmap(Config.instance().getFile(path)); - if (name == "0") { + if ("0".equals(name)) { cursorA0 = Gdx.graphics.newCursor(pm, 0, 0); setGdxCursor(cursorA0); - } else if (name == "1") { + } else if ("1".equals(name)) { cursorA1 = Gdx.graphics.newCursor(pm, 0, 0); setGdxCursor(cursorA1); } else { @@ -461,20 +463,20 @@ public class Forge implements ApplicationListener { pm.dispose(); return; } - if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_MAGNIFIER) && name != "0") + if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_ENABLE_MAGNIFIER) && !"0".equals(name)) return; //don't change if it's disabled - if (currentScreen != null && !currentScreen.toString().toLowerCase().contains("match") && name != "0") + if (currentScreen != null && !currentScreen.toString().toLowerCase().contains("match") && !"0".equals(name)) return; // cursor indicator should be during matches if (textureRegion == null) { return; } - if (cursor0 != null && name == "0") { + if (cursor0 != null && "0".equals(name)) { setGdxCursor(cursor0); return; - } else if (cursor1 != null && name == "1") { + } else if (cursor1 != null && "1".equals(name)) { setGdxCursor(cursor1); return; - } else if (cursor2 != null && name == "2") { + } else if (cursor2 != null && "2".equals(name)) { setGdxCursor(cursor2); return; } @@ -496,10 +498,10 @@ public class Forge implements ApplicationListener { textureRegion.getRegionWidth(), // The width of the area from the other Pixmap in pixels textureRegion.getRegionHeight() // The height of the area from the other Pixmap in pixels ); - if (name == "0") { + if ("0".equals(name)) { cursor0 = Gdx.graphics.newCursor(pm, 0, 0); setGdxCursor(cursor0); - } else if (name == "1") { + } else if ("1".equals(name)) { cursor1 = Gdx.graphics.newCursor(pm, 0, 0); setGdxCursor(cursor1); } else { @@ -829,8 +831,10 @@ public class Forge implements ApplicationListener { endKeyInput(); //end key input before switching screens ForgeAnimation.endAll(); //end all active animations before switching screens currentScreen = screen0; - currentScreen.setSize(screenWidth, screenHeight); - currentScreen.onActivate(); + if (currentScreen != null) { + currentScreen.setSize(screenWidth, screenHeight); + currentScreen.onActivate(); + } } catch (Exception ex) { graphics.end(); //check if sentry is enabled, if not it will call the gui interface but here we end the graphics so we only send it via sentry.. diff --git a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java index 104840e8f4d..a55a40578ae 100644 --- a/forge-gui-mobile/src/forge/assets/AssetsDownloader.java +++ b/forge-gui-mobile/src/forge/assets/AssetsDownloader.java @@ -1,15 +1,18 @@ package forge.assets; -import java.io.File; import java.io.IOException; import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; import java.util.List; +import java.util.TimeZone; import com.badlogic.gdx.files.FileHandle; import forge.gui.GuiBase; +import forge.util.TextUtil; import org.apache.commons.lang3.StringUtils; -import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Gdx; import com.google.common.collect.ImmutableList; @@ -18,26 +21,27 @@ import forge.gui.FThreads; import forge.gui.download.GuiDownloadZipService; import forge.gui.util.SOptionPane; import forge.localinstance.properties.ForgeConstants; -import forge.screens.SplashScreen; import forge.util.FileUtil; public class AssetsDownloader { - public static final boolean SHARE_DESKTOP_ASSETS = true; //change to false to test downloading separate assets for desktop version - private final static ImmutableList downloadIgnoreExit = ImmutableList.of("Download", "Ignore", "Exit"); private final static ImmutableList downloadExit = ImmutableList.of("Download", "Exit"); //if not sharing desktop assets, check whether assets are up to date - public static void checkForUpdates(final SplashScreen splashScreen) { - if (Gdx.app.getType() == ApplicationType.Desktop && SHARE_DESKTOP_ASSETS) { return; } - + public static void checkForUpdates(boolean exited, Runnable runnable) { + if (exited) + return; + final String packageSize = GuiBase.isAndroid() ? "160MB" : "270MB"; + final String apkSize = "12MB"; final String versionString = Forge.getDeviceAdapter().getVersionString(); final boolean isSnapshots = versionString.contains("SNAPSHOT"); final String snapsURL = "https://downloads.cardforge.org/dailysnapshots/"; final String releaseURL = "https://releases.cardforge.org/forge/forge-gui-android/"; final String versionText = isSnapshots ? snapsURL + "version.txt" : releaseURL + "version.txt"; - - splashScreen.getProgressBar().setDescription("Checking for updates..."); + FileHandle assetsDir = Gdx.files.absolute(ForgeConstants.ASSETS_DIR); + FileHandle resDir = Gdx.files.absolute(ForgeConstants.RES_DIR); + boolean mandatory = false; + Forge.getSplashScreen().getProgressBar().setDescription("Checking for updates..."); String message; boolean connectedToInternet = Forge.getDeviceAdapter().isConnectedToInternet(); @@ -45,68 +49,156 @@ public class AssetsDownloader { try { URL versionUrl = new URL(versionText); String version = FileUtil.readFileToString(versionUrl); - String filename = "forge-android-" + version + "-signed-aligned.apk"; - String apkURL = isSnapshots ? snapsURL + filename : releaseURL + version + "/" + filename; - if (!StringUtils.isEmpty(version) && !versionString.equals(version)) { - splashScreen.prepareForDialogs(); + String filename = ""; + String installerURL = ""; + if (GuiBase.isAndroid()) { + filename = "forge-android-" + version + "-signed-aligned.apk"; + installerURL = isSnapshots ? snapsURL + filename : releaseURL + version + "/" + filename; + } else { + filename = isSnapshots ? "forge-installer-" + version + ".jar" : "forge-gui-desktop-" + version + ".tar.bz2"; + String releaseBZ2URL = "https://github.com/Card-Forge/forge/releases/download/forge-" + version + "/"; + String snapsBZ2URL = "https://downloads.cardforge.org/dailysnapshots/"; + installerURL = isSnapshots ? snapsBZ2URL : releaseBZ2URL; + } + //TODO build version + /*String buildver = ""; + SimpleDateFormat DateFor = TextUtil.getSimpleDate(); + Calendar calendar = Calendar.getInstance(); + Date buildDateOriginal = null; + try { + FileHandle build = Gdx.files.classpath("build.txt"); + if (build.exists()) { + SimpleDateFormat original = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + original.setTimeZone(TimeZone.getTimeZone("UTC")); + Date buildDate = original.parse(build.readString()); + buildDateOriginal = original.parse(build.readString()); + calendar.setTime(buildDate); + DateFor.setTimeZone(TimeZone.getDefault()); + buildver = "\nForge Build: " + DateFor.format(calendar.getTime()); + } + } catch (Exception e) { + e.printStackTrace(); + }*/ + + if (!StringUtils.isEmpty(version) && !versionString.equals(version) && !versionString.equalsIgnoreCase("GIT")) { + Forge.getSplashScreen().prepareForDialogs(); message = "A new version of Forge is available (" + version + ").\n" + "You are currently on an older version (" + versionString + ").\n\n" + "Would you like to update to the new version now?"; if (!Forge.getDeviceAdapter().isConnectedToWifi()) { - message += " If so, you may want to connect to wifi first. The download is around 12MB."; + message += " If so, you may want to connect to wifi first. The download is around " + (GuiBase.isAndroid() ? apkSize : packageSize) + "."; + } + if (!GuiBase.isAndroid()) { + message += Forge.getDeviceAdapter().getLatestChanges(null, null); } if (SOptionPane.showConfirmDialog(message, "New Version Available", "Update Now", "Update Later", true, true)) { - String apkFile = new GuiDownloadZipService("", "update", apkURL, - Forge.getDeviceAdapter().getDownloadsDir(), null, splashScreen.getProgressBar()).download(filename); - if (apkFile != null) { - Forge.getDeviceAdapter().openFile(apkFile); + String installer = new GuiDownloadZipService("", "update", installerURL, + Forge.getDeviceAdapter().getDownloadsDir(), null, Forge.getSplashScreen().getProgressBar()).download(filename); + if (installer != null) { + Forge.getDeviceAdapter().openFile(installer); Forge.isMobileAdventureMode = Forge.advStartup; Forge.exitAnimation(false); return; } - SOptionPane.showOptionDialog("Could not download update. " + - "Press OK to proceed without update.", "Update Failed", null, ImmutableList.of("Ok")); + switch (SOptionPane.showOptionDialog("Could not download update. " + + "Press OK to proceed without update.", "Update Failed", null, ImmutableList.of("Ok"))) { + default: + if (!GuiBase.isAndroid()) { + run(runnable); + return; + } + break; + } } + } else { + if (!GuiBase.isAndroid()) + run(runnable); } } catch (Exception e) { e.printStackTrace(); + if (!GuiBase.isAndroid()) { + run(runnable); + return; + } } - } - - //see if assets need updating - if (GuiBase.isAndroid()) { - FileHandle resDir = Gdx.files.absolute(ForgeConstants.RES_DIR); - FileHandle assetsDir = Gdx.files.absolute(ForgeConstants.ASSETS_DIR); - FileHandle advBG = Gdx.files.absolute(ForgeConstants.DEFAULT_SKINS_DIR).child(ForgeConstants.ADV_TEXTURE_BG_FILE); - if (!advBG.exists()) { - FileHandle deleteVersion = assetsDir.child("version.txt"); - if (deleteVersion.exists()) - deleteVersion.delete(); - FileHandle deleteBuild = resDir.child("build.txt"); - if (deleteBuild.exists()) - deleteBuild.delete(); - } - } - File versionFile = new File(ForgeConstants.ASSETS_DIR + "version.txt"); - if (!versionFile.exists()) { - try { - versionFile.createNewFile(); - } - catch (IOException e) { - e.printStackTrace(); - Forge.exitAnimation(false); //can't continue if this fails + } else { + if (!GuiBase.isAndroid()) { + run(runnable); return; } } - else if (versionString.equals(FileUtil.readFileToString(versionFile)) && FSkin.getSkinDir() != null) { + // non android don't have seperate package to check + if (!GuiBase.isAndroid()) { + run(runnable); + return; + } + // Android assets fallback + String build = ""; + String log = ""; + + //see if assets need updating + FileHandle advBG = Gdx.files.absolute(ForgeConstants.DEFAULT_SKINS_DIR).child(ForgeConstants.ADV_TEXTURE_BG_FILE); + if (!advBG.exists()) { + FileHandle deleteVersion = assetsDir.child("version.txt"); + if (deleteVersion.exists()) + deleteVersion.delete(); + FileHandle deleteBuild = resDir.child("build.txt"); + if (deleteBuild.exists()) + deleteBuild.delete(); + } + + FileHandle versionFile = assetsDir.child("version.txt"); + if (!versionFile.exists()) { + try { + versionFile.file().createNewFile(); + } + catch (IOException e) { + e.printStackTrace(); + Forge.isMobileAdventureMode = Forge.advStartup; + Forge.exitAnimation(false); //can't continue if this fails + return; + } + } else if (versionString.equals(FileUtil.readFileToString(versionFile.file())) && FSkin.getSkinDir() != null) { + run(runnable); return; //if version matches what had been previously saved and FSkin isn't requesting assets download, no need to download assets } - splashScreen.prepareForDialogs(); //ensure colors set up for showing message dialogs + FileHandle f = Gdx.files.classpath("build.txt"); + FileHandle t = resDir.child("build.txt"); + if (f.exists() && t.exists()) { + String buildString = f.readString(); + String target = t.readString(); + try { + Date buildDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(buildString); + Date targetDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(target); + // if res folder has same build date then continue loading assets + if (buildDate.equals(targetDate) && versionString.equals(FileUtil.readFileToString(versionFile.file()))) { + run(runnable); + return; + } + mandatory = true; + //format to local date + SimpleDateFormat original = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + original.setTimeZone(TimeZone.getTimeZone("UTC")); + targetDate = original.parse(target); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(targetDate); + SimpleDateFormat simpleDate = TextUtil.getSimpleDate(); + simpleDate.setTimeZone(TimeZone.getDefault()); + build += "Installed resources date: " + simpleDate.format(calendar.getTime()) + "\n\n"; + log = Forge.getDeviceAdapter().getLatestChanges(null, null); + } catch (Exception e) { + e.printStackTrace(); + } + } - boolean canIgnoreDownload = FSkin.getAllSkins() != null; //don't allow ignoring download if resource files haven't been previously loaded + Forge.getSplashScreen().prepareForDialogs(); //ensure colors set up for showing message dialogs + + boolean canIgnoreDownload = resDir.exists() && FSkin.getAllSkins() != null && !FileUtil.readFileToString(versionFile.file()).isEmpty(); //don't allow ignoring download if resource files haven't been previously loaded + if (mandatory && connectedToInternet) + canIgnoreDownload = false; if (!connectedToInternet) { message = "Updated resource files cannot be downloaded due to lack of internet connection.\n\n"; @@ -119,6 +211,7 @@ public class AssetsDownloader { switch (SOptionPane.showOptionDialog(message, "No Internet Connection", null, ImmutableList.of("Ok"))) { default: { if (!canIgnoreDownload) { + Forge.isMobileAdventureMode = Forge.advStartup; Forge.exitAnimation(false); //exit if can't ignore download } } @@ -128,7 +221,7 @@ public class AssetsDownloader { //prompt user whether they wish to download the updated resource files message = "There are updated resource files to download. " + - "This download is around 50MB, "; + "This download is around " + packageSize + ", "; if (Forge.getDeviceAdapter().isConnectedToWifi()) { message += "which shouldn't take long if your wifi connection is good."; } @@ -145,13 +238,18 @@ public class AssetsDownloader { options = downloadExit; } - switch (SOptionPane.showOptionDialog(message, "", null, options)) { + switch (SOptionPane.showOptionDialog(message + build + log, "", null, options)) { case 1: if (!canIgnoreDownload) { + Forge.isMobileAdventureMode = Forge.advStartup; Forge.exitAnimation(false); //exit if can't ignore download + return; + } else { + run(runnable); + return; } - return; case 2: + Forge.isMobileAdventureMode = Forge.advStartup; Forge.exitAnimation(false); return; } @@ -160,7 +258,7 @@ public class AssetsDownloader { boolean allowDeletion = Forge.androidVersion < 30 || GuiBase.isUsingAppDirectory(); String assetURL = isSnapshots ? snapsURL + "assets.zip" : releaseURL + versionString + "/" + "assets.zip"; new GuiDownloadZipService("", "resource files", assetURL, - ForgeConstants.ASSETS_DIR, ForgeConstants.RES_DIR, splashScreen.getProgressBar(), allowDeletion).downloadAndUnzip(); + ForgeConstants.ASSETS_DIR, ForgeConstants.RES_DIR, Forge.getSplashScreen().getProgressBar(), allowDeletion).downloadAndUnzip(); if (allowDeletion) FSkinFont.deleteCachedFiles(); //delete cached font files in case any skin's .ttf file changed @@ -168,18 +266,37 @@ public class AssetsDownloader { //reload light version of skin after assets updated FThreads.invokeInEdtAndWait(() -> { FSkinFont.updateAll(); //update all fonts used by splash screen - FSkin.loadLight(FSkin.getName(), splashScreen); + FSkin.loadLight(FSkin.getName(), Forge.getSplashScreen()); }); //save version string to file once assets finish downloading //so they don't need to be re-downloaded until you upgrade again - FileUtil.writeFile(versionFile, versionString); - - //add restart after assets update - String msg = allowDeletion ? "Resource update finished..." : "Forge misses some files for deletion.\nIf you encounter issues, try deleting the Forge/res folder and/or deleting Forge/cache/fonts folder and try to download and update the assets."; - switch (SOptionPane.showOptionDialog(msg, "", null, ImmutableList.of("Restart"))) { - default: - Forge.exitAnimation(true); + if (connectedToInternet) { + if (versionFile.exists()) + FileUtil.writeFile(versionFile.file(), versionString); + } + //final check if temp.zip exists then extraction is not complete... + FileHandle check = assetsDir.child("temp.zip"); + if (check.exists()) { + if (versionFile.exists()) + versionFile.delete(); + check.delete(); + } + // auto restart after update + Forge.isMobileAdventureMode = Forge.advStartup; + Forge.exitAnimation(true); + } + private static void run(Runnable toRun) { + if (toRun != null) { + if (!GuiBase.isAndroid()) { + Forge.getSplashScreen().getProgressBar().setDescription("Loading game resources..."); + } + FThreads.invokeInBackgroundThread(toRun); + return; + } + if (!GuiBase.isAndroid()) { + Forge.isMobileAdventureMode = Forge.advStartup; + Forge.exitAnimation(false); } } } diff --git a/forge-gui/release-files/CHANGES.txt b/forge-gui/release-files/CHANGES.txt index 05f0bf1829e..bf29f450212 100644 --- a/forge-gui/release-files/CHANGES.txt +++ b/forge-gui/release-files/CHANGES.txt @@ -1,2 +1,1171 @@ -- Bug fixes - -As always, this release of Forge features an assortment of bug fixes and improvements based on user feedback during the previous release run. +## Unreleased +### No issue + +**add snapshot notification button** + + +[a0c865b4b375d22](https://github.com/Card-Forge/forge/commit/a0c865b4b375d22) Anthony Calosa *2024-10-24 12:44:22* + +**format release notes** + + +[fa974504b97a676](https://github.com/Card-Forge/forge/commit/fa974504b97a676) Anthony Calosa *2024-10-24 10:38:24* + +**update TextUtil** + + +[bf3111ba036c149](https://github.com/Card-Forge/forge/commit/bf3111ba036c149) Anthony Calosa *2024-10-24 10:26:56* + +**add desktop RSSReader, update autoupdater** + + +[7a976291ba05b4c](https://github.com/Card-Forge/forge/commit/7a976291ba05b4c) Anthony Calosa *2024-10-24 10:12:04* + +**fix manifest entries** + + * BuildInfo reflects correct version + +[b26d0db07e03b54](https://github.com/Card-Forge/forge/commit/b26d0db07e03b54) Anthony Calosa *2024-10-24 01:18:32* + +**Merge pull request #6419 from Card-Forge/revert-6234-ok_shortcut** + + * Revert "gui-desktop : add keyboard shortcut to press OK/Yes button" + +[e28d041ede2ae29](https://github.com/Card-Forge/forge/commit/e28d041ede2ae29) kevlahnota *2024-10-23 23:35:01* + +**Merge pull request #6423 from kevlahnota/master2** + + * update splash closing + +[c593c812bccc3ec](https://github.com/Card-Forge/forge/commit/c593c812bccc3ec) kevlahnota *2024-10-23 23:34:00* + +**update splash closing** + + +[07d2d0a023c98af](https://github.com/Card-Forge/forge/commit/07d2d0a023c98af) Anthony Calosa *2024-10-23 23:30:16* + +**Revert "gui-desktop : add keyboard shortcut to press OK/Yes button"** + + +[76ac1e2534139e6](https://github.com/Card-Forge/forge/commit/76ac1e2534139e6) Chris H *2024-10-23 16:57:32* + +**finally renamed** + + +[f06c8c3881a3c2c](https://github.com/Card-Forge/forge/commit/f06c8c3881a3c2c) kevlahnota *2024-10-23 01:35:40* + +**update rename script** + + +[0de880c68dce8c4](https://github.com/Card-Forge/forge/commit/0de880c68dce8c4) kevlahnota *2024-10-22 23:42:34* + +**single mv workflow** + + +[f7cd6426d5b391b](https://github.com/Card-Forge/forge/commit/f7cd6426d5b391b) kevlahnota *2024-10-22 23:15:11* + +**Update snapshots-pc.yml again** + + +[f1961c03948e232](https://github.com/Card-Forge/forge/commit/f1961c03948e232) kevlahnota *2024-10-22 23:00:03* + +**Update snapshots-pc.yml** + + +[8000e80c13c984d](https://github.com/Card-Forge/forge/commit/8000e80c13c984d) kevlahnota *2024-10-22 21:55:50* + +**Merge pull request #6412 from kevlahnota/master2** + + * display locked room, fix nonrotated card panels + +[8568498b696b2d2](https://github.com/Card-Forge/forge/commit/8568498b696b2d2) kevlahnota *2024-10-22 21:49:21* + +**Merge pull request #6234 from Ayora29/ok_shortcut** + + * gui-desktop : add keyboard shortcut to press OK/Yes button + +[051ec47ff639fde](https://github.com/Card-Forge/forge/commit/051ec47ff639fde) kevlahnota *2024-10-22 21:48:04* + +**Merge pull request #6392 from CollinJ/master** + + * Fix the SpellSmith missing some cards. + +[99b0c96bfdc92bd](https://github.com/Card-Forge/forge/commit/99b0c96bfdc92bd) kevlahnota *2024-10-22 21:47:16* + +**Update attack_in_the_box.txt** + + * Closes #6416 + +[4f3dc5891a5f440](https://github.com/Card-Forge/forge/commit/4f3dc5891a5f440) tool4ever *2024-10-22 21:16:31* + +**Merge branch 'master' into ok_shortcut** + + +[2bab2f6c2b7f47c](https://github.com/Card-Forge/forge/commit/2bab2f6c2b7f47c) Chris H *2024-10-22 19:40:18* + +**Merge branch 'master' into master** + + +[a02a0a25fc5caa6](https://github.com/Card-Forge/forge/commit/a02a0a25fc5caa6) CollinJ *2024-10-22 17:12:12* + +**Merge pull request #6414 from paulsnoops/22bar** + + * Ban Leyline of Resonance in Arena Standard archive + +[dd33f9a28a69db3](https://github.com/Card-Forge/forge/commit/dd33f9a28a69db3) Paul Hammerton *2024-10-22 15:53:08* + +**Ban Leyline of Resonance in Arena Standard archive** + + +[65f72b25ed59672](https://github.com/Card-Forge/forge/commit/65f72b25ed59672) Paul Hammerton *2024-10-22 15:48:34* + +**incorporate emptyroom** + + +[310f0ea352982fb](https://github.com/Card-Forge/forge/commit/310f0ea352982fb) Anthony Calosa *2024-10-22 15:28:49* + +**update code as suggested** + + +[f7f9943436c834b](https://github.com/Card-Forge/forge/commit/f7f9943436c834b) Anthony Calosa *2024-10-22 15:05:47* + +**update better fix and replace rotate transform to spiral image (so it will not conflict with the existing rotate transform)** + + +[b9a06e14a4951e8](https://github.com/Card-Forge/forge/commit/b9a06e14a4951e8) Anthony Calosa *2024-10-22 14:36:05* + +**Merge branch 'master' into master2** + + +[f2cb01677e6afa0](https://github.com/Card-Forge/forge/commit/f2cb01677e6afa0) Anthony Calosa *2024-10-22 13:50:53* + +**display locked room, fix nonrotated card panels** + + +[1b3e3f7f7cefbd1](https://github.com/Card-Forge/forge/commit/1b3e3f7f7cefbd1) Anthony Calosa *2024-10-22 13:38:23* + +**Further improvement to PeekAndRevealAi (fix AI paying 0 for X) (#6410)** + + * - Add puzzle PS_DSK2. + * - Fix PeekAndRevealAi not paying the X mana cost. + * - Further improvement to PeekAndRevelAi. + +[84965594d057220](https://github.com/Card-Forge/forge/commit/84965594d057220) Agetian *2024-10-22 11:07:13* + +**Merge pull request #6409 from paulsnoops/edition-updates** + + * Edition updates: FDN, PW24 + +[9014e282cbeff4f](https://github.com/Card-Forge/forge/commit/9014e282cbeff4f) Paul Hammerton *2024-10-22 10:16:47* + +**Merge pull request #6407 from Ayora29/fix_token_names** + + * Fix tokens things + +[890c5f0b0dbe172](https://github.com/Card-Forge/forge/commit/890c5f0b0dbe172) Paul Hammerton *2024-10-22 10:11:59* + +**Edition updates: FDN, PW24** + + +[e05d0de220a5471](https://github.com/Card-Forge/forge/commit/e05d0de220a5471) Paul Hammerton *2024-10-22 10:11:30* + +**Fix logic for Henzie (#6402)** + + +[031cd4176d2510e](https://github.com/Card-Forge/forge/commit/031cd4176d2510e) tool4ever *2024-10-22 08:14:43* + +**Fix tokens things** + + +[18b22279df5c42f](https://github.com/Card-Forge/forge/commit/18b22279df5c42f) fanch *2024-10-22 07:59:33* + +**Update experimental_lab_staff_room.txt** + + +[9dd712c18c47ffa](https://github.com/Card-Forge/forge/commit/9dd712c18c47ffa) tool4ever *2024-10-22 05:51:45* + +**Merge pull request #6405 from kevlahnota/master2** + + * update manifest + +[32b209b47bc2218](https://github.com/Card-Forge/forge/commit/32b209b47bc2218) kevlahnota *2024-10-22 03:47:03* + +**update manifest** + + +[c5a01eb5d19a7f0](https://github.com/Card-Forge/forge/commit/c5a01eb5d19a7f0) Anthony Calosa *2024-10-22 03:34:06* + +**Merge pull request #6404 from kevlahnota/master2** + + * Fix NPE, add manifest entries to jar + +[d231af2cad35bbe](https://github.com/Card-Forge/forge/commit/d231af2cad35bbe) kevlahnota *2024-10-22 02:59:28* + +**Merge branch 'master' into master2** + + +[bfca273ca66fd93](https://github.com/Card-Forge/forge/commit/bfca273ca66fd93) Anthony Calosa *2024-10-22 02:58:54* + +**prevent NPE** + + +[5a84c9c4f4f37ad](https://github.com/Card-Forge/forge/commit/5a84c9c4f4f37ad) Anthony Calosa *2024-10-22 02:36:57* + +**add manifest entries to forge desktop/mobile jar** + + * allow launching the jar without launcher if possible + +[2aa6d9a6e645385](https://github.com/Card-Forge/forge/commit/2aa6d9a6e645385) Anthony Calosa *2024-10-22 02:18:07* + +**Fix snaps (#6403)** + + * Update snapshots-pc.yml + * Update snapshots-pc.yml + * Update snapshots-pc.yml + +[1536868d610046d](https://github.com/Card-Forge/forge/commit/1536868d610046d) Chris H *2024-10-22 01:55:05* + +**Merge branch 'master' into master2** + + * # Conflicts: + * # .github/workflows/snapshots-pc.yml + +[1ab6d82f69a9b42](https://github.com/Card-Forge/forge/commit/1ab6d82f69a9b42) Anthony Calosa *2024-10-21 22:49:11* + +**update snapshot-pc workflow** + + +[530505054645b61](https://github.com/Card-Forge/forge/commit/530505054645b61) Anthony Calosa *2024-10-21 22:25:05* + +**update snapshot-android workflow** + + +[13f0cda7f6e68c4](https://github.com/Card-Forge/forge/commit/13f0cda7f6e68c4) Anthony Calosa *2024-10-21 22:14:09* + +**Merge pull request #6401 from Card-Forge/kevlahnota-patch-3** + + * Update AudioClip.java + +[1a815b4ed7cb4f9](https://github.com/Card-Forge/forge/commit/1a815b4ed7cb4f9) kevlahnota *2024-10-21 16:21:46* + +**Update AudioClip.java** + + * Surround audio clip with try catch, seems accessing audio in lwjgl3 produce invalidid, could be thread problem. + +[b4bffe93f1670bf](https://github.com/Card-Forge/forge/commit/b4bffe93f1670bf) kevlahnota *2024-10-21 16:15:27* + +**update installer, restore the tar.bz2 archive along with the installer and try to grant permission on the shell executables.** + + +[fbf26efc605ceea](https://github.com/Card-Forge/forge/commit/fbf26efc605ceea) Anthony Calosa *2024-10-21 15:16:55* + +**update permission, include shell script to archive** + + +[ec9209ceb6389fd](https://github.com/Card-Forge/forge/commit/ec9209ceb6389fd) Anthony Calosa *2024-10-21 15:16:55* + +**pretty print xml** + + +[9a3680861164269](https://github.com/Card-Forge/forge/commit/9a3680861164269) Anthony Calosa *2024-10-21 15:16:55* + +**try to fix permission check** + + +[993578d6957d840](https://github.com/Card-Forge/forge/commit/993578d6957d840) Anthony Calosa *2024-10-21 15:16:55* + +**delete version.txt if res folder is incomplete to allow redownload** + + +[21a738e616db309](https://github.com/Card-Forge/forge/commit/21a738e616db309) Anthony Calosa *2024-10-21 15:16:55* + +**add info on permission** + + +[0d06258edbbc1ac](https://github.com/Card-Forge/forge/commit/0d06258edbbc1ac) Anthony Calosa *2024-10-21 15:16:55* + +**delete version.txt if res folder is incomplete to allow redownload** + + +[4273420da5682af](https://github.com/Card-Forge/forge/commit/4273420da5682af) Anthony Calosa *2024-10-21 14:53:56* + +**try to fix permission check** + + +[91cfd1ff3a3bb95](https://github.com/Card-Forge/forge/commit/91cfd1ff3a3bb95) Anthony Calosa *2024-10-21 13:56:23* + +**add info on permission** + + +[05ce94d36fd388c](https://github.com/Card-Forge/forge/commit/05ce94d36fd388c) Anthony Calosa *2024-10-21 12:43:54* + +**update permission, include shell script to archive** + + +[f3aa3c53edfd18b](https://github.com/Card-Forge/forge/commit/f3aa3c53edfd18b) Anthony Calosa *2024-10-21 12:35:24* + +**pretty print xml** + + +[6e9febdfc77831f](https://github.com/Card-Forge/forge/commit/6e9febdfc77831f) Anthony Calosa *2024-10-21 11:41:07* + +**update installer, restore the tar.bz2 archive along with the installer and try to grant permission on the shell executables.** + + +[995336a764e6ebc](https://github.com/Card-Forge/forge/commit/995336a764e6ebc) Anthony Calosa *2024-10-21 11:35:23* + +**Merge pull request #6399 from Card-Forge/kevlahnota-patch-2** + + * Update snapshots-pc.yml + +[281420739044acb](https://github.com/Card-Forge/forge/commit/281420739044acb) kevlahnota *2024-10-21 10:14:18* + +**Update snapshots-pc.yml** + + +[a47d4e6a6c146fb](https://github.com/Card-Forge/forge/commit/a47d4e6a6c146fb) kevlahnota *2024-10-21 10:13:49* + +**Fix AI paying 0 for PeekAndRevealAi (#6396)** + + * - Add puzzle PS_DSK2. + * - Fix PeekAndRevealAi not paying the X mana cost. + +[41c64b282a76a0e](https://github.com/Card-Forge/forge/commit/41c64b282a76a0e) Agetian *2024-10-21 09:33:47* + +**remove adventure-mac command (-XstartOnFirstThread isn't needed anymore to start on Mac)** + + +[e9fa2a5fea8b63f](https://github.com/Card-Forge/forge/commit/e9fa2a5fea8b63f) Anthony Calosa *2024-10-21 07:26:30* + +**update version code, remove redundant CURRENT_VERSION** + + +[ca5b0683d1ec79f](https://github.com/Card-Forge/forge/commit/ca5b0683d1ec79f) Anthony Calosa *2024-10-21 07:01:39* + +**Merge branch 'master' into master** + + +[94c75f1e71acb78](https://github.com/Card-Forge/forge/commit/94c75f1e71acb78) CollinJ *2024-10-21 05:05:24* + +**Merge pull request #6394 from kevlahnota/master2** + + * fix updater versionstring + +[ece577221786b62](https://github.com/Card-Forge/forge/commit/ece577221786b62) kevlahnota *2024-10-21 04:58:19* + +**update** + + +[59f672225d9af5e](https://github.com/Card-Forge/forge/commit/59f672225d9af5e) Anthony Calosa *2024-10-21 04:41:26* + +**Merge branch 'master' into master2** + + +[7203eaa07a6a053](https://github.com/Card-Forge/forge/commit/7203eaa07a6a053) Anthony Calosa *2024-10-21 04:19:02* + +**fix updater versionstring** + + +[f82236cc4f9c203](https://github.com/Card-Forge/forge/commit/f82236cc4f9c203) Anthony Calosa *2024-10-21 04:14:17* + +**Merge pull request #6393 from Card-Forge/tehdiplomat-patch-4** + + * Update snapshots-pc.yml + +[2495b02c73cc192](https://github.com/Card-Forge/forge/commit/2495b02c73cc192) Chris H *2024-10-21 03:08:17* + +**Update snapshots-pc.yml** + + * izpack needs to allow jar files + +[33c85a4f0f08e31](https://github.com/Card-Forge/forge/commit/33c85a4f0f08e31) Chris H *2024-10-21 03:07:11* + +**Merge pull request #6103 from kevlahnota/master2** + + * Update Android build (SDK 35), Java 17, LibGDX 1.13.0 + +[4e48daeadb8db9f](https://github.com/Card-Forge/forge/commit/4e48daeadb8db9f) Chris H *2024-10-21 02:55:10* + +**update pom** + + +[1979c23389ca6d9](https://github.com/Card-Forge/forge/commit/1979c23389ca6d9) Anthony Calosa *2024-10-21 01:15:57* + +**fix adventure-editor pom** + + +[612473c1fb3aedb](https://github.com/Card-Forge/forge/commit/612473c1fb3aedb) Anthony Calosa *2024-10-21 01:13:45* + +**Fix the SpellSmith missing some cards.** + + * The main issues is that getAllCards returns a card list that is unique + * by name. That menas each card only has a single rarity. In this case, + * cards like "Forbidden Orchard" and "Choke" de-deuplicate to a version of + * the card with 'S' rarity. This means that when filtering by rarity, the + * 'S' rarity will be filtered out. + * Another similar issue is that when a card exists in multiple sets with + * different rarities, you might filter to a set in which the card is 'R', + * but the de-duped version in allCards has rarity 'U', so using the cardDB + * to check the rarity to filter on doesn't work. + * When filtering by a specific set, the solution is to use the rarity of + * the card in that set. + * When not filtering by a set but filtering by rarity, we have to address + * the root cause of the de-duping. + * WHen de-duping, I changed the logic to ignore 'S' rarities. This fixes + * the rarity filter when not filtering by an edition (although if there + * are multiple rarities you still have to kind of guess). + * This has the side-effect of making the card image used something more + * legible. Before 'Choke' de-duped to the MPS_AHK set which has illegible + * text. By ignoring 'S' rarities, it not de-dups to 8ED. + * More work could probably be done to improve de-duping, but perfect + * correctness would probably involve de-duping only after filtering, which + * is likely too slow. + +[5de234aacb86a7d](https://github.com/Card-Forge/forge/commit/5de234aacb86a7d) Collin *2024-10-20 19:29:11* + +**use flatten plugin** + + +[e833b9f40088e1b](https://github.com/Card-Forge/forge/commit/e833b9f40088e1b) Anthony Calosa *2024-10-20 16:03:42* + +**remove slf4j-simple** + + +[9cf06a04daedf92](https://github.com/Card-Forge/forge/commit/9cf06a04daedf92) Anthony Calosa *2024-10-20 14:23:01* + +**Merge branch 'master' into master2** + + +[7bebf8732c8fb68](https://github.com/Card-Forge/forge/commit/7bebf8732c8fb68) Anthony Calosa *2024-10-20 13:56:30* + +**fix dependency conflict** + + +[5a1f864db0b7fc0](https://github.com/Card-Forge/forge/commit/5a1f864db0b7fc0) Anthony Calosa *2024-10-20 13:19:13* + +**Merge pull request #6386 from dracontes/rb-sld-2-marvel** + + * SLD: Marvel x MTG Superdrop + +[5a3f2ed60729a98](https://github.com/Card-Forge/forge/commit/5a3f2ed60729a98) Paul Hammerton *2024-10-20 12:30:03* + +**remove '-P'** + + +[7b714423d87b2e4](https://github.com/Card-Forge/forge/commit/7b714423d87b2e4) Anthony Calosa *2024-10-20 12:19:30* + +**fix compilation** + + +[39c8a6af3e3079f](https://github.com/Card-Forge/forge/commit/39c8a6af3e3079f) Anthony Calosa *2024-10-20 12:09:29* + +**Merge branch 'master' into master2** + + +[426e63598fd7824](https://github.com/Card-Forge/forge/commit/426e63598fd7824) Anthony Calosa *2024-10-20 10:38:41* + +**cleanup** + + +[1f596668f29b45e](https://github.com/Card-Forge/forge/commit/1f596668f29b45e) Anthony Calosa *2024-10-20 10:36:48* + +**create forge-installer** + + +[d1be72489689694](https://github.com/Card-Forge/forge/commit/d1be72489689694) Anthony Calosa *2024-10-20 10:27:14* + +**Support Black Panther** + + +[0186759bf75f356](https://github.com/Card-Forge/forge/commit/0186759bf75f356) tool4EvEr *2024-10-20 10:21:00* + +**Fix Embodiment of Agonies counting Asmoranomardicadaistinaculdacar (#6388)** + + +[98c0959d8f3a01c](https://github.com/Card-Forge/forge/commit/98c0959d8f3a01c) tool4ever *2024-10-20 10:02:48* + +**Support Captain America** + + +[cf7aa547691eff5](https://github.com/Card-Forge/forge/commit/cf7aa547691eff5) tool4EvEr *2024-10-20 08:45:16* + +**update dependency** + + +[86b58ef47903775](https://github.com/Card-Forge/forge/commit/86b58ef47903775) Anthony Calosa *2024-10-19 20:28:09* + +**update plugins** + + +[8a7866da872b726](https://github.com/Card-Forge/forge/commit/8a7866da872b726) Anthony Calosa *2024-10-19 20:00:07* + +**Update TypeLists.txt** + + +[43434e49993e052](https://github.com/Card-Forge/forge/commit/43434e49993e052) Renato Filipe Vidal Santos *2024-10-19 13:29:27* + +**Merge branch 'master' into master2** + + +[5bc364393a3725c](https://github.com/Card-Forge/forge/commit/5bc364393a3725c) Anthony Calosa *2024-10-19 12:04:26* + +**Add files via upload** + + +[26281603bb4c495](https://github.com/Card-Forge/forge/commit/26281603bb4c495) Renato Filipe Vidal Santos *2024-10-19 12:02:10* + +**Update iron_man_titan_of_innovation.txt** + + +[28a42b116b49223](https://github.com/Card-Forge/forge/commit/28a42b116b49223) Renato Filipe Vidal Santos *2024-10-19 11:43:00* + +**Update wolverine_best_there_is.txt** + + +[84eb2f28f50f9c3](https://github.com/Card-Forge/forge/commit/84eb2f28f50f9c3) Renato Filipe Vidal Santos *2024-10-19 11:42:36* + +**Update captain_america_first_avenger.txt** + + +[0a8c925a719959e](https://github.com/Card-Forge/forge/commit/0a8c925a719959e) Renato Filipe Vidal Santos *2024-10-19 11:41:51* + +**Update black_panther_wakandan_king.txt** + + +[9fb4e6e35961752](https://github.com/Card-Forge/forge/commit/9fb4e6e35961752) Renato Filipe Vidal Santos *2024-10-19 11:41:08* + +**Add files via upload** + + +[b0cc6fc49f7c2b3](https://github.com/Card-Forge/forge/commit/b0cc6fc49f7c2b3) Renato Filipe Vidal Santos *2024-10-19 11:01:29* + +**Merge pull request #6385 from paulsnoops/marvel_formats** + + * Add Marvel SLD to Vintage & Legacy Archived formats + +[42893234b36f5d8](https://github.com/Card-Forge/forge/commit/42893234b36f5d8) Paul Hammerton *2024-10-19 09:38:23* + +**Add Marvel SLD to Vintage & Legacy Archived formats** + + +[d9d89e9c0d3e24e](https://github.com/Card-Forge/forge/commit/d9d89e9c0d3e24e) Paul Hammerton *2024-10-19 09:30:37* + +**Merge pull request #6384 from paulsnoops/edition_updates** + + * Edition updates: PSPL, SLD + +[1d6d356e02221db](https://github.com/Card-Forge/forge/commit/1d6d356e02221db) Paul Hammerton *2024-10-19 09:26:29* + +**Edition updates: PSPL, SLD** + + +[af5e4eab695f4e2](https://github.com/Card-Forge/forge/commit/af5e4eab695f4e2) Paul Hammerton *2024-10-19 09:20:17* + +**Merge branch 'master' into master2** + + +[a953818a765b369](https://github.com/Card-Forge/forge/commit/a953818a765b369) Anthony Calosa *2024-10-19 07:59:18* + +**- Add puzzle PS_DSK2. (#6382)** + + +[339b04c60a22c97](https://github.com/Card-Forge/forge/commit/339b04c60a22c97) Agetian *2024-10-19 05:33:38* + +**minor cleanup** + + +[ce7a1829113b99a](https://github.com/Card-Forge/forge/commit/ce7a1829113b99a) Anthony Calosa *2024-10-19 04:39:42* + +**fix tags** + + +[677bb7b12c5f52c](https://github.com/Card-Forge/forge/commit/677bb7b12c5f52c) Anthony Calosa *2024-10-19 04:13:43* + +**fix name** + + +[8ad1f41fef764a9](https://github.com/Card-Forge/forge/commit/8ad1f41fef764a9) Anthony Calosa *2024-10-19 04:09:01* + +**refactor module to map-editor, add gdx particle editor** + + +[7f0ce0b4e78ff7e](https://github.com/Card-Forge/forge/commit/7f0ce0b4e78ff7e) Anthony Calosa *2024-10-19 04:07:36* + +**remove custom manifest entries** + + +[8ce2f61390e322c](https://github.com/Card-Forge/forge/commit/8ce2f61390e322c) kevlahnota *2024-10-18 23:19:50* + +**replacer token -> mandatory.java.args** + + +[a09de0294fc5afe](https://github.com/Card-Forge/forge/commit/a09de0294fc5afe) Anthony Calosa *2024-10-18 23:05:10* + +**Merge branch 'master' into master2** + + +[0cdcdeaa49f1273](https://github.com/Card-Forge/forge/commit/0cdcdeaa49f1273) Anthony Calosa *2024-10-18 19:08:41* + +**Merge branch 'master' into ok_shortcut** + + +[1e707dcdbf480fa](https://github.com/Card-Forge/forge/commit/1e707dcdbf480fa) Ayora29 *2024-10-18 18:09:06* + +**Merge pull request #6377 from Ayora29/fix_token_names** + + * WOC : Fix token name + +[4ee2af4e1e7dcbe](https://github.com/Card-Forge/forge/commit/4ee2af4e1e7dcbe) Paul Hammerton *2024-10-18 16:33:12* + +**Update longhorn_firebeast.txt** + + +[b2ec9c3a4990f1f](https://github.com/Card-Forge/forge/commit/b2ec9c3a4990f1f) tool4ever *2024-10-18 16:29:09* + +**update scripts** + + +[3455045f2e0f8d2](https://github.com/Card-Forge/forge/commit/3455045f2e0f8d2) Anthony Calosa *2024-10-18 15:16:00* + +**WOC : Fix token name w_1_1_pegasus_flying -> w_2_2_pegasus_flying** + + +[e7ec68147076be7](https://github.com/Card-Forge/forge/commit/e7ec68147076be7) fanch *2024-10-18 14:12:31* + +**Merge branch 'master' into ok_shortcut** + + +[b080a337bea1926](https://github.com/Card-Forge/forge/commit/b080a337bea1926) Ayora29 *2024-10-18 14:05:52* + +**Merge branch 'master' into ok_shortcut** + + * # Conflicts: + * # forge-gui-desktop/src/main/java/forge/toolbox/FOptionPane.java + +[be6f3538672fa71](https://github.com/Card-Forge/forge/commit/be6f3538672fa71) fanch *2024-10-18 13:47:10* + +**unused import** + + +[548450eb1a01a59](https://github.com/Card-Forge/forge/commit/548450eb1a01a59) Anthony Calosa *2024-10-18 12:00:55* + +**update to LibGDX 1.13.0, add ForgeAndroidApplication (modified AndroidApplication)** + + +[c1779a55d59eb28](https://github.com/Card-Forge/forge/commit/c1779a55d59eb28) Anthony Calosa *2024-10-18 11:44:30* + +**cleanup** + + +[e6caed4ced2609c](https://github.com/Card-Forge/forge/commit/e6caed4ced2609c) Anthony Calosa *2024-10-18 03:38:57* + +**test remove old build tools on modded android maven plugin** + + +[5f98543f6def913](https://github.com/Card-Forge/forge/commit/5f98543f6def913) Anthony Calosa *2024-10-18 03:28:56* + +**Merge branch 'master' into master2** + + +[e0639ba33a70d8e](https://github.com/Card-Forge/forge/commit/e0639ba33a70d8e) Anthony Calosa *2024-10-17 21:23:38* + +**test older build tools** + + +[2ec505b01a80d41](https://github.com/Card-Forge/forge/commit/2ec505b01a80d41) Anthony Calosa *2024-10-17 21:13:21* + +**Add Enduring Friendship (YDSK) (#6354)** + + +[e6a62e54fcbafd9](https://github.com/Card-Forge/forge/commit/e6a62e54fcbafd9) TwentyToedToad *2024-10-17 20:26:18* + +**Constructed as default mode (#6358)** + + * Co-authored-by: Agetian <stavdev@mail.ru> + +[2571aff4c863245](https://github.com/Card-Forge/forge/commit/2571aff4c863245) JMAilan *2024-10-17 15:58:01* + +**MH2 : Fix token name u_1_1_bird_flying -> w_1_1_bird_flying** + + +[e862f4d8ca593b2](https://github.com/Card-Forge/forge/commit/e862f4d8ca593b2) fanch *2024-10-17 15:56:23* + +**Add Chittering Illuminator (YDSK) (#6370)** + + * Add Chittering Illuminator (YDSK) + +[95eb400b19fc450](https://github.com/Card-Forge/forge/commit/95eb400b19fc450) TwentyToedToad *2024-10-17 15:55:12* + +**MH2 : Fix token name u_1_1_bird_flying -> w_1_1_bird_flying** + + +[faaec84a8b1c87d](https://github.com/Card-Forge/forge/commit/faaec84a8b1c87d) fanch *2024-10-17 15:08:28* + +**Merge branch 'master' of https://github.com/Ayora29/forge** + + +[0d63692ec66978b](https://github.com/Card-Forge/forge/commit/0d63692ec66978b) fanch *2024-10-17 15:06:59* + +**MH2 : Fix token name u_1_1_bird_flying -> w_1_1_bird_flying** + + +[ed2a4bf3bfd0a80](https://github.com/Card-Forge/forge/commit/ed2a4bf3bfd0a80) fanch *2024-10-17 15:05:39* + +**Merge branch 'master' into master2** + + +[8403bda70e949a0](https://github.com/Card-Forge/forge/commit/8403bda70e949a0) Anthony Calosa *2024-10-17 14:37:36* + +**fix** + + +[b1ba4b2c4f0aa4f](https://github.com/Card-Forge/forge/commit/b1ba4b2c4f0aa4f) Anthony Calosa *2024-10-17 14:33:30* + +**update** + + +[bde1ebc990111ee](https://github.com/Card-Forge/forge/commit/bde1ebc990111ee) Anthony Calosa *2024-10-17 14:20:46* + +**test list** + + +[54a1995572d82a0](https://github.com/Card-Forge/forge/commit/54a1995572d82a0) Anthony Calosa *2024-10-17 13:48:20* + +**Add Eager Flameguide (YDSK) (#6350)** + + +[9281f899747094a](https://github.com/Card-Forge/forge/commit/9281f899747094a) TwentyToedToad *2024-10-17 13:27:13* + +**Add Wingbright Thief (YDSK) (#6368)** + + +[0048f25db28d440](https://github.com/Card-Forge/forge/commit/0048f25db28d440) TwentyToedToad *2024-10-17 13:25:58* + +**Add Mischievous Lookout (YDSK) (#6366)** + + +[65775f87b4929dd](https://github.com/Card-Forge/forge/commit/65775f87b4929dd) TwentyToedToad *2024-10-17 13:25:14* + +**Add Unnatural Summons (YDSK) (#6367)** + + +[54396e7f714440a](https://github.com/Card-Forge/forge/commit/54396e7f714440a) TwentyToedToad *2024-10-17 13:16:45* + +**Add Golden Sidekick (YDSK) (#6362)** + + +[ace00aa5f837028](https://github.com/Card-Forge/forge/commit/ace00aa5f837028) TwentyToedToad *2024-10-17 13:11:29* + +**test tmate** + + +[dc357461d8fe0e9](https://github.com/Card-Forge/forge/commit/dc357461d8fe0e9) Anthony Calosa *2024-10-17 13:09:08* + +**Add Soul Shredder (YDSK) (#6338)** + + +[d2d38d5d2601958](https://github.com/Card-Forge/forge/commit/d2d38d5d2601958) TwentyToedToad *2024-10-17 13:03:31* + +**test min** + + +[e7814ec6d19dae6](https://github.com/Card-Forge/forge/commit/e7814ec6d19dae6) Anthony Calosa *2024-10-17 13:02:47* + +**Add Ethrimik, Imagined Fiend (YDSK) (#6339)** + + +[c44e41b4d3adec8](https://github.com/Card-Forge/forge/commit/c44e41b4d3adec8) TwentyToedToad *2024-10-17 13:02:41* + +**test again** + + +[a5d1165214ffeb8](https://github.com/Card-Forge/forge/commit/a5d1165214ffeb8) Anthony Calosa *2024-10-17 12:55:15* + +**test build-tools** + + +[1db465d17c95664](https://github.com/Card-Forge/forge/commit/1db465d17c95664) Anthony Calosa *2024-10-17 12:53:15* + +**test platform-tools** + + +[331366687e3e3f5](https://github.com/Card-Forge/forge/commit/331366687e3e3f5) Anthony Calosa *2024-10-17 12:50:55* + +**test permission** + + +[b1bc765627c41a7](https://github.com/Card-Forge/forge/commit/b1bc765627c41a7) Anthony Calosa *2024-10-17 12:23:54* + +**test android root** + + +[57b1c9e0c8be970](https://github.com/Card-Forge/forge/commit/57b1c9e0c8be970) Anthony Calosa *2024-10-17 12:18:57* + +**test without path** + + +[5b266883033daf8](https://github.com/Card-Forge/forge/commit/5b266883033daf8) Anthony Calosa *2024-10-17 11:54:43* + +**add test-build profile** + + +[97f9ce6b43d423b](https://github.com/Card-Forge/forge/commit/97f9ce6b43d423b) Anthony Calosa *2024-10-17 11:43:17* + +**Merge branch 'master' into master2** + + +[24638ecfce97f5f](https://github.com/Card-Forge/forge/commit/24638ecfce97f5f) Anthony Calosa *2024-10-17 07:56:46* + +**remove test build** + + +[e7aad18787ef230](https://github.com/Card-Forge/forge/commit/e7aad18787ef230) Anthony Calosa *2024-10-17 07:48:02* + +**update name** + + +[5c419df8b5d005b](https://github.com/Card-Forge/forge/commit/5c419df8b5d005b) Anthony Calosa *2024-10-17 07:36:38* + +**test android workflow** + + +[e1e69a48973a82f](https://github.com/Card-Forge/forge/commit/e1e69a48973a82f) Anthony Calosa *2024-10-17 07:34:29* + +**Add Glimmer Hoarder (YDSK) (#6333)** + + +[ea045f6a15ab1e3](https://github.com/Card-Forge/forge/commit/ea045f6a15ab1e3) TwentyToedToad *2024-10-17 07:08:56* + +**Add Razor Demon (#6334)** + + +[4aa7f0a4feb607e](https://github.com/Card-Forge/forge/commit/4aa7f0a4feb607e) TwentyToedToad *2024-10-17 07:07:15* + +**Add Housemeld (YDSK) (#6341)** + + +[aedd3bc521b2764](https://github.com/Card-Forge/forge/commit/aedd3bc521b2764) TwentyToedToad *2024-10-17 07:01:46* + +**Add Fear of Ridicule (YDSK) (#6343)** + + +[7c3f8b57f061392](https://github.com/Card-Forge/forge/commit/7c3f8b57f061392) TwentyToedToad *2024-10-17 06:56:28* + +**Add Replicating Terror (YDSK) (#6344)** + + +[9d8df142b4e733e](https://github.com/Card-Forge/forge/commit/9d8df142b4e733e) TwentyToedToad *2024-10-17 06:55:06* + +**Add Welcome the Darkness (YDSK) (#6346)** + + +[c3aa31cb9828e4a](https://github.com/Card-Forge/forge/commit/c3aa31cb9828e4a) TwentyToedToad *2024-10-17 06:53:50* + +**Add Anugished Recollection (YDSK) (#6347)** + + +[fbde7dca06c6d82](https://github.com/Card-Forge/forge/commit/fbde7dca06c6d82) TwentyToedToad *2024-10-17 06:52:45* + +**Add Wary Zone Guard (YDSK) (#6353)** + + +[dc6be93b25b8521](https://github.com/Card-Forge/forge/commit/dc6be93b25b8521) TwentyToedToad *2024-10-17 06:48:07* + +**Add Mangled Soulrager (YDSK) (#6364)** + + +[b5246c42cfb5132](https://github.com/Card-Forge/forge/commit/b5246c42cfb5132) TwentyToedToad *2024-10-17 06:35:55* + +**Add Polterheist (YDSK) (#6365)** + + +[47a8b72b2e53ca2](https://github.com/Card-Forge/forge/commit/47a8b72b2e53ca2) TwentyToedToad *2024-10-17 06:33:46* + +**Fix IndexOutOfBoundsException in generateParticipants (#6359)** + + * Co-authored-by: Jetz <Jetz722@gmail.com> + +[54ecbeef6e0c1fa](https://github.com/Card-Forge/forge/commit/54ecbeef6e0c1fa) Jetz72 *2024-10-17 05:03:11* + +**Sorin tweaks (#6373)** + + * update + * Update enemies.json + +[db0e188fab4b68f](https://github.com/Card-Forge/forge/commit/db0e188fab4b68f) Simisays *2024-10-17 05:01:58* + +**update version digits** + + +[e2a6dfabe8c2bac](https://github.com/Card-Forge/forge/commit/e2a6dfabe8c2bac) Anthony Calosa *2024-10-17 04:35:11* + +**update android pom** + + +[89c699b94d4bd48](https://github.com/Card-Forge/forge/commit/89c699b94d4bd48) Anthony Calosa *2024-10-17 03:34:37* + +**Merge branch 'master' into master2** + + * # Conflicts: + * # README.md + * # forge-gui-android/pom.xml + * # forge-gui-android/src/main/AndroidManifest.xml + +[0420ad4ef227a70](https://github.com/Card-Forge/forge/commit/0420ad4ef227a70) Anthony Calosa *2024-10-17 02:48:20* + +**removed version from AndroidManifest** + + +[f5b30a6826074f1](https://github.com/Card-Forge/forge/commit/f5b30a6826074f1) Hans Mackowiak *2024-10-17 01:12:02* + +**~ fix version pattern for android.manifest merger** + + +[94f183546274931](https://github.com/Card-Forge/forge/commit/94f183546274931) Hans Mackowiak *2024-10-17 01:12:02* + +**AndroidManifest** + + +[23be0c568dfe284](https://github.com/Card-Forge/forge/commit/23be0c568dfe284) Hans Mackowiak *2024-10-17 01:12:02* + +**~ update android-maven-plugin** + + +[0c5f7962e2ffc7e](https://github.com/Card-Forge/forge/commit/0c5f7962e2ffc7e) Hans Mackowiak *2024-10-17 01:12:02* + +**Update README.md** + + +[c05760bab83d5f6](https://github.com/Card-Forge/forge/commit/c05760bab83d5f6) VishalKeerthan *2024-10-17 01:09:13* + +**Update README.md** + + +[0edd7d9d87d0646](https://github.com/Card-Forge/forge/commit/0edd7d9d87d0646) VishalKeerthan *2024-10-17 01:09:13* + +**update start button colors** + + +[143f2d883fd75c1](https://github.com/Card-Forge/forge/commit/143f2d883fd75c1) Anthony Calosa *2024-10-16 21:42:26* + +**Merge branch 'master' into master2** + + +[c07329db42a594e](https://github.com/Card-Forge/forge/commit/c07329db42a594e) Anthony Calosa *2024-10-16 21:33:20* + +**Add Fear of Change (#6327)** + + +[28744ff21104549](https://github.com/Card-Forge/forge/commit/28744ff21104549) TwentyToedToad *2024-10-16 15:12:10* + +**Merge pull request #6363 from paulsnoops/slp_edition** + + * Edition updates: SLP + +[ed7ba03b5a3c45a](https://github.com/Card-Forge/forge/commit/ed7ba03b5a3c45a) Paul Hammerton *2024-10-16 14:52:36* + +**Edition updates: SLP** + + +[ffda68653319773](https://github.com/Card-Forge/forge/commit/ffda68653319773) Paul Hammerton *2024-10-16 14:37:11* + +**Merge pull request #6360 from Ayora29/fix_token_names** + + * Fix token name in C21 + +[f727371a12d7112](https://github.com/Card-Forge/forge/commit/f727371a12d7112) Paul Hammerton *2024-10-16 14:28:30* + +**update button colors** + + +[be8b77bf06e28e0](https://github.com/Card-Forge/forge/commit/be8b77bf06e28e0) Anthony Calosa *2024-10-16 14:04:44* + +**Fix token name g_4_4_phyrexian_beast -> g_4_4_fungus_beast_trample** + + +[cbefaf1984ee729](https://github.com/Card-Forge/forge/commit/cbefaf1984ee729) fanch *2024-10-16 13:15:09* + +**Merge branch 'master' into master2** + + +[d66a7ba604fdaff](https://github.com/Card-Forge/forge/commit/d66a7ba604fdaff) Anthony Calosa *2024-10-16 12:45:48* + +**Merge pull request #6337 from nwg5817/rewardRaritySort** + + * Adventure: Reward Scene Sort by Rarity + +[a1f425a8035f910](https://github.com/Card-Forge/forge/commit/a1f425a8035f910) Hans Mackowiak *2024-10-16 11:13:32* + +**Merge pull request #6335 from nwg5817/boosterQoL** + + * Adventure: Minor Booster Pack QoL Changes + +[a07cee4e768b802](https://github.com/Card-Forge/forge/commit/a07cee4e768b802) Hans Mackowiak *2024-10-16 11:12:36* + +**replace ${alpha-version} -> ${revision}** + + +[94d5fc62bd64c4f](https://github.com/Card-Forge/forge/commit/94d5fc62bd64c4f) Anthony Calosa *2024-10-16 10:16:19* + +**Merge branch 'master' into master2** + + +[059d7aae1ba89f0](https://github.com/Card-Forge/forge/commit/059d7aae1ba89f0) Anthony Calosa *2024-10-16 10:16:03* + +**Script fixes (#6356)** + + +[9d04766d1353d41](https://github.com/Card-Forge/forge/commit/9d04766d1353d41) tool4ever *2024-10-16 09:35:40* + +**Merge pull request #6357 from churrufli/netdecks161024** + + * Net Decks Archive Updates + +[4d04e49bd98a7af](https://github.com/Card-Forge/forge/commit/4d04e49bd98a7af) Paul Hammerton *2024-10-16 09:21:47* + +**Net Decks Archive Updates (Standard, Modern, Legacy, Vintage, Pioneer, Pauper)** + + +[92ee722db653a45](https://github.com/Card-Forge/forge/commit/92ee722db653a45) Churrufli *2024-10-16 09:12:14* + +**Merge branch 'master' into master2** + + +[fe83488c2184905](https://github.com/Card-Forge/forge/commit/fe83488c2184905) Anthony Calosa *2024-10-16 07:12:56* + +**Update demonic_covenant.txt (#6355)** + + +[d65dedb92a8c386](https://github.com/Card-Forge/forge/commit/d65dedb92a8c386) Fulgur14 *2024-10-16 06:32:43* + +**Merge branch 'master' into master2** + + +[9c44efc629135d4](https://github.com/Card-Forge/forge/commit/9c44efc629135d4) Anthony Calosa *2024-10-16 01:05:08* + +**Update tunnel_surveyor.txt** + + +[5f53b8995e530b5](https://github.com/Card-Forge/forge/commit/5f53b8995e530b5) Chris H *2024-10-16 00:47:04* + +**Merge branch 'master' into rewardRaritySort** + + +[38d8761fe398525](https://github.com/Card-Forge/forge/commit/38d8761fe398525) JMAilan *2024-10-15 15:46:19* + +**Merge branch 'master' into boosterQoL** + + +[965dd136bb529f6](https://github.com/Card-Forge/forge/commit/965dd136bb529f6) JMAilan *2024-10-15 15:36:57* + +**Booster QoL** + + * Remove open confirmation and disable leaving inventory scene when opening boosters. + * Change Booster Pack Inventory Name + * Old: + * Booster Pack: WAR + * New: + * War of the Sparks Booster + * Final + * Tweak + +[0a08650393d8394](https://github.com/Card-Forge/forge/commit/0a08650393d8394) Meta *2024-10-15 15:26:00* + +**Update furious_spinesplitter.txt** + + * Closes #6332 + +[83dd00e294e21e7](https://github.com/Card-Forge/forge/commit/83dd00e294e21e7) tool4ever *2024-10-15 12:41:39* + +**Merge branch 'master' into master2** + + +[ed58a68128ee77b](https://github.com/Card-Forge/forge/commit/ed58a68128ee77b) Anthony Calosa *2024-10-15 11:16:13* + +**update phase for upload since signv2 will run on verify phase and it should finish first before uploading** + + +[a565eff5fbe580e](https://github.com/Card-Forge/forge/commit/a565eff5fbe580e) Anthony Calosa *2024-10-15 11:14:45* + +**Update head_games.txt** + + +[ce70a3949f67624](https://github.com/Card-Forge/forge/commit/ce70a3949f67624) tool4ever *2024-10-15 10:51:57* + +**Update experimental_lab_staff_room.txt** + + +[8f7b782d6b97fae](https://github.com/Card-Forge/forge/commit/8f7b782d6b97fae) tool4ever *2024-10-15 10:47:26* + +**- Add DSK alt wincon achievement by Marek. (#6331)** + + +[1466346d724eb56](https://github.com/Card-Forge/forge/commit/1466346d724eb56) Agetian *2024-10-15 06:50:38* + +**quick fix for black texture** + + +[8fc3b45b1223617](https://github.com/Card-Forge/forge/commit/8fc3b45b1223617) Anthony Calosa *2024-10-15 02:55:56* + +**Merge branch 'master' into master2** + + * # Conflicts: + * # forge-adventure/pom.xml + * # forge-ai/pom.xml + * # forge-core/pom.xml + * # forge-game/pom.xml + * # forge-gui-android/AndroidManifest.xml + * # forge-gui-android/pom.xml + * # forge-gui-desktop/pom.xml + * # forge-gui-ios/pom.xml + * # forge-gui-mobile-dev/pom.xml + * # forge-gui-mobile/pom.xml + * # forge-gui-mobile/src/forge/Forge.java + * # forge-gui/pom.xml + * # forge-lda/pom.xml + * # pom.xml + +[83df147d0e87e6e](https://github.com/Card-Forge/forge/commit/83df147d0e87e6e) Anthony Calosa *2024-10-15 02:29:23* + +**Fixed non-cards for rarity sorting** + + * import + +[5b62a1ffb54a4cf](https://github.com/Card-Forge/forge/commit/5b62a1ffb54a4cf) Meta *2024-10-15 01:56:30* + +**[maven-release-plugin] prepare release forge-1.6.65** + + +[fa538bd5c90dc5d](https://github.com/Card-Forge/forge/commit/fa538bd5c90dc5d) GitHub Actions *2024-10-15 01:53:45* + +**[maven-release-plugin] prepare for next development iteration** + + +[d366bf8ffc49fb4](https://github.com/Card-Forge/forge/commit/d366bf8ffc49fb4) GitHub Actions *2024-10-15 01:53:45* + +**Manually update files that need to be updated** + + +[0475f4bafaf367f](https://github.com/Card-Forge/forge/commit/0475f4bafaf367f) Chris H *2024-10-15 01:53:45* + +**Add files via upload** + + +[3db4db0d07cb218](https://github.com/Card-Forge/forge/commit/3db4db0d07cb218) Fulgur14 *2024-10-14 23:30:33* + +**Migrate DSK upcoming** + + +[932bfb9e3301b13](https://github.com/Card-Forge/forge/commit/932bfb9e3301b13) Chris H *2024-10-14 18:22:35* + +**Add Winter Cynical Opportunist (#6325)** + + +[da712a5e49c60f8](https://github.com/Card-Forge/forge/commit/da712a5e49c60f8) Chris H *2024-10-14 18:04:30* + +**Add Experimental Lab // Staff Room (#6324)** + + +[0fb2db556bd008c](https://github.com/Card-Forge/forge/commit/0fb2db556bd008c) TwentyToedToad *2024-10-14 17:32:34* + + diff --git a/forge-gui/src/main/java/forge/download/AutoUpdater.java b/forge-gui/src/main/java/forge/download/AutoUpdater.java index 6f3d79e0631..008e8563166 100644 --- a/forge-gui/src/main/java/forge/download/AutoUpdater.java +++ b/forge-gui/src/main/java/forge/download/AutoUpdater.java @@ -88,7 +88,7 @@ public class AutoUpdater { return false; } else if (updateChannel.equals("none")) { String message = localizer.getMessage("lblYouHaventSetUpdateChannel"); - List options = ImmutableList.of(localizer.getMessage("lblCancel"), localizer.getMessage("lblRelease"), localizer.getMessage("lblSnapshot")); + List options = ImmutableList.of(localizer.getMessageorUseDefault("lblCancel", "Cancel"), localizer.getMessageorUseDefault("lblRelease", "Release"), localizer.getMessageorUseDefault("lblSnapshot", "Snapshot")); int option = SOptionPane.showOptionDialog(message, localizer.getMessage("lblManualCheck"), null, options, 0); if (option < 1) { return false; @@ -97,14 +97,14 @@ public class AutoUpdater { } if (buildVersion.contains("SNAPSHOT")) { - if (!updateChannel.equalsIgnoreCase(localizer.getMessage("lblSnapshot"))) { + if (!updateChannel.equalsIgnoreCase(localizer.getMessageorUseDefault("lblSnapshot", "Snapshot"))) { System.out.println("Snapshot build versions must use snapshot update channel to work"); return false; } versionUrlString = SNAPSHOT_VERSION_INDEX + "version.txt"; } else { - if (!updateChannel.equalsIgnoreCase(localizer.getMessage("lblRelease"))) { + if (!updateChannel.equalsIgnoreCase(localizer.getMessageorUseDefault("lblRelease", "Release"))) { System.out.println("Release build versions must use release update channel to work"); return false; } @@ -151,13 +151,13 @@ public class AutoUpdater { } private void retrieveVersion() throws MalformedURLException { - if (VERSION_FROM_METADATA && updateChannel.equalsIgnoreCase(localizer.getMessage("lblRelease"))) { + if (VERSION_FROM_METADATA && updateChannel.equalsIgnoreCase(localizer.getMessageorUseDefault("lblRelease", "Release"))) { extractVersionFromMavenRelease(); } else { URL versionUrl = new URL(versionUrlString); version = FileUtil.readFileToString(versionUrl); } - if (updateChannel.equalsIgnoreCase(localizer.getMessage("lblRelease"))) { + if (updateChannel.equalsIgnoreCase(localizer.getMessageorUseDefault("lblRelease", "Release"))) { packageUrl = RELEASE_VERSION_INDEX + "forge/forge-gui-desktop/" + version + "/forge-gui-desktop-" + version + ".tar.bz2"; } else { packageUrl = SNAPSHOT_VERSION_INDEX + "forge-installer-" + version + ".jar"; diff --git a/forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java b/forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java index bfa1da0b429..e8664ebb4b7 100644 --- a/forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java +++ b/forge-gui/src/main/java/forge/interfaces/IDeviceAdapter.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Date; public interface IDeviceAdapter { boolean isConnectedToInternet(); @@ -13,6 +14,7 @@ public interface IDeviceAdapter { boolean isTablet(); String getDownloadsDir(); String getVersionString(); + String getLatestChanges(Date buildDateOriginal, Date maxDate); boolean openFile(String filename); void setLandscapeMode(boolean landscapeMode); void preventSystemSleep(boolean preventSleep);