@@ -45,6 +45,38 @@ public int GetHashCode(UndertaleSprite x)
45
45
}
46
46
}
47
47
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 >
48
80
{
49
81
public bool Equals ( UndertaleGameObject ? x , UndertaleGameObject ? y )
50
82
{
@@ -64,17 +96,25 @@ public int GetHashCode(UndertaleGameObject x)
64
96
}
65
97
public class GameObjectSummary
66
98
{
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 ) > ( ) ;
74
107
}
75
108
76
109
static public class DiffUtils
77
110
{
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
+ }
78
118
// thanks to Pong to acknowledge me that possibility
79
119
private static unsafe bool UnsafeCompare ( byte [ ] a1 , byte [ ] a2 )
80
120
{
@@ -150,8 +190,7 @@ private static void AddedRemovedCodes(UndertaleData name, UndertaleData referenc
150
190
private static void ModifiedCodes( UndertaleData name, UndertaleData reference , DirectoryInfo outputFolder )
151
191
{
152
192
using MemoryStream ms = new ( ) ;
153
- SharpSerializerBinarySettings settings = new ( BinarySerializationMode . Burst ) ;
154
- SharpSerializer burstSerializer = new ( settings) ;
193
+ SharpSerializer burstSerializer = new ( new SharpSerializerBinarySettings ( BinarySerializationMode . Burst ) ) ;
155
194
156
195
GlobalDecompileContext contextName = new ( name , false ) ;
157
196
GlobalDecompileContext contextRef = new ( reference , false ) ;
@@ -206,34 +245,89 @@ private static void AddedRemovedObjects(UndertaleData name, UndertaleData refere
206
245
DirectoryInfo dirAddedObject = new ( Path . Join ( outputFolder . FullName , Path . DirectorySeparatorChar . ToString ( ) , "AddedGameObjects" ) ) ;
207
246
dirAddedObject. Create ( ) ;
208
247
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 ( ) ) ;
211
250
using ( StreamWriter sw = new ( Path . Join ( outputFolder . FullName , Path . DirectorySeparatorChar . ToString ( ) , $ "addedGameObjects.txt") ) )
212
251
{
213
252
foreach ( UndertaleGameObject ob in added)
214
253
{
215
254
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
+
216
267
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 )
229
269
) ;
230
270
}
231
271
}
232
272
File. WriteAllLines ( Path . Join ( outputFolder . FullName , Path . DirectorySeparatorChar . ToString ( ) , $ "removedGameObjects.txt") , removed . Select ( x => x . Name . Content ) ) ;
233
273
}
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
+ }
234
327
public static void DiffObjects( UndertaleData name , UndertaleData reference , DirectoryInfo outputFolder )
235
328
{
236
329
AddedRemovedObjects( name , reference , outputFolder ) ;
330
+ ModifiedObjects( name , reference , outputFolder ) ;
237
331
}
238
332
public static void DiffRooms( UndertaleData name , UndertaleData reference , DirectoryInfo outputFolder )
239
333
{
0 commit comments