Merge RefreshMap and UnpackMap commands. Add regex filename filter.

This provides a single utility command for interacting with maps, that takes an arg for the map operation. The filename filter allows all maps in the mod to be operated on by default, or a regex can be passed to limit the operation to certain maps.
This commit is contained in:
RoosterDragon
2023-10-28 20:02:27 +01:00
committed by Matthias Mailänder
parent ab9b393238
commit 6b0db6699d
3 changed files with 95 additions and 100 deletions

View File

@@ -0,0 +1,95 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.UtilityCommands
{
sealed class MapCommand : IUtilityCommand
{
string IUtilityCommand.Name => "--map";
bool IUtilityCommand.ValidateArguments(string[] args)
{
return args.Length >= 2 &&
new string[] { "refresh", "unpack", "repack" }.Contains(args[1]) &&
(args.Length <= 2 || IsValidRegex(args[2]));
static bool IsValidRegex(string pattern)
{
try
{
_ = new Regex(pattern);
}
catch (ArgumentException)
{
return false;
}
return true;
}
}
[Desc("(refresh|unpack|repack) [filenameRegex=.*]",
"For maps matching regex: " +
"refresh a map to reformat map.yaml and regenerate the preview, " +
"unpack oramap files into folders, " +
"repack folders into oramap files (only if previously unpacked).")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
var filenameRegex = args.Length >= 3 ? new Regex(args[2]) : null;
// HACK: The engine code assumes that Game.modData is set.
// HACK: We know that maps can only be oramap or folders, which are ReadWrite
var modData = Game.ModData = utility.ModData;
modData.MapCache.LoadMaps();
foreach (var kv in modData.MapCache.MapLocations)
{
foreach (var mapFilename in kv.Key.Contents)
{
if (filenameRegex != null && !filenameRegex.IsMatch(mapFilename))
continue;
using (var mapPackage = kv.Key.OpenPackage(mapFilename, modData.ModFiles))
{
var map = new Map(modData, mapPackage);
switch (args[1])
{
case "refresh":
map.Save((IReadWritePackage)mapPackage);
break;
case "unpack":
if (mapPackage is ZipFileLoader.ReadWriteZipFile z)
map.Save(new Folder(z.Name.Replace(".oramap", "")));
break;
case "repack":
if (mapPackage is Folder f)
{
if (File.Exists(f.Name + ".oramap"))
{
map.Save(ZipFileLoader.Create(f.Name + ".oramap"));
Directory.Delete(f.Name, true);
}
}
break;
}
}
}
}
}
}
}

View File

@@ -1,35 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.UtilityCommands
{
sealed class RefreshMapCommand : IUtilityCommand
{
string IUtilityCommand.Name => "--refresh-map";
bool IUtilityCommand.ValidateArguments(string[] args)
{
return args.Length >= 2;
}
[Desc("MAP", "Opens and resaves a map to reformat map.yaml and regenerate the preview.")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
// HACK: The engine code assumes that Game.modData is set.
// HACK: We know that maps can only be oramap or folders, which are ReadWrite
var modData = Game.ModData = utility.ModData;
using (var package = new Folder(Platform.EngineDir).OpenPackage(args[1], modData.ModFiles))
new Map(modData, package).Save((IReadWritePackage)package);
}
}
}

View File

@@ -1,65 +0,0 @@
#region Copyright & License Information
/*
* Copyright (c) The OpenRA Developers and Contributors
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion
using System.IO;
using System.Linq;
using OpenRA.FileSystem;
namespace OpenRA.Mods.Common.UtilityCommands
{
sealed class UnpackMapCommand : IUtilityCommand
{
string IUtilityCommand.Name => "--unpack-map";
bool IUtilityCommand.ValidateArguments(string[] args)
{
return args.Length >= 2 && new string[] { "unpack", "repack" }.Contains(args[1]);
}
[Desc("(unpack|repack)", "For all maps, either unpacks oramap files into folders, or repacks folders into oramap files (only if previously unpacked).")]
void IUtilityCommand.Run(Utility utility, string[] args)
{
var unpack = args[1] == "unpack";
// HACK: The engine code assumes that Game.modData is set.
// HACK: We know that maps can only be oramap or folders, which are ReadWrite
var modData = Game.ModData = utility.ModData;
modData.MapCache.LoadMaps();
foreach (var kv in modData.MapCache.MapLocations)
{
foreach (var mapFilename in kv.Key.Contents)
{
var mapPackage = kv.Key.OpenPackage(mapFilename, modData.ModFiles);
var map = new Map(modData, mapPackage);
if (unpack)
{
if (mapPackage is ZipFileLoader.ReadWriteZipFile z)
{
map.Save(new Folder(z.Name.Replace(".oramap", "")));
}
}
else
{
if (mapPackage is Folder f)
{
if (File.Exists(f.Name + ".oramap"))
{
map.Save(ZipFileLoader.Create(f.Name + ".oramap"));
Directory.Delete(f.Name, true);
}
}
}
}
}
}
}
}