Skip to content

Commit

Permalink
Merge pull request #1090 from thamstras/patch-bbs-arc
Browse files Browse the repository at this point in the history
Add "bbsarc" patch mode
  • Loading branch information
shananas authored Jul 31, 2024
2 parents 0f46bee + 03bcc74 commit 30adf98
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 2 deletions.
2 changes: 1 addition & 1 deletion OpenKh.Bbs/OpenKh.Bbs.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
</PropertyGroup>

Expand Down
1 change: 0 additions & 1 deletion OpenKh.Bbs/Pmp.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Microsoft.VisualBasic.CompilerServices;
using OpenKh.Common;
using OpenKh.Common.Utils;
using OpenKh.Imaging;
Expand Down
1 change: 1 addition & 0 deletions OpenKh.Patcher/OpenKh.Patcher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\OpenKh.Bbs\OpenKh.Bbs.csproj" />
<ProjectReference Include="..\OpenKh.Command.Bdxio\OpenKh.Command.Bdxio.csproj" />
<ProjectReference Include="..\OpenKh.Common\OpenKh.Common.csproj" />
<ProjectReference Include="..\OpenKh.Egs\OpenKh.Egs.csproj" />
Expand Down
37 changes: 37 additions & 0 deletions OpenKh.Patcher/PatcherProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.IO;
using System.Linq;
using YamlDotNet.Serialization;
using OpenKh.Bbs;

namespace OpenKh.Patcher
{
Expand Down Expand Up @@ -217,6 +218,9 @@ private static void PatchFile(Context context, AssetFile assetFile, Stream strea
case "binarc":
PatchBinarc(context, assetFile, stream);
break;
case "bbsarc":
PatchBBSArc(context, assetFile, stream);
break;
case "imd":
case "imgd":
CreateImageImd(context, assetFile.Source[0]).Write(stream);
Expand Down Expand Up @@ -308,6 +312,39 @@ private static void PatchBinarc(Context context, AssetFile assetFile, Stream str
entry.Stream?.Dispose();
}

private static void PatchBBSArc(Context context, AssetFile assetFile, Stream stream)
{
var entryList = Arc.IsValid(stream) ? Arc.Read(stream).ToList() : new List<Arc.Entry>();
foreach (var file in assetFile.Source)
{
var entry = entryList.FirstOrDefault(e => e.Name == file.Name);

if (entry == null)
{
entry = new Arc.Entry()
{
Name = file.Name
};
entryList.Add(entry);
}
else if (entry.IsLink)
{
throw new Exception("Cannot patch an arc link!");
}

MemoryStream data = new MemoryStream();
if (entry.Data != null)
{
data.Write(entry.Data);
data.SetPosition(0);
}
PatchFile(context, file, data);
entry.Data = data.ToArray();
}

OpenKh.Bbs.Arc.Write(entryList, stream.SetPosition(0));
}

private static Imgd CreateImageImd(Context context, AssetFile source)
{
var srcFile = context.GetSourceModAssetPath(source.Name);
Expand Down
176 changes: 176 additions & 0 deletions OpenKh.Tests/Patcher/PatcherTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using OpenKh.Bbs;
using OpenKh.Command.Bdxio.Utils;
using OpenKh.Common;
using OpenKh.Imaging;
Expand Down Expand Up @@ -1990,6 +1991,164 @@ public void ListPatchPrztTest()
});
}

[Fact]
public void BbsArcCreateArcTest()
{
var patcher = new PatcherProcessor();
var patch = new Metadata
{
Assets = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc.arc",
Method = "bbsarc",
Source = new List<AssetFile> {
new AssetFile
{
Name = "newfile",
Method = "copy",
Source = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc/newfile.bin"
}
}
}
}
}
}
};

CreateFile(ModInputDir, "somedir/somearc/newfile.bin").Using(x =>
{
x.Write(new byte[] { 4, 5, 6, 7 });
});

patcher.Patch(AssetsInputDir, ModOutputDir, patch, ModInputDir);

AssertFileExists(ModOutputDir, patch.Assets[0].Name);
AssertArcFile("newfile", entry =>
{
Assert.Equal(4, entry.Data.Length);
Assert.Equal(new byte[] { 4, 5, 6, 7 }, entry.Data);
}, ModOutputDir, patch.Assets[0].Name);
}

[Fact]
public void BbsArcAddToArcTest()
{
var patcher = new PatcherProcessor();
var patch = new Metadata
{
Assets = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc.arc",
Method = "bbsarc",
Source = new List<AssetFile> {
new AssetFile
{
Name = "newfile",
Method = "copy",
Source = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc/newfile.bin"
}
}
}
}
}
}
};

CreateFile(AssetsInputDir, "somedir/somearc.arc").Using(x =>
{
Arc.Write(new List<Arc.Entry>
{
new Arc.Entry
{
Name = "abcd",
Data = new byte[] {0, 1, 2, 3 }
}
}, x);
});

CreateFile(ModInputDir, "somedir/somearc/newfile.bin").Using(x =>
{
x.Write(new byte[] { 4, 5, 6, 7 });
});

patcher.Patch(AssetsInputDir, ModOutputDir, patch, ModInputDir);

AssertFileExists(ModOutputDir, patch.Assets[0].Name);
AssertArcFile("abcd", entry =>
{
Assert.Equal(4, entry.Data.Length);
Assert.Equal(new byte[] { 0, 1, 2, 3 }, entry.Data);
}, ModOutputDir, patch.Assets[0].Name);
AssertArcFile("newfile", entry =>
{
Assert.Equal(4, entry.Data.Length);
Assert.Equal(new byte[] { 4, 5, 6, 7 }, entry.Data);
}, ModOutputDir, patch.Assets[0].Name);
}

[Fact]
public void BbsArcReplaceInArcTest()
{
var patcher = new PatcherProcessor();
var patch = new Metadata
{
Assets = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc.arc",
Method = "bbsarc",
Source = new List<AssetFile> {
new AssetFile
{
Name = "abcd",
Method = "copy",
Source = new List<AssetFile> {
new AssetFile
{
Name = "somedir/somearc/abcd.bin"
}
}
}
}
}
}
};

CreateFile(AssetsInputDir, "somedir/somearc.arc").Using(x =>
{
Arc.Write(new List<Arc.Entry>
{
new Arc.Entry
{
Name = "abcd",
Data = new byte[] {0, 1, 2, 3}
}
}, x);
});

CreateFile(ModInputDir, "somedir/somearc/abcd.bin").Using(x =>
{
x.Write(new byte[] { 4, 5, 6, 7 });
});

patcher.Patch(AssetsInputDir, ModOutputDir, patch, ModInputDir);

AssertFileExists(ModOutputDir, patch.Assets[0].Name);
AssertArcFile("abcd", entry =>
{
Assert.Equal(4, entry.Data.Length);
Assert.Equal(new byte[] { 4, 5, 6, 7 }, entry.Data);
}, ModOutputDir, patch.Assets[0].Name);
}

[Fact]
public void ProcessMultipleTest()
{
Expand Down Expand Up @@ -2069,6 +2228,23 @@ private static void AssertBarFile(string name, Action<Bar.Entry> assertion, para
assertion(entry);
}

private static void AssertArcFile(string name, Action<Arc.Entry> assertion, params string[] paths)
{
var filePath = Path.Join(paths);
var entries = File.OpenRead(filePath).Using(x =>
{
if (!Arc.IsValid(x))
Assert.Fail($"Not a valid Arc");
return Arc.Read(x);
});

var entry = entries.SingleOrDefault(x => x.Name == name);
if (entry == null)
throw new XunitException($"Arc Entry '{name}' not found");

assertion(entry);
}

private static Stream CreateFile(params string[] paths)
{
var filePath = Path.Join(paths);
Expand Down
16 changes: 16 additions & 0 deletions docs/tool/GUI.ModsManager/creatingMods.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This document will focus on teaching you how to create mods using the OpenKH Mod
* [przt](#przt-source-example)
* [magc](#magc-source-example)
* [objentry](#objentry-source-example)
* [bbsarc](#bbsarc-bbs)
* [Example of a Fully Complete `mod.yml` File](#an-example-of-a-fully-complete-modyml-can-be-seen-below-and-the-full-source-of-the-mod-can-be-seen-here)
* [Generating a Simple `mod.yml` for New Mod Authors](#generating-a-simple-modyml-for-new-mod-authors)
* [Publishing a Mod on GitHub](#publishing-a-mod-on-github)
Expand Down Expand Up @@ -539,6 +540,21 @@ Sora:
SpawnObject4: 0
```

### `bbsarc` (BBS)
Allows you to add/patch files inside a bbs `.arc` container without having to `copy` the entire arc file into your mod. You can use any method to patch those files, although at time of writing the only one that works for BBS files (other than `bbsarc`) is `copy`.

Asset example:

```
- name: arc/map/SW10.arc
method: bbsarc
source:
- name: sw_10.pvd
method: copy
source:
- name: sw_10.pvd
```

### An example of a fully complete mod.yml can be seen below, and the full source of the mod can be seen [here](https://github.com/OpenKH/mod-template)

```
Expand Down

0 comments on commit 30adf98

Please sign in to comment.