Skip to content

Commit

Permalink
feat: nop option for xml
Browse files Browse the repository at this point in the history
  • Loading branch information
Rast1234 committed Jan 13, 2024
1 parent f2cd974 commit 59b1d5a
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/SyncFaction.ModManager/Services/XmlHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal ListAction ParseListAction(string action) =>
_ => throw new ArgumentOutOfRangeException(nameof(action), action, "Unsupported action")
};

private XmlText? GetNodeOrSubnodeText(XmlNode node)
public XmlText? GetNodeOrSubnodeText(XmlNode node)
{
if (node.NodeType == XmlNodeType.Text)
{
Expand Down
25 changes: 25 additions & 0 deletions src/SyncFaction.ModManager/Services/XmlMagic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ private static XmlDocument ReadXmlDocument(LogicalFile file)
private void MergeRecursive(XmlNode source, XmlNode target, string? action, bool copyAttrs)
{
log.LogTrace("Merging [{src}] into [{dst}], action [{action}], copyAttrs [{copyAttrs}]", source.Name, target.Name, action, copyAttrs);

if (xmlHelper.GetNodeOrSubnodeText(source)?.Value?.Contains(XmlModels.Extensions.NopName, StringComparison.OrdinalIgnoreCase) == true)
{
log.LogTrace("Skipped merging [{src}] as no-op, not descending into [{dst}]", source.Name, target.Name);
return;
}

if (copyAttrs)
{
xmlHelper.CopyAttrs(source, target);
Expand Down Expand Up @@ -141,6 +148,12 @@ private void MergeRecursive(XmlNode source, XmlNode target, string? action, bool
/// </summary>
private void AddNew(XmlNode node, XmlNode target)
{
if (xmlHelper.GetNodeOrSubnodeText(node)?.Value?.Contains(XmlModels.Extensions.NopName, StringComparison.OrdinalIgnoreCase) == true)
{
log.LogTrace("Skipped add new [{src}] as no-op, not descending into [{dst}]", node.Name, target.Name);
return;
}

switch (node.NodeType)
{
case XmlNodeType.Element:
Expand All @@ -159,6 +172,12 @@ private void AddNew(XmlNode node, XmlNode target)

private void Add(XmlNode node, XmlNode target)
{
if (xmlHelper.GetNodeOrSubnodeText(node)?.Value?.Contains(XmlModels.Extensions.NopName, StringComparison.OrdinalIgnoreCase) == true)
{
log.LogTrace("Skipped add [{src}] as no-op, not descending into [{dst}]", node.Name, target.Name);
return;
}

switch (node.NodeType)
{
case XmlNodeType.Element:
Expand All @@ -175,6 +194,12 @@ private void Add(XmlNode node, XmlNode target)

private void CopyRecursive(XmlNode node, XmlNode target, bool copyAttrs)
{
if (xmlHelper.GetNodeOrSubnodeText(node)?.Value?.Contains(XmlModels.Extensions.NopName, StringComparison.OrdinalIgnoreCase) == true)
{
log.LogTrace("Skipped copy [{src}] as no-op, not descending into [{dst}]", node.Name, target.Name);
return;
}

if (copyAttrs)
{
xmlHelper.CopyAttrs(node, target);
Expand Down
2 changes: 1 addition & 1 deletion src/SyncFaction.ModManager/XmlModels/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,5 @@ public static XmlNode Wrap(this XmlNode node, string nodeName = HolderName)

public const string HolderName = "syncfaction_holder";

public static readonly string NoOpName = "syncfaction_noop";
public static readonly string NopName = "syncfaction_nop";
}
21 changes: 21 additions & 0 deletions src/SyncFaction.ModManager/XmlModels/ListBox.XmlHorror.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,27 @@ public bool AllowCustomCamelCase
set => AllowCustom = value;
}

[XmlAttribute(AttributeName = "ALLOWNOP")]
public bool AllowNopUppercase
{
get => AllowNop;
set => AllowNop = value;
}

[XmlAttribute(AttributeName = "allownop")]
public bool AllowNopLowercase
{
get => AllowNop;
set => AllowNop = value;
}

[XmlAttribute(AttributeName = "allowNop")]
public bool AllowNopCamelCase
{
get => AllowNop;
set => AllowNop = value;
}

[XmlAttribute(AttributeName = "SAMEOPTIONSAS")]
public string SameOptionsAsUppercase
{
Expand Down
11 changes: 11 additions & 0 deletions src/SyncFaction.ModManager/XmlModels/ListBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public partial class ListBox : Input
[XmlAttribute]
public bool AllowCustom { get; set; } = true;

/// <summary>
/// no-op option, experimental
/// </summary>
[XmlAttribute]
public bool AllowNop { get; set; } = true;

[XmlAttribute]
public string SameOptionsAs { get; set; }

Expand Down Expand Up @@ -45,6 +51,11 @@ private IEnumerable<IOption> InitDisplayOptions()
yield return xmlOption;
}

if (AllowNop)
{
yield return new NopOption();
}

if (AllowCustom)
{
yield return new CustomOption();
Expand Down
6 changes: 3 additions & 3 deletions src/SyncFaction.ModManager/XmlModels/ModInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ private IEnumerable<IChange> MirrorMiscTableChanges(IFileSystem fs, IReadOnlyLis
foreach (var change in changes)
{
var vppPaths = GetPaths(fs, change.File);
if (!vppPaths.File.EndsWith(".xtbl", StringComparison.InvariantCultureIgnoreCase))
if (!vppPaths.File.EndsWith(".xtbl", StringComparison.OrdinalIgnoreCase))
{
continue;
}
Expand Down Expand Up @@ -317,13 +317,13 @@ public VppPath GetPaths(IFileSystem fs, string rawPath)
}

var vpp = parts[1];
if (vpp.EndsWith(".vpp", StringComparison.InvariantCultureIgnoreCase))
if (vpp.EndsWith(".vpp", StringComparison.OrdinalIgnoreCase))
{
vpp += "_pc";
log.LogTrace("Patched .vpp archive extension: [{patched}]", vpp);
}

if (!vpp.EndsWith(".vpp_pc", StringComparison.InvariantCultureIgnoreCase))
if (!vpp.EndsWith(".vpp_pc", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException($"modinfo.xml references wrong vpp to edit: [{path}]. path should reference vpp_pc archive");
}
Expand Down
25 changes: 25 additions & 0 deletions src/SyncFaction.ModManager/XmlModels/NopOption.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Xml;

namespace SyncFaction.ModManager.XmlModels;

/// <summary>
/// User input with a value to ignore related operations
/// </summary>
public class NopOption : IOption
{
public XmlNode? ValueHolder
{
get
{
var fakeDoc = new XmlDocument();
var holder = fakeDoc.GetHolderNode();
holder.InnerXml = Extensions.NopName;
return holder;
}
}

/// <summary>
/// For debug printing as json
/// </summary>
public bool ShouldSerializeValueHolder() => false;
}
45 changes: 44 additions & 1 deletion src/SyncFaction.Toolbox/PegWalker.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Text.RegularExpressions;
using Microsoft.Extensions.FileSystemGlobbing;
using Microsoft.Extensions.Logging;
using SyncFaction.ModManager.Services;
Expand Down Expand Up @@ -46,7 +47,10 @@ public async Task RepackPeg(FileInfo archive, DirectoryInfo edits, DirectoryInfo
await using var c = cpu.OpenRead();
await using var g = gpu.OpenRead();
var peg = await pegArchiver.UnpackPeg(c, g, name, token);
var editFiles = edits.EnumerateFiles().ToDictionary(x => x.Name.ToLowerInvariant());
var editFiles = edits
.EnumerateFiles()
.Where(x => x.Extension.ToLowerInvariant() == ".png")
.ToDictionary(x => x.Name.ToLowerInvariant());
var logicalTextures = WalkTextures(peg, editFiles, token).ToList();

var cpuOut = new FileInfo(Path.Combine(output.FullName, $"{peg.Name}{Path.GetExtension(cpu.Name)}"));
Expand All @@ -63,12 +67,14 @@ private IEnumerable<LogicalTexture> WalkTextures(LogicalTextureArchive peg, Dict
{
if (editFiles.TryGetValue(logicalTexture.EditName, out var editFile))
{
editFiles.Remove(logicalTexture.EditName);
var png = imageConverter.ReadPngFile(editFile, token).Result;
log.LogInformation("Replacement for [{texture}]: [{file}] {w}x{h}", logicalTexture, editFile.FullName, png.Width, png.Height);
if(logicalTexture.Flags.HasFlag(TextureFlags.HasAnimTiles) && (png.Width != logicalTexture.Size.Width || png.Height != logicalTexture.Size.Height))
{
throw new InvalidOperationException($"Texture {logicalTexture.EditName} has animation tiles, can only replace with same-sized image. Expected {logicalTexture.Size}, got {png.Width}x{png.Height}");
}

var data = imageConverter.Encode(png, logicalTexture);
yield return logicalTexture with {Data = data, Size = new Size(png.Width, png.Height), DataOffset = -1};
}
Expand All @@ -77,6 +83,20 @@ private IEnumerable<LogicalTexture> WalkTextures(LogicalTextureArchive peg, Dict
yield return logicalTexture;
}
}

var newfiles = editFiles.OrderBy(x => x.Key, StringComparer.Ordinal);
foreach (var (_, file) in newfiles)
{
var png = imageConverter.ReadPngFile(file, token).Result;
var size = new Size(png.Width, png.Height);
var (format, flags, mipLevels, name) = ParseFilename(file.Name);
var stub = new LogicalTexture(size, size, new Size(0, 0), format, flags, mipLevels, -1, name, -1, -1, peg.Align, Stream.Null);
log.LogInformation("New [{texture}] from [{file}]", stub, file.FullName);
var data = imageConverter.Encode(png, stub);
yield return stub with {Data = data};
}


/*
TODO invent sane name format for new textures
* no order number (order by filename)
Expand All @@ -87,4 +107,27 @@ private IEnumerable<LogicalTexture> WalkTextures(LogicalTextureArchive peg, Dict
*/
}

private (RfgCpeg.Entry.BitmapFormat format, TextureFlags flags, int mipLevels, string name) ParseFilename(string fileName)
{
var match = nameFormat.Match(fileName.ToLowerInvariant());
var name = match.Groups["name"].Value + ".tga";
var formatString = match.Groups["format"].Value;
var mipLevels = int.Parse(match.Groups["mipLevels"].Value);

var (format, flags) = formatString switch
{
"dxt1" => (RfgCpeg.Entry.BitmapFormat.PcDxt1, TextureFlags.None),
"dxt1_srgb" => (RfgCpeg.Entry.BitmapFormat.PcDxt1, TextureFlags.Srgb),
"dxt5" => (RfgCpeg.Entry.BitmapFormat.PcDxt5, TextureFlags.None),
"dxt5_srgb" => (RfgCpeg.Entry.BitmapFormat.PcDxt5, TextureFlags.Srgb),
"rgba" => (RfgCpeg.Entry.BitmapFormat.Pc8888, TextureFlags.None),
"rgba_srgb" => (RfgCpeg.Entry.BitmapFormat.Pc8888, TextureFlags.Srgb),
_ => throw new ArgumentOutOfRangeException(nameof(formatString), formatString, "Unknown texture format from filename")
};

return (format, flags, mipLevels, name);
}

private readonly Regex nameFormat = new (@"^(?<name>.*?)\s+(?<format>.*?)\s+(?<mipLevels>\d+).png$");
}
5 changes: 5 additions & 0 deletions src/SyncFaction/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@
</TextBlock>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type modXml:NopOption}">
<TextBlock IsHitTestVisible="False" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="DarkGray">
Try to leave default value (not guaranteed)
</TextBlock>
</DataTemplate>
<ControlTemplate x:Key="TabControlTemplate" TargetType="TabControl">
<DockPanel>
<!--<Border BorderThickness="0 2 0 0" BorderBrush="LightGray" DockPanel.Dock="Bottom" />-->
Expand Down

0 comments on commit 59b1d5a

Please sign in to comment.