@@ -395,7 +395,7 @@ protected boolean canUseCachedMap(File cachedMap) {
395395 }
396396
397397 // Check if source map is newer
398- if (map .isPresent () && map .get (). lastModified ( ) > cachedMap .lastModified ()) {
398+ if (map .isPresent () && getSourceMapLastModified ( map .get ()) > cachedMap .lastModified ()) {
399399 WLogger .info ("Source map is newer than cache" );
400400 return false ;
401401 }
@@ -514,16 +514,69 @@ protected File ensureCachedMap(WurstGui gui) throws IOException {
514514
515515 File sourceMap = map .get ();
516516
517+ long sourceLastModified = getSourceMapLastModified (sourceMap );
517518 // If cached map doesn't exist or source is newer, update cache
518- if (!cachedMap .exists () || sourceMap . lastModified () > cachedMap .lastModified ()) {
519+ if (!cachedMap .exists () || sourceLastModified > cachedMap .lastModified ()) {
519520 WLogger .info ("Updating cached map from source" );
520521 gui .sendProgress ("Updating cached map" );
521- Files .copy (sourceMap , cachedMap );
522+ if (sourceMap .isDirectory ()) {
523+ buildArchiveFromFolder (sourceMap , cachedMap );
524+ } else {
525+ Files .copy (sourceMap , cachedMap );
526+ }
522527 }
523528
524529 return cachedMap ;
525530 }
526531
532+ protected static long getSourceMapLastModified (File sourceMap ) {
533+ if (!sourceMap .isDirectory ()) {
534+ return sourceMap .lastModified ();
535+ }
536+ try (java .util .stream .Stream <Path > files = java .nio .file .Files .walk (sourceMap .toPath ())) {
537+ return files
538+ .map (Path ::toFile )
539+ .mapToLong (File ::lastModified )
540+ .max ()
541+ .orElse (sourceMap .lastModified ());
542+ } catch (IOException e ) {
543+ WLogger .warning ("Could not inspect folder map timestamp: " + sourceMap + " (" + e .getMessage () + ")" );
544+ return sourceMap .lastModified ();
545+ }
546+ }
547+
548+ private static void buildArchiveFromFolder (File sourceFolder , File cachedMap ) throws IOException {
549+ try {
550+ java .nio .file .Files .deleteIfExists (cachedMap .toPath ());
551+ MpqEditorFactory .createEmptyArchive (cachedMap );
552+ try (MpqEditor mpqEditor = MpqEditorFactory .getEditor (Optional .of (cachedMap ))) {
553+ try (java .util .stream .Stream <Path > files = java .nio .file .Files .walk (sourceFolder .toPath ())) {
554+ List <Path > regularFiles = files
555+ .filter (java .nio .file .Files ::isRegularFile )
556+ .sorted (Comparator .comparing (path -> sourceFolder .toPath ().relativize (path ).toString ().replace ('\\' , '/' )))
557+ .collect (Collectors .toList ());
558+ for (Path file : regularFiles ) {
559+ String filenameInMpq = sourceFolder .toPath ().relativize (file ).toString ().replace ('/' , '\\' );
560+ if (isInternalMpqMetadataFile (filenameInMpq )) {
561+ continue ;
562+ }
563+ mpqEditor .insertFile (filenameInMpq , file .toFile ());
564+ }
565+ }
566+ }
567+ } catch (IOException e ) {
568+ throw e ;
569+ } catch (Exception e ) {
570+ throw new IOException ("Could not build MPQ archive from folder map: " + sourceFolder .getAbsolutePath (), e );
571+ }
572+ }
573+
574+ private static boolean isInternalMpqMetadataFile (String filenameInMpq ) {
575+ return filenameInMpq .equals ("(listfile)" )
576+ || filenameInMpq .equals ("(attributes)" )
577+ || filenameInMpq .equals ("(signature)" );
578+ }
579+
527580 private void cleanupOppositeModeCacheAndOutputs () {
528581 if (cachedMapFileName .isEmpty ()) {
529582 File cacheDir = new File (getBuildDir (), "cache" );
@@ -685,7 +738,7 @@ protected File executeBuildMapPipeline(ModelManager modelManager, WurstGui gui,
685738 throw new RequestFailedException (MessageType .Error , map .get ().getAbsolutePath () + " does not exist." );
686739 }
687740
688- mapLastModified = map .get (). lastModified ( );
741+ mapLastModified = getSourceMapLastModified ( map .get ());
689742 mapPath = map .get ().getAbsolutePath ();
690743
691744 gui .sendProgress ("Copying map" );
@@ -830,6 +883,17 @@ protected byte[] extractMapScript(Optional<File> mapCopy) throws Exception {
830883 if (!mapCopy .isPresent ()) {
831884 return null ;
832885 }
886+ if (mapCopy .get ().isDirectory ()) {
887+ File rootScript = new File (mapCopy .get (), "war3map.j" );
888+ if (rootScript .exists ()) {
889+ return java .nio .file .Files .readAllBytes (rootScript .toPath ());
890+ }
891+ File scriptsScript = new File (new File (mapCopy .get (), "scripts" ), "war3map.j" );
892+ if (scriptsScript .exists ()) {
893+ return java .nio .file .Files .readAllBytes (scriptsScript .toPath ());
894+ }
895+ return null ;
896+ }
833897 try (@ Nullable MpqEditor mpqEditor = MpqEditorFactory .getEditor (mapCopy , true )) {
834898 if (mpqEditor .hasFile ("war3map.j" )) {
835899 return mpqEditor .extractFile ("war3map.j" );
0 commit comments