Skip to content

Commit aaebbbd

Browse files
committed
[Major] gameobject added/modified
1 parent c5ef560 commit aaebbbd

File tree

1 file changed

+117
-23
lines changed

1 file changed

+117
-23
lines changed

DiffUtils.cs

Lines changed: 117 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,38 @@ public int GetHashCode(UndertaleSprite x)
4545
}
4646
}
4747
class UndertaleGameObjectComparer : IEqualityComparer<UndertaleGameObject>
48+
{
49+
public bool Equals(UndertaleGameObject? x, UndertaleGameObject? y)
50+
{
51+
if (x == null || y == null) return false;
52+
return x.Name.Content == y.Name.Content &&
53+
(x.Sprite?.Name.Content ?? "") == (y.Sprite?.Name.Content ?? "") &&
54+
(x.ParentId?.Name.Content ?? "") == (y.ParentId?.Name.Content ?? "") &&
55+
x.Visible == y.Visible &&
56+
x.Persistent == y.Persistent &&
57+
x.Awake == y.Awake &&
58+
x.CollisionShape == y.CollisionShape &&
59+
x.Events.Count == y.Events.Count;
60+
}
61+
62+
// If Equals() returns true for a pair of objects
63+
// then GetHashCode() must return the same value for these objects.
64+
65+
public int GetHashCode(UndertaleGameObject x)
66+
{
67+
//Check whether the object is null
68+
if (x == null) return 0;
69+
return x.Name.Content.GetHashCode() ^
70+
(x.Sprite?.Name.Content ?? "").GetHashCode() ^
71+
(x.ParentId?.Name.Content ?? "").GetHashCode() ^
72+
x.Visible.GetHashCode() ^
73+
x.Persistent.GetHashCode() ^
74+
x.Awake.GetHashCode() ^
75+
x.CollisionShape.GetHashCode() ^
76+
x.Events.Count.GetHashCode();
77+
}
78+
}
79+
class UndertaleGameObjectNameComparer : IEqualityComparer<UndertaleGameObject>
4880
{
4981
public bool Equals(UndertaleGameObject? x, UndertaleGameObject? y)
5082
{
@@ -64,17 +96,25 @@ public int GetHashCode(UndertaleGameObject x)
6496
}
6597
public class GameObjectSummary
6698
{
67-
public string name = "";
68-
public string spriteName = "";
69-
public string parentName = "";
70-
public bool isVisible;
71-
public bool isPersistent;
72-
public bool isAwake;
73-
public string collisionShapeFlags = "";
99+
public string name {get; set;} = "";
100+
public string spriteName {get; set;} = "";
101+
public string parentName {get; set;} = "";
102+
public bool isVisible {get; set;}
103+
public bool isPersistent {get; set;}
104+
public bool isAwake {get; set;}
105+
public string collisionShapeFlags {get; set;} = "";
106+
public List<(string, int)> Events {get; set;} = new List<(string, int)>();
74107
}
75108

76109
static public class DiffUtils
77110
{
111+
public static IEnumerable<(int, T)> Enumerate<T>(this IEnumerable<T> ienumerable)
112+
{
113+
int ind = 0;
114+
foreach(T element in ienumerable) {
115+
yield return (ind++, element);
116+
}
117+
}
78118
// thanks to Pong to acknowledge me that possibility
79119
private static unsafe bool UnsafeCompare(byte[] a1, byte[] a2)
80120
{
@@ -150,8 +190,7 @@ private static void AddedRemovedCodes(UndertaleData name, UndertaleData referenc
150190
private static void ModifiedCodes(UndertaleData name, UndertaleData reference, DirectoryInfo outputFolder)
151191
{
152192
using MemoryStream ms = new();
153-
SharpSerializerBinarySettings settings = new(BinarySerializationMode.Burst);
154-
SharpSerializer burstSerializer = new(settings);
193+
SharpSerializer burstSerializer = new(new SharpSerializerBinarySettings(BinarySerializationMode.Burst));
155194

156195
GlobalDecompileContext contextName = new(name, false);
157196
GlobalDecompileContext contextRef = new(reference, false);
@@ -206,34 +245,89 @@ private static void AddedRemovedObjects(UndertaleData name, UndertaleData refere
206245
DirectoryInfo dirAddedObject = new(Path.Join(outputFolder.FullName, Path.DirectorySeparatorChar.ToString(), "AddedGameObjects"));
207246
dirAddedObject.Create();
208247

209-
IEnumerable<UndertaleGameObject> added = name.GameObjects.Except(reference.GameObjects, new UndertaleGameObjectComparer());
210-
IEnumerable<UndertaleGameObject> removed = reference.GameObjects.Except(name.GameObjects, new UndertaleGameObjectComparer());
248+
IEnumerable<UndertaleGameObject> added = name.GameObjects.Except(reference.GameObjects, new UndertaleGameObjectNameComparer());
249+
IEnumerable<UndertaleGameObject> removed = reference.GameObjects.Except(name.GameObjects, new UndertaleGameObjectNameComparer());
211250
using (StreamWriter sw = new(Path.Join(outputFolder.FullName, Path.DirectorySeparatorChar.ToString(), $"addedGameObjects.txt")))
212251
{
213252
foreach(UndertaleGameObject ob in added)
214253
{
215254
sw.WriteLine(ob.Name.Content);
255+
GameObjectSummary gameObjectSummary = new()
256+
{
257+
name = ob.Name.Content,
258+
spriteName = ob.Sprite?.Name.Content ?? "",
259+
parentName = ob.ParentId?.Name.Content ?? "",
260+
isVisible = ob.Visible,
261+
isPersistent = ob.Persistent,
262+
isAwake = ob.Awake,
263+
collisionShapeFlags = ob.CollisionShape.ToString(),
264+
Events = ob.Events.Enumerate().SelectMany(x => x.Item2.Select(y => (((EventType)x.Item1).ToString(), (int)y.EventSubtype))).ToList(),
265+
};
266+
216267
File.WriteAllText(Path.Join(dirAddedObject.FullName, Path.DirectorySeparatorChar.ToString(), $"{ob.Name.Content}.json"),
217-
JsonConvert.SerializeObject(
218-
new GameObjectSummary()
219-
{
220-
name = ob.Name.Content,
221-
spriteName = ob.Sprite?.Name.Content ?? "",
222-
parentName = ob.ParentId?.Name.Content ?? "",
223-
isVisible = ob.Visible,
224-
isPersistent = ob.Persistent,
225-
isAwake = ob.Awake,
226-
collisionShapeFlags = ob.CollisionShape.ToString(),
227-
}
228-
)
268+
JsonConvert.SerializeObject(gameObjectSummary)
229269
);
230270
}
231271
}
232272
File.WriteAllLines(Path.Join(outputFolder.FullName, Path.DirectorySeparatorChar.ToString(), $"removedGameObjects.txt"), removed.Select(x => x.Name.Content));
233273
}
274+
private static void ModifiedObjects(UndertaleData name, UndertaleData reference, DirectoryInfo outputFolder)
275+
{
276+
diff_match_patch dmp = new();
277+
UndertaleGameObjectComparer comparer = new();
278+
279+
DirectoryInfo dirModifiedObject = new(Path.Join(outputFolder.FullName, Path.DirectorySeparatorChar.ToString(), "ModifiedObjects"));
280+
dirModifiedObject.Create();
281+
282+
UndertaleGameObject obRef;
283+
string strName = "";
284+
string strRef = "";
285+
286+
IEnumerable<UndertaleGameObject> common = name.GameObjects.Intersect(reference.GameObjects, new UndertaleGameObjectNameComparer());
287+
288+
foreach(UndertaleGameObject ob in common)
289+
{
290+
obRef = reference.GameObjects.First(t => t.Name.Content == ob.Name.Content);
291+
if (comparer.Equals(ob, obRef)) continue;
292+
293+
strName = JsonConvert.SerializeObject(
294+
new GameObjectSummary()
295+
{
296+
name = ob.Name.Content,
297+
spriteName = ob.Sprite?.Name.Content ?? "",
298+
parentName = ob.ParentId?.Name.Content ?? "",
299+
isVisible = ob.Visible,
300+
isPersistent = ob.Persistent,
301+
isAwake = ob.Awake,
302+
collisionShapeFlags = ob.CollisionShape.ToString(),
303+
Events = ob.Events.Enumerate().SelectMany(x => x.Item2.Select(y => (((EventType)x.Item1).ToString(), (int)y.EventSubtype))).ToList(),
304+
}
305+
);
306+
strRef = JsonConvert.SerializeObject(
307+
new GameObjectSummary()
308+
{
309+
name = obRef.Name.Content,
310+
spriteName = obRef.Sprite?.Name.Content ?? "",
311+
parentName = obRef.ParentId?.Name.Content ?? "",
312+
isVisible = obRef.Visible,
313+
isPersistent = obRef.Persistent,
314+
isAwake = obRef.Awake,
315+
collisionShapeFlags = obRef.CollisionShape.ToString(),
316+
Events = ob.Events.Enumerate().SelectMany(x => x.Item2.Select(y => (((EventType)x.Item1).ToString(), (int)y.EventSubtype))).ToList(),
317+
}
318+
);
319+
320+
List<Diff> diff = dmp.diff_main(strRef, strName);
321+
if (diff.Count == 0 || (diff.Count == 1 && diff[0].operation == Operation.EQUAL)) continue;
322+
323+
string report = dmp.diff_prettyHtml(diff);
324+
File.WriteAllText(Path.Join(dirModifiedObject.FullName, Path.DirectorySeparatorChar.ToString(), $"{ob.Name.Content}.html"), report);
325+
}
326+
}
234327
public static void DiffObjects(UndertaleData name, UndertaleData reference, DirectoryInfo outputFolder)
235328
{
236329
AddedRemovedObjects(name, reference, outputFolder);
330+
ModifiedObjects(name, reference, outputFolder);
237331
}
238332
public static void DiffRooms(UndertaleData name, UndertaleData reference, DirectoryInfo outputFolder)
239333
{

0 commit comments

Comments
 (0)