Added '--global-panic' commandline arg

This commit is contained in:
Vhati 2013-09-15 01:31:48 -04:00
parent 60971d4abe
commit 2bf3860cbc
8 changed files with 49 additions and 10 deletions

View file

@ -5,6 +5,8 @@ Changelog
- Fixed advanced find tags' panic arg (was "true" all the time) - Fixed advanced find tags' panic arg (was "true" all the time)
- Fixed advanced selector tag not narrowing results when it had a value - Fixed advanced selector tag not narrowing results when it had a value
- Fixed perpetually green "Update" button - Fixed perpetually green "Update" button
- Added --global-panic commandline arg to show mod devs typoed find tags
- Added commandline tips in readme_modders.txt
1.2: 1.2:
- Added a commandline interface - Added a commandline interface

View file

@ -191,6 +191,25 @@ Advanced XML
edit in the wake of earlier ones. edit in the wake of earlier ones.
Commandline
Running Slipstream from a prompt can speed up development...
--patch Abc.ftl Def "Ghi 1.0.ftl"
Patches named mod files. Dirs can also be named, so you won't have to
re-zip for every test.
--global-panic
While patching, reveals typoed <find...> tags. Any find that yields no
matches will cause an error, as if it had panic='true'.
--runftl
Runs the game. If used with "--patch", runs afterward if successful.
Pitfalls Pitfalls
FTL Bug (fixed in 1.03.3): If a ship is modded to have level 5 shields, FTL Bug (fixed in 1.03.3): If a ship is modded to have level 5 shields,

View file

@ -56,11 +56,14 @@ public class SlipstreamCLI {
.hasArg() .hasArg()
.withArgName("DIR") .withArgName("DIR")
.create() ); .create() );
options.addOption( OptionBuilder.withLongOpt( "global-panic" )
.withDescription( "patch as if advanced find tags had panic='true'" )
.create() );
options.addOption( OptionBuilder.withLongOpt( "list-mods" ) options.addOption( OptionBuilder.withLongOpt( "list-mods" )
.withDescription( "list available mod names" ) .withDescription( "list available mod names" )
.create() ); .create() );
options.addOption( OptionBuilder.withLongOpt( "runftl" ) options.addOption( OptionBuilder.withLongOpt( "runftl" )
.withDescription( "run the game" ) .withDescription( "run the game (standalone or with 'patch')" )
.create() ); .create() );
options.addOption( OptionBuilder.withLongOpt( "patch" ) options.addOption( OptionBuilder.withLongOpt( "patch" )
.withDescription( "revert to vanilla and add named mods (if any)" ) .withDescription( "revert to vanilla and add named mods (if any)" )
@ -259,8 +262,10 @@ public class SlipstreamCLI {
resDat.datFile = new File( datsDir, "resource.dat" ); resDat.datFile = new File( datsDir, "resource.dat" );
resDat.bakFile = new File( backupDir, "resource.dat.bak" ); resDat.bakFile = new File( backupDir, "resource.dat.bak" );
boolean globalPanic = cmdline.hasOption( "global-panic" );
SilentPatchObserver patchObserver = new SilentPatchObserver(); SilentPatchObserver patchObserver = new SilentPatchObserver();
ModPatchThread patchThread = new ModPatchThread( modFiles, dataDat, resDat, patchObserver ); ModPatchThread patchThread = new ModPatchThread( modFiles, dataDat, resDat, globalPanic, patchObserver );
deleteHook.addWatchedThread( patchThread ); deleteHook.addWatchedThread( patchThread );
patchThread.start(); patchThread.start();

View file

@ -37,6 +37,7 @@ public class ModPatchThread extends Thread {
private List<File> modFiles = new ArrayList<File>(); private List<File> modFiles = new ArrayList<File>();
private BackedUpDat dataDat = null; private BackedUpDat dataDat = null;
private BackedUpDat resDat = null; private BackedUpDat resDat = null;
private boolean globalPanic = false;
private ModPatchObserver observer = null; private ModPatchObserver observer = null;
private final int progMax = 100; private final int progMax = 100;
@ -46,10 +47,11 @@ public class ModPatchThread extends Thread {
private final int progRepackMax = 5; private final int progRepackMax = 5;
private int progMilestone = 0; private int progMilestone = 0;
public ModPatchThread( List<File> modFiles, BackedUpDat dataDat, BackedUpDat resDat, ModPatchObserver observer ) { public ModPatchThread( List<File> modFiles, BackedUpDat dataDat, BackedUpDat resDat, boolean globalPanic, ModPatchObserver observer ) {
this.modFiles.addAll( modFiles ); this.modFiles.addAll( modFiles );
this.dataDat = dataDat; this.dataDat = dataDat;
this.resDat = resDat; this.resDat = resDat;
this.globalPanic = globalPanic;
this.observer = observer; this.observer = observer;
} }
@ -223,7 +225,7 @@ public class ModPatchThread extends Thread {
InputStream mainStream = null; InputStream mainStream = null;
try { try {
mainStream = ftlP.getInputStream(innerPath); mainStream = ftlP.getInputStream(innerPath);
InputStream mergedStream = ModUtilities.patchXMLFile( mainStream, zis, "windows-1252", ftlP.getName()+":"+innerPath, modFile.getName()+":"+parentPath+fileName ); InputStream mergedStream = ModUtilities.patchXMLFile( mainStream, zis, "windows-1252", globalPanic, ftlP.getName()+":"+innerPath, modFile.getName()+":"+parentPath+fileName );
mainStream.close(); mainStream.close();
ftlP.remove( innerPath ); ftlP.remove( innerPath );
ftlP.add( innerPath, mergedStream ); ftlP.add( innerPath, mergedStream );

View file

@ -207,7 +207,7 @@ public class ModUtilities {
* @see net.vhati.modmanager.core.XMLPatcher * @see net.vhati.modmanager.core.XMLPatcher
* @see net.vhati.modmanager.core.SloppyXMLOutputProcessor * @see net.vhati.modmanager.core.SloppyXMLOutputProcessor
*/ */
public static InputStream patchXMLFile( InputStream mainStream, InputStream appendStream, String encoding, String mainDescription, String appendDescription ) throws IOException, JDOMException { public static InputStream patchXMLFile( InputStream mainStream, InputStream appendStream, String encoding, boolean globalPanic, String mainDescription, String appendDescription ) throws IOException, JDOMException {
Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" ); Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" );
String mainText = decodeText( mainStream, mainDescription ).text; String mainText = decodeText( mainStream, mainDescription ).text;
@ -221,6 +221,7 @@ public class ModUtilities {
Document appendDoc = parseStrictOrSloppyXML( appendText, appendDescription+" (wrapped)" ); Document appendDoc = parseStrictOrSloppyXML( appendText, appendDescription+" (wrapped)" );
XMLPatcher patcher = new XMLPatcher(); XMLPatcher patcher = new XMLPatcher();
patcher.setGlobalPanic( globalPanic );
Document mergedDoc = patcher.patch( mainDoc, appendDoc ); Document mergedDoc = patcher.patch( mainDoc, appendDoc );
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();

View file

@ -36,6 +36,7 @@ import org.jdom2.input.SAXBuilder;
*/ */
public class XMLPatcher { public class XMLPatcher {
protected boolean globalPanic = false;
protected Namespace modNS; protected Namespace modNS;
protected Namespace modAppendNS; protected Namespace modAppendNS;
protected Namespace modOverwriteNS; protected Namespace modOverwriteNS;
@ -47,6 +48,10 @@ public class XMLPatcher {
modOverwriteNS = Namespace.getNamespace( "mod-overwrite", "mod-overwrite" ); modOverwriteNS = Namespace.getNamespace( "mod-overwrite", "mod-overwrite" );
} }
public void setGlobalPanic( boolean b ) {
globalPanic = b;
}
public Document patch( Document mainDoc, Document appendDoc ) { public Document patch( Document mainDoc, Document appendDoc ) {
Document resultDoc = mainDoc.clone(); Document resultDoc = mainDoc.clone();
@ -100,7 +105,8 @@ public class XMLPatcher {
int searchStart = getAttributeIntValue( node, "start", 0 ); int searchStart = getAttributeIntValue( node, "start", 0 );
int searchLimit = getAttributeIntValue( node, "limit", 1 ); int searchLimit = getAttributeIntValue( node, "limit", 1 );
boolean panic = getAttributeBooleanValue( node, "panic", false ); boolean panic = getAttributeBooleanValue( node, "panic", false );
if ( globalPanic ) panic = true;
if ( searchName == null || searchName.length() == 0 ) if ( searchName == null || searchName.length() == 0 )
throw new IllegalArgumentException( String.format( "<%s> requires a name attribute (%s).", node.getName(), getPathToRoot(node) ) ); throw new IllegalArgumentException( String.format( "<%s> requires a name attribute (%s).", node.getName(), getPathToRoot(node) ) );
if ( searchType != null && searchType.length() == 0 ) if ( searchType != null && searchType.length() == 0 )
@ -136,7 +142,8 @@ public class XMLPatcher {
int searchStart = getAttributeIntValue( node, "start", 0 ); int searchStart = getAttributeIntValue( node, "start", 0 );
int searchLimit = getAttributeIntValue( node, "limit", -1 ); int searchLimit = getAttributeIntValue( node, "limit", -1 );
boolean panic = getAttributeBooleanValue( node, "panic", false ); boolean panic = getAttributeBooleanValue( node, "panic", false );
if ( globalPanic ) panic = true;
if ( searchType != null && searchType.length() == 0 ) if ( searchType != null && searchType.length() == 0 )
throw new IllegalArgumentException( String.format( "<%s> type attribute, when present, can't be empty (%s).", node.getName(), getPathToRoot(node) ) ); throw new IllegalArgumentException( String.format( "<%s> type attribute, when present, can't be empty (%s).", node.getName(), getPathToRoot(node) ) );
if ( searchStart < 0 ) if ( searchStart < 0 )
@ -188,7 +195,8 @@ public class XMLPatcher {
int searchStart = getAttributeIntValue( node, "start", 0 ); int searchStart = getAttributeIntValue( node, "start", 0 );
int searchLimit = getAttributeIntValue( node, "limit", -1 ); int searchLimit = getAttributeIntValue( node, "limit", -1 );
boolean panic = getAttributeBooleanValue( node, "panic", false ); boolean panic = getAttributeBooleanValue( node, "panic", false );
if ( globalPanic ) panic = true;
if ( searchType != null && searchType.length() == 0 ) if ( searchType != null && searchType.length() == 0 )
throw new IllegalArgumentException( String.format( "<%s> type attribute, when present, can't be empty (%s).", node.getName(), getPathToRoot(node) ) ); throw new IllegalArgumentException( String.format( "<%s> type attribute, when present, can't be empty (%s).", node.getName(), getPathToRoot(node) ) );
if ( searchChildType != null && searchChildType.length() == 0 ) if ( searchChildType != null && searchChildType.length() == 0 )
@ -237,7 +245,8 @@ public class XMLPatcher {
int searchStart = getAttributeIntValue( node, "start", 0 ); int searchStart = getAttributeIntValue( node, "start", 0 );
int searchLimit = getAttributeIntValue( node, "limit", -1 ); int searchLimit = getAttributeIntValue( node, "limit", -1 );
boolean panic = getAttributeBooleanValue( node, "panic", false ); boolean panic = getAttributeBooleanValue( node, "panic", false );
if ( globalPanic ) panic = true;
if ( searchStart < 0 ) if ( searchStart < 0 )
throw new IllegalArgumentException( String.format( "<%s> 'start' attribute is not >= 0 (%s).", node.getName(), getPathToRoot(node) ) ); throw new IllegalArgumentException( String.format( "<%s> 'start' attribute is not >= 0 (%s).", node.getName(), getPathToRoot(node) ) );
if ( searchLimit < -1 ) if ( searchLimit < -1 )

View file

@ -818,7 +818,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
log.info( "" ); log.info( "" );
log.info( "Patching..." ); log.info( "Patching..." );
log.info( "" ); log.info( "" );
ModPatchThread patchThread = new ModPatchThread( modFiles, dataDat, resDat, patchDlg ); ModPatchThread patchThread = new ModPatchThread( modFiles, dataDat, resDat, false, patchDlg );
patchThread.start(); patchThread.start();
patchDlg.setVisible( true ); patchDlg.setVisible( true );

View file

@ -373,6 +373,7 @@ public class ModXMLSandbox extends JFrame implements ActionListener {
Document appendDoc = ModUtilities.parseStrictOrSloppyXML( appendText, "Sandbox Append XML" ); Document appendDoc = ModUtilities.parseStrictOrSloppyXML( appendText, "Sandbox Append XML" );
XMLPatcher patcher = new XMLPatcher(); XMLPatcher patcher = new XMLPatcher();
patcher.setGlobalPanic( false );
Document resultDoc = patcher.patch( mainDoc, appendDoc ); Document resultDoc = patcher.patch( mainDoc, appendDoc );
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();