Added *.xml.rawappend suffix to preserve whitespace in 'misc.xml'

This commit is contained in:
Vhati 2014-08-22 04:03:21 -04:00
parent bdda972091
commit 3bd41687dd
4 changed files with 77 additions and 22 deletions

View file

@ -14,6 +14,7 @@ Changelog
- Added a Validate warning for junk files named '.dropbox' - Added a Validate warning for junk files named '.dropbox'
- Added a check during patching to skip junk files - Added a check during patching to skip junk files
- Added an error popup when the jar is double-clicked - Added an error popup when the jar is double-clicked
- Added *.xml.rawappend suffix to preserve whitespace in 'misc.xml'
- Minor optimizations to reduce memory usage - Minor optimizations to reduce memory usage
1.4: 1.4:

View file

@ -197,6 +197,22 @@ Advanced XML
edit in the wake of earlier ones. edit in the wake of earlier ones.
Raw Appending
FTL is quirky. Occasionally you may need to include non-standard XML in a
mod without elaborate parsing. For instance, "misc.xml" defines phrases
for localization, which may begin/end with a space. Normally, this
whitespace would be trimmed away, leading to ugly results in-game.
If your mod has a file named "misc.xml.rawappend", the content of that
file will be tacked onto the end of "misc.xml". Line-endings and encoding
will be standardized, but Slipstream will make no attempt to
(mis)understand the tags of either file.
You can still override existing tags by adding your own with the same
name attribute.
Commandline Commandline
Running Slipstream from a prompt can speed up development... Running Slipstream from a prompt can speed up development...

View file

@ -249,19 +249,48 @@ public class ModPatchThread extends Thread {
catch ( IOException e ) {} catch ( IOException e ) {}
} }
if ( !moddedItems.contains(innerPath) ) if ( !moddedItems.contains(innerPath) ) {
moddedItems.add( innerPath ); moddedItems.add( innerPath );
} }
} }
}
else if ( fileName.endsWith( ".xml.rawappend" ) || fileName.endsWith( ".rawappend.xml" ) ) {
innerPath = parentPath + fileName.replaceAll( "[.](?:xml[.]rawappend|rawappend[.]xml)$", ".xml" );
innerPath = checkCase( innerPath, knownPaths, knownPathsLower );
if ( !ftlP.contains( innerPath ) ) {
log.warn( String.format( "Non-existent innerPath wasn't raw appended: %s", innerPath ) );
}
else {
log.warn( String.format( "Appending xml as raw text: %s", innerPath ) );
InputStream mainStream = null;
try {
mainStream = ftlP.getInputStream(innerPath);
InputStream mergedStream = ModUtilities.appendXMLFile( mainStream, zis, "windows-1252", ftlP.getName()+":"+innerPath, modFile.getName()+":"+parentPath+fileName );
mainStream.close();
ftlP.remove( innerPath );
ftlP.add( innerPath, mergedStream );
}
finally {
try {if ( mainStream != null ) mainStream.close();}
catch ( IOException e ) {}
}
if ( !moddedItems.contains(innerPath) ) {
moddedItems.add( innerPath );
}
}
}
else if ( fileName.endsWith( ".xml" ) ) { else if ( fileName.endsWith( ".xml" ) ) {
innerPath = checkCase( innerPath, knownPaths, knownPathsLower ); innerPath = checkCase( innerPath, knownPaths, knownPathsLower );
InputStream fixedStream = ModUtilities.rebuildXMLFile( zis, "windows-1252", modFile.getName()+":"+parentPath+fileName ); InputStream fixedStream = ModUtilities.rebuildXMLFile( zis, "windows-1252", modFile.getName()+":"+parentPath+fileName );
if ( !moddedItems.contains(innerPath) ) if ( !moddedItems.contains(innerPath) ) {
moddedItems.add( innerPath ); moddedItems.add( innerPath );
else } else {
log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) ); log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) );
}
if ( ftlP.contains( innerPath ) ) if ( ftlP.contains( innerPath ) )
ftlP.remove( innerPath ); ftlP.remove( innerPath );
@ -277,10 +306,11 @@ public class ModPatchThread extends Thread {
InputStream fixedStream = ModUtilities.encodeText( fixedText, "windows-1252", modFile.getName()+":"+parentPath+fileName+" (with new EOL)" ); InputStream fixedStream = ModUtilities.encodeText( fixedText, "windows-1252", modFile.getName()+":"+parentPath+fileName+" (with new EOL)" );
if ( !moddedItems.contains(innerPath) ) if ( !moddedItems.contains(innerPath) ) {
moddedItems.add( innerPath ); moddedItems.add( innerPath );
else } else {
log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) ); log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) );
}
if ( ftlP.contains( innerPath ) ) if ( ftlP.contains( innerPath ) )
ftlP.remove( innerPath ); ftlP.remove( innerPath );
@ -289,10 +319,11 @@ public class ModPatchThread extends Thread {
else { else {
innerPath = checkCase( innerPath, knownPaths, knownPathsLower ); innerPath = checkCase( innerPath, knownPaths, knownPathsLower );
if ( !moddedItems.contains(innerPath) ) if ( !moddedItems.contains(innerPath) ) {
moddedItems.add( innerPath ); moddedItems.add( innerPath );
else } else {
log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) ); log.warn( String.format( "Clobbering earlier mods: %s", innerPath ) );
}
if ( ftlP.contains( innerPath ) ) if ( ftlP.contains( innerPath ) )
ftlP.remove( innerPath ); ftlP.remove( innerPath );

View file

@ -159,29 +159,36 @@ public class ModUtilities {
/** /**
* Semi-intelligently appends XML from one file (src) onto another (dst). * Semi-intelligently appends mainStream, with content from appendStream.
* Note: This is how patching used to work prior to SMM 1.2. * Note: This is similar to how patching used to work prior to SMM 1.2.
* *
* The two InputStreams are read, and the combined result * XML parsing/tidying does NOT take place. The new content is basically
* is returned as a new third InputStream. * tacked on as-is. Any xml declaration tags will be scrubbed from both
* streams, and a new one will be prepended.
* *
* The returned stream is a ByteArrayInputStream * The two InputStreams are read, and the combined result is returned as a
* which doesn't need closing. * new third InputStream.
*
* The returned stream is a ByteArrayInputStream which doesn't need
* closing.
* *
* The result will have CR-LF line endings and the desired encoding. * The result will have CR-LF line endings and the desired encoding.
* Note: FTL stubbornly assumes all XML is in windows-1252 encoding, * Note: FTL stubbornly assumes all XML is in windows-1252 encoding, even
* even on Linux. * on Linux.
* *
* The description arguments identify the streams for log messages. * The description arguments identify the streams for log messages.
*
* Note: SMM 1.5 changed the order of arguments (previous releases took
* the source of new content to append as the first argument).
*/ */
public static InputStream appendXMLFile( InputStream srcStream, InputStream dstStream, String encoding, String srcDescription, String dstDescription ) throws IOException { public static InputStream appendXMLFile( InputStream mainStream, InputStream appendStream, String encoding, String mainDescription, String appendDescription ) throws IOException {
Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" ); Pattern xmlDeclPtn = Pattern.compile( "<[?]xml [^>]*?[?]>\n*" );
String srcText = decodeText( srcStream, srcDescription ).text; String mainText = decodeText( mainStream, mainDescription ).text;
srcText = xmlDeclPtn.matcher(srcText).replaceFirst( "" ); mainText = xmlDeclPtn.matcher(mainText).replaceFirst( "" );
String dstText = decodeText( dstStream, dstDescription ).text; String appendText = decodeText( appendStream, appendDescription ).text;
dstText = xmlDeclPtn.matcher(dstText).replaceFirst( "" ); appendText = xmlDeclPtn.matcher(appendText).replaceFirst( "" );
// Concatenate, filtering the stream to standardize newlines and encode. // Concatenate, filtering the stream to standardize newlines and encode.
// //
@ -190,9 +197,9 @@ public class ModUtilities {
Writer writer = new EOLWriter( new OutputStreamWriter( tmpData, encoder ), "\r\n" ); Writer writer = new EOLWriter( new OutputStreamWriter( tmpData, encoder ), "\r\n" );
writer.append( "<?xml version=\"1.0\" encoding=\""+ encoding +"\"?>\n" ); writer.append( "<?xml version=\"1.0\" encoding=\""+ encoding +"\"?>\n" );
writer.append( dstText ); writer.append( mainText );
writer.append( "\n\n<!-- Appended by Slipstream -->\n\n" ); writer.append( "\n\n<!-- Appended by Slipstream -->\n\n" );
writer.append( srcText ); writer.append( appendText );
writer.append( "\n" ); writer.append( "\n" );
writer.flush(); writer.flush();
InputStream result = new ByteArrayInputStream( tmpData.toByteArray() ); InputStream result = new ByteArrayInputStream( tmpData.toByteArray() );