Skip to content

Commit 82aa068

Browse files
committed
Add buildprop proc test
1 parent fd6cc3b commit 82aa068

File tree

3 files changed

+124
-17
lines changed

3 files changed

+124
-17
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using dnlib.DotNet;
6+
using Mod.Localizer.ContentFramework;
7+
using Newtonsoft.Json;
8+
using Newtonsoft.Json.Serialization;
9+
using Terraria;
10+
11+
namespace Mod.Localizer.ContentProcessor
12+
{
13+
public sealed class BuildPropertyProcessor : Processor<Content>
14+
{
15+
private readonly BuildPropHelper _helper = new BuildPropHelper();
16+
17+
public BuildPropertyProcessor(TmodFileWrapper.ITmodFile modFile, ModuleDef modModule, GameCultures culture) : base(modFile, modModule, culture)
18+
{
19+
}
20+
21+
public override IReadOnlyList<Content> DumpContents()
22+
{
23+
var json = _helper.Load(ModFile);
24+
25+
_helper.Write(ModFile, json);
26+
27+
return new List<Content>();
28+
}
29+
30+
public override void PatchContents(IReadOnlyList<Content> contents)
31+
{
32+
33+
}
34+
35+
private class BuildPropHelper
36+
{
37+
public string Load(TmodFileWrapper.ITmodFile modFile)
38+
{
39+
var prop = LoadRaw(modFile);
40+
41+
var json = JsonConvert.SerializeObject(prop, new JsonSerializerSettings
42+
{
43+
ContractResolver = new StringFieldContractResolver(),
44+
Formatting = Formatting.Indented
45+
});
46+
47+
return json;
48+
}
49+
50+
private object LoadRaw(TmodFileWrapper.ITmodFile modFile)
51+
{
52+
return _readBuildFile.Invoke(null, new[] { modFile.Instance });
53+
}
54+
55+
public void Write(TmodFileWrapper.ITmodFile modFile, string json)
56+
{
57+
var obj = JsonConvert.DeserializeObject(json, _readBuildFile.DeclaringType, new JsonSerializerSettings
58+
{
59+
ContractResolver = new StringFieldContractResolver()
60+
});
61+
62+
var info = LoadRaw(modFile);
63+
64+
foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(FieldSelector))
65+
{
66+
var replace = field.GetValue(obj);
67+
field.SetValue(info, replace);
68+
}
69+
70+
var data = (byte[])_toBytes.Invoke(info, new object[0]);
71+
modFile.Files["Info"] = data;
72+
}
73+
74+
public BuildPropHelper()
75+
{
76+
var type = typeof(BitsByte).Assembly
77+
.GetType("Terraria.ModLoader.BuildProperties");
78+
var modFileType = type.Assembly.GetType("Terraria.ModLoader.IO.TmodFile");
79+
80+
_readBuildFile = type.GetMethod("ReadModFile", BindingFlags.Static | BindingFlags.NonPublic, null, new[] { modFileType }, null);
81+
_toBytes = type.GetMethod("ToBytes", BindingFlags.Instance | BindingFlags.NonPublic);
82+
}
83+
84+
private readonly MethodInfo _readBuildFile;
85+
private readonly MethodInfo _toBytes;
86+
87+
private sealed class StringFieldContractResolver : DefaultContractResolver
88+
{
89+
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
90+
{
91+
var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
92+
.Where(FieldSelector)
93+
.Select(f => CreateProperty(f, memberSerialization))
94+
.ToList();
95+
fields.ForEach(p => { p.Writable = p.Readable = true; });
96+
return fields;
97+
}
98+
}
99+
100+
private static bool FieldSelector(FieldInfo f) => f.FieldType == typeof(string);
101+
}
102+
}
103+
}

Mod.Localizer/Mod.Localizer.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
<Compile Include="ContentFramework\TileContent.cs" />
6363
<Compile Include="ContentFramework\TranslationContent.cs" />
6464
<Compile Include="ContentProcessor\BuffProcessor.cs" />
65+
<Compile Include="ContentProcessor\BuildPropertyProcessor.cs" />
6566
<Compile Include="ContentProcessor\MiscTextProcessor.cs" />
6667
<Compile Include="ContentProcessor\NpcProcessor.cs" />
6768
<Compile Include="ContentProcessor\TileProcessor.cs" />

Mod.Localizer/TmodFileWrapper.cs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -191,31 +191,32 @@ public object CreateHandler(MethodInfo method, object instance)
191191
private sealed class TmodFile : ITmodFile
192192
{
193193
private readonly TmodFileImplementation _impl;
194-
private readonly object _modFile;
194+
195+
public object Instance { get; }
195196

196197
public TmodFile(string path, TmodFileImplementation impl)
197198
{
198199
_impl = impl;
199-
_modFile = impl.CreateTmodFile(path);
200+
Instance = impl.CreateTmodFile(path);
200201
}
201202

202203
public string Name
203204
{
204-
get => _impl.InvokeMethod<string>(_modFile, TmodFileImplementation.GetName);
205-
set => _impl.InvokeMethod<object>(_modFile, TmodFileImplementation.SetName, value);
205+
get => _impl.InvokeMethod<string>(Instance, TmodFileImplementation.GetName);
206+
set => _impl.InvokeMethod<object>(Instance, TmodFileImplementation.SetName, value);
206207
}
207208

208-
public string Path => _impl.GetFieldValue<string>(_modFile, TmodFileImplementation.Path);
209+
public string Path => _impl.GetFieldValue<string>(Instance, TmodFileImplementation.Path);
209210

210211
public Version Version
211212
{
212-
get => _impl.InvokeMethod<Version>(_modFile, TmodFileImplementation.GetVersion);
213-
set => _impl.InvokeMethod<object>(_modFile, TmodFileImplementation.SetVersion, value);
213+
get => _impl.InvokeMethod<Version>(Instance, TmodFileImplementation.GetVersion);
214+
set => _impl.InvokeMethod<object>(Instance, TmodFileImplementation.SetVersion, value);
214215
}
215216

216217
public void AddFile(string fileName, byte[] data)
217218
{
218-
_impl.InvokeMethod<object>(_modFile, TmodFileImplementation.AddFile, fileName, data);
219+
_impl.InvokeMethod<object>(Instance, TmodFileImplementation.AddFile, fileName, data);
219220
}
220221

221222
public byte[] GetMainAssembly(bool? windows = null)
@@ -238,13 +239,13 @@ public byte[] GetMainPdb(bool? windows = null)
238239
}
239240

240241
public IDictionary<string, byte[]> Files =>
241-
_impl.GetFieldValue<IDictionary<string, byte[]>>(_modFile, TmodFileImplementation.Files);
242+
_impl.GetFieldValue<IDictionary<string, byte[]>>(Instance, TmodFileImplementation.Files);
242243

243244
public bool HasFile(string fileName) =>
244-
_impl.InvokeMethod<bool>(_modFile, TmodFileImplementation.HasFile, fileName);
245+
_impl.InvokeMethod<bool>(Instance, TmodFileImplementation.HasFile, fileName);
245246

246247
public byte[] GetFile(string fileName) =>
247-
_impl.InvokeMethod<byte[]>(_modFile, TmodFileImplementation.GetFile, fileName);
248+
_impl.InvokeMethod<byte[]>(Instance, TmodFileImplementation.GetFile, fileName);
248249

249250
public void Read()
250251
{
@@ -254,9 +255,9 @@ public void Read()
254255

255256
// invoke TmodFile.Read() with state and handler
256257
// state will be random number greater than 4 (see TmodFile.cs#L19)
257-
_impl.InvokeMethod<object>(_modFile, TmodFileImplementation.Read, int.MaxValue, handler);
258+
_impl.InvokeMethod<object>(Instance, TmodFileImplementation.Read, int.MaxValue, handler);
258259

259-
var ex = _impl.GetFieldValue<Exception>(_modFile, TmodFileImplementation.ReadException);
260+
var ex = _impl.GetFieldValue<Exception>(Instance, TmodFileImplementation.ReadException);
260261
if (ex != null)
261262
{
262263
throw ex;
@@ -265,12 +266,12 @@ public void Read()
265266

266267
public void RemoveFile(string fileName)
267268
{
268-
_impl.InvokeMethod<object>(_modFile, TmodFileImplementation.RemoveFile, fileName);
269+
_impl.InvokeMethod<object>(Instance, TmodFileImplementation.RemoveFile, fileName);
269270
}
270271

271272
public void Save()
272273
{
273-
_impl.InvokeMethod<object>(_modFile, TmodFileImplementation.Save);
274+
_impl.InvokeMethod<object>(Instance, TmodFileImplementation.Save);
274275
}
275276

276277
public void Write(string path)
@@ -279,11 +280,11 @@ public void Write(string path)
279280
var originPath = Path;
280281

281282
// invoke save method
282-
_impl.SetFieldValue(_modFile, TmodFileImplementation.Path, path);
283+
_impl.SetFieldValue(Instance, TmodFileImplementation.Path, path);
283284
Save();
284285

285286
// recover its original value
286-
_impl.SetFieldValue(_modFile, TmodFileImplementation.Path, originPath);
287+
_impl.SetFieldValue(Instance, TmodFileImplementation.Path, originPath);
287288
}
288289

289290
// ReSharper disable MemberCanBePrivate.Local
@@ -324,6 +325,8 @@ public interface ITmodFile
324325
byte[] GetMainAssembly(bool? windows = null);
325326

326327
byte[] GetMainPdb(bool? windows = null);
328+
329+
object Instance { get; }
327330
}
328331
}
329332
}

0 commit comments

Comments
 (0)