From 5c7d8f78179bda52621d3c620a12200b5f6fc4c2 Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Tue, 6 Jan 2026 04:52:25 +0300 Subject: [PATCH 1/3] Add "Assume FTL 1.6.9" flag setting --- pom.xml | 2 +- src/main/java/net/vhati/modmanager/FTLModManager.java | 1 + .../java/net/vhati/modmanager/cli/SlipstreamCLI.java | 10 +++++----- .../java/net/vhati/modmanager/core/ModUtilities.java | 8 +++++--- .../net/vhati/modmanager/core/SlipstreamConfig.java | 6 ++++++ .../java/net/vhati/modmanager/ui/ManagerFrame.java | 2 +- .../vhati/modmanager/ui/SlipstreamConfigDialog.java | 6 ++++++ 7 files changed, 25 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index b235564..560e745 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 net.vhati.modmanager ftl-mod-manager - 1.9.1 + 1.9.1.1 Slipstream Mod Manager diff --git a/src/main/java/net/vhati/modmanager/FTLModManager.java b/src/main/java/net/vhati/modmanager/FTLModManager.java index b4fa76b..539ff07 100644 --- a/src/main/java/net/vhati/modmanager/FTLModManager.java +++ b/src/main/java/net/vhati/modmanager/FTLModManager.java @@ -115,6 +115,7 @@ private static void guiInit() { props.setProperty( SlipstreamConfig.ALLOW_ZIP, "false" ); props.setProperty( SlipstreamConfig.FTL_DATS_PATH, "" ); // Prompt. props.setProperty( SlipstreamConfig.STEAM_DISTRO, "" ); // Prompt. + props.setProperty( SlipstreamConfig.ASSUME_FTL_1_6_9, "true" ); props.setProperty( SlipstreamConfig.STEAM_EXE_PATH, "" ); // Prompt. props.setProperty( SlipstreamConfig.RUN_STEAM_FTL, "" ); // Prompt. props.setProperty( SlipstreamConfig.NEVER_RUN_FTL, "false" ); diff --git a/src/main/java/net/vhati/modmanager/cli/SlipstreamCLI.java b/src/main/java/net/vhati/modmanager/cli/SlipstreamCLI.java index b8b092b..d9b4e29 100644 --- a/src/main/java/net/vhati/modmanager/cli/SlipstreamCLI.java +++ b/src/main/java/net/vhati/modmanager/cli/SlipstreamCLI.java @@ -86,6 +86,9 @@ public void uncaughtException( Thread t, Throwable e ) { DelayedDeleteHook deleteHook = new DelayedDeleteHook(); Runtime.getRuntime().addShutdownHook( deleteHook ); + File configFile = new File( "modman.cfg" ); + SlipstreamConfig appConfig = getConfig( configFile ); + if ( slipstreamCmd.validate ) { // Exits (0/1). log.info( "Validating..." ); @@ -117,7 +120,7 @@ public void uncaughtException( Thread t, Throwable e ) { } } - Report validateReport = ModUtilities.validateModFile( modFile ); + Report validateReport = ModUtilities.validateModFile( modFile, appConfig ); formatter.format( validateReport.messages, resultBuf, 0 ); resultBuf.append( "\n" ); @@ -133,13 +136,10 @@ public void uncaughtException( Thread t, Throwable e ) { System.exit( anyInvalid ? 1 : 0 ); } - File configFile = new File( "modman.cfg" ); - SlipstreamConfig appConfig = getConfig( configFile ); - if ( slipstreamCmd.listMods ) { // Exits. log.info( "Listing mods..." ); - boolean allowZip = appConfig.getProperty( SlipstreamConfig.ALLOW_ZIP, "false" ).equals( "true" ); + boolean allowZip = appConfig.getProperyAsBoolean( SlipstreamConfig.ALLOW_ZIP ); File[] modFiles = modsDir.listFiles( new ModAndDirFileFilter( allowZip, true ) ); List dirList = new ArrayList(); List fileList = new ArrayList(); diff --git a/src/main/java/net/vhati/modmanager/core/ModUtilities.java b/src/main/java/net/vhati/modmanager/core/ModUtilities.java index 4e4c361..9c0424d 100644 --- a/src/main/java/net/vhati/modmanager/core/ModUtilities.java +++ b/src/main/java/net/vhati/modmanager/core/ModUtilities.java @@ -433,8 +433,9 @@ public static boolean isJunkFile( String innerPath ) { * Checks a mod file for common problems. * * @param modFile an *.ftl file to check + * @param config app configuration */ - public static Report validateModFile( File modFile ) { + public static Report validateModFile( File modFile, SlipstreamConfig config ) { List messages = new ArrayList(); List pendingMsgs = new ArrayList(); @@ -499,7 +500,8 @@ else if ( isJunkFile( innerPath ) ) { ) ); modValid = false; } - else if ( innerPath.matches( "^.*[.]font$" ) ) { + else if ( ! config.getProperyAsBoolean(SlipstreamConfig.ASSUME_FTL_1_6_9) + && innerPath.matches( "^.*[.]font$" ) ) { pendingMsgs.add( new ReportMessage( ReportMessage.WARNING, String.format( "The *.font files introduced with FTL 1.6.1 won't work in FTL 1.01-1.5.13, which used TTF fonts." ) @@ -624,7 +626,7 @@ else if ( isTxt ) { String.format( "Windows-1252 encoding with fancy non-ASCII chars (UTF-8 is recommended for clarity): %s", charBuf.toString() ) ) ); } - else { + else if (! config.getProperyAsBoolean(SlipstreamConfig.ASSUME_FTL_1_6_9)) { // Not windows-1252. // Nag if there are chars that can't be converted to // windows-1252 (for FTL 1.01-1.5.13). diff --git a/src/main/java/net/vhati/modmanager/core/SlipstreamConfig.java b/src/main/java/net/vhati/modmanager/core/SlipstreamConfig.java index fe66234..5b17e0c 100644 --- a/src/main/java/net/vhati/modmanager/core/SlipstreamConfig.java +++ b/src/main/java/net/vhati/modmanager/core/SlipstreamConfig.java @@ -17,6 +17,7 @@ public class SlipstreamConfig { public static final String ALLOW_ZIP = "allow_zip"; public static final String FTL_DATS_PATH = "ftl_dats_path"; public static final String STEAM_DISTRO = "steam_distro"; + public static final String ASSUME_FTL_1_6_9 = "assume_ftl_1_6_9"; public static final String STEAM_EXE_PATH = "steam_exe_path"; public static final String RUN_STEAM_FTL = "run_steam_ftl"; public static final String NEVER_RUN_FTL = "never_run_ftl"; @@ -62,6 +63,10 @@ public int getPropertyAsInt( String key, int defaultValue ) { return defaultValue; } + public boolean getProperyAsBoolean( String key ) { + return config.getProperty( key, "false" ).equals( "true" ); + } + public String getProperty( String key, String defaultValue ) { return config.getProperty( key, defaultValue ); } @@ -83,6 +88,7 @@ public void writeConfig() throws IOException { userFieldsMap.put( ALLOW_ZIP, "Sets whether to treat .zip files as .ftl files. Default: false." ); userFieldsMap.put( FTL_DATS_PATH, "The path to FTL's resources folder. If invalid, you'll be prompted." ); userFieldsMap.put( STEAM_DISTRO, "If true, FTL was installed via Steam. Stops the GUI asking for a path." ); + userFieldsMap.put( ASSUME_FTL_1_6_9, "Only perform checks that are relevant to FTL 1.6.9+" ); userFieldsMap.put( STEAM_EXE_PATH, "The path to Steam's executable, if FTL was installed via Steam." ); userFieldsMap.put( RUN_STEAM_FTL, "If true, SMM will use Steam to launch FTL, if possible." ); userFieldsMap.put( NEVER_RUN_FTL, "If true, there will be no offer to run FTL after patching. Default: false." ); diff --git a/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java b/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java index 742e6f7..8e83e27 100644 --- a/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java +++ b/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java @@ -751,7 +751,7 @@ else if ( source == validateBtn ) { boolean anyInvalid = false; for ( ModFileInfo modFileInfo : modsTablePanel.getSelectedItems() ) { - Report validateReport = ModUtilities.validateModFile( modFileInfo.getFile() ); + Report validateReport = ModUtilities.validateModFile( modFileInfo.getFile(), appConfig ); ReportFormatter formatter = new ReportFormatter(); formatter.format( validateReport.messages, resultBuf, 0 ); diff --git a/src/main/java/net/vhati/modmanager/ui/SlipstreamConfigDialog.java b/src/main/java/net/vhati/modmanager/ui/SlipstreamConfigDialog.java index 85bb94d..002a4e7 100644 --- a/src/main/java/net/vhati/modmanager/ui/SlipstreamConfigDialog.java +++ b/src/main/java/net/vhati/modmanager/ui/SlipstreamConfigDialog.java @@ -30,6 +30,7 @@ public class SlipstreamConfigDialog extends JDialog implements ActionListener { protected static final String ALLOW_ZIP = SlipstreamConfig.ALLOW_ZIP; + protected static final String ASSUME_FTL_1_6_9 = SlipstreamConfig.ASSUME_FTL_1_6_9; protected static final String RUN_STEAM_FTL = SlipstreamConfig.RUN_STEAM_FTL; protected static final String NEVER_RUN_FTL = SlipstreamConfig.NEVER_RUN_FTL; protected static final String USE_DEFAULT_UI = SlipstreamConfig.USE_DEFAULT_UI; @@ -58,6 +59,9 @@ public SlipstreamConfigDialog( Frame owner, SlipstreamConfig appConfig ) { editorPanel.addRow( ALLOW_ZIP, ContentType.BOOLEAN ); editorPanel.addTextRow( "Treat .zip files as .ftl files." ); editorPanel.addSeparatorRow(); + editorPanel.addRow( ASSUME_FTL_1_6_9, ContentType.BOOLEAN ); + editorPanel.addTextRow( "Only perform checks that are relevant to FTL 1.6.9+." ); + editorPanel.addSeparatorRow(); editorPanel.addRow( RUN_STEAM_FTL, ContentType.BOOLEAN ); editorPanel.addTextRow( "Use Steam to run FTL, if possible." ); editorPanel.addSeparatorRow(); @@ -88,6 +92,7 @@ public SlipstreamConfigDialog( Frame owner, SlipstreamConfig appConfig ) { editorPanel.addFillRow(); editorPanel.getBoolean( ALLOW_ZIP ).setSelected( "true".equals( appConfig.getProperty( SlipstreamConfig.ALLOW_ZIP, "false" ) ) ); + editorPanel.getBoolean( ASSUME_FTL_1_6_9 ).setSelected( "true".equals( appConfig.getProperty( SlipstreamConfig.ASSUME_FTL_1_6_9, "true" ) ) ); editorPanel.getBoolean( RUN_STEAM_FTL ).setSelected( "true".equals( appConfig.getProperty( SlipstreamConfig.RUN_STEAM_FTL, "false" ) ) ); editorPanel.getBoolean( NEVER_RUN_FTL ).setSelected( "true".equals( appConfig.getProperty( SlipstreamConfig.NEVER_RUN_FTL, "false" ) ) ); editorPanel.getBoolean( USE_DEFAULT_UI ).setSelected( "true".equals( appConfig.getProperty( SlipstreamConfig.USE_DEFAULT_UI, "false" ) ) ); @@ -149,6 +154,7 @@ public void actionPerformed( ActionEvent e ) { if ( source == applyBtn ) { String tmp; appConfig.setProperty( SlipstreamConfig.ALLOW_ZIP, editorPanel.getBoolean( ALLOW_ZIP ).isSelected() ? "true" : "false" ); + appConfig.setProperty( SlipstreamConfig.ASSUME_FTL_1_6_9, editorPanel.getBoolean( ASSUME_FTL_1_6_9 ).isSelected() ? "true" : "false" ); appConfig.setProperty( SlipstreamConfig.RUN_STEAM_FTL, editorPanel.getBoolean( RUN_STEAM_FTL ).isSelected() ? "true" : "false" ); appConfig.setProperty( SlipstreamConfig.NEVER_RUN_FTL, editorPanel.getBoolean( NEVER_RUN_FTL ).isSelected() ? "true" : "false" ); appConfig.setProperty( SlipstreamConfig.USE_DEFAULT_UI, editorPanel.getBoolean( USE_DEFAULT_UI ).isSelected() ? "true" : "false" ); From 6c87b18cc2ce7c2f9752b4ab2f11c24ef0dc83cd Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Tue, 6 Jan 2026 05:19:25 +0300 Subject: [PATCH 2/3] Fix compilation error --- src/main/java/net/vhati/modmanager/ui/ModXMLSandbox.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/vhati/modmanager/ui/ModXMLSandbox.java b/src/main/java/net/vhati/modmanager/ui/ModXMLSandbox.java index 8a07df2..f9b47a9 100644 --- a/src/main/java/net/vhati/modmanager/ui/ModXMLSandbox.java +++ b/src/main/java/net/vhati/modmanager/ui/ModXMLSandbox.java @@ -52,6 +52,7 @@ import javax.swing.text.Caret; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.undo.CannotRedoException; import javax.swing.undo.UndoManager; @@ -535,9 +536,9 @@ private void buildTreeFromString( DefaultTreeModel treeModel, String path ) { chunk += "/"; boolean found = false; - Enumeration enumIt = currentNode.children(); + Enumeration enumIt = currentNode.children(); while ( enumIt.hasMoreElements() ) { - DefaultMutableTreeNode tmpNode = enumIt.nextElement(); + DefaultMutableTreeNode tmpNode = (DefaultMutableTreeNode)enumIt.nextElement(); if ( chunk.equals( tmpNode.getUserObject() ) ) { found = true; currentNode = tmpNode; From f503f9c60d92812ab7e7b24abf7450a5f56d085f Mon Sep 17 00:00:00 2001 From: Ivan Pozdeev Date: Tue, 6 Jan 2026 06:47:48 +0300 Subject: [PATCH 3/3] Fix "java.lang.NoSuchMethodError: java.nio.ByteBuffer.rewind" when running with JRE 9+ --- src/main/java/net/vhati/modmanager/core/ModUtilities.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/vhati/modmanager/core/ModUtilities.java b/src/main/java/net/vhati/modmanager/core/ModUtilities.java index 9c0424d..6e7c0e5 100644 --- a/src/main/java/net/vhati/modmanager/core/ModUtilities.java +++ b/src/main/java/net/vhati/modmanager/core/ModUtilities.java @@ -32,6 +32,7 @@ import java.util.zip.ZipInputStream; import ar.com.hjg.pngj.PngReader; +import java.nio.Buffer; import org.jdom2.Content; import org.jdom2.Document; @@ -128,7 +129,7 @@ public static DecodeResult decodeText( InputStream is, String description ) thro Map errorMap = new LinkedHashMap(); for ( String guess : new String[] {"UTF-8", "windows-1252"} ) { try { - byteBuffer.rewind(); + ((Buffer)byteBuffer).rewind(); byteBuffer.limit( allBytes.length ); CharsetDecoder decoder = Charset.forName( guess ).newDecoder(); result = decoder.decode( byteBuffer ).toString();