@@ -197,6 +197,98 @@ public bool Contains([NotNull] string tagName) {
197197 return tags . ContainsKey ( tagName ) ;
198198 }
199199
200+ public void Sort ( IComparer < NbtTag > sorter , bool recursive )
201+ {
202+ if ( recursive )
203+ {
204+ var restore_sort = ( NbtCompound ) this . Clone ( ) ;
205+ PerformAction ( new DescriptionHolder ( "Sort {0}" , this ) ,
206+ ( ) => { DoSort ( sorter , true ) ; } ,
207+ ( ) => { DoUnsortRecursive ( restore_sort ) ; }
208+ ) ;
209+ }
210+ else
211+ {
212+ var restore_sort = this . Tags . ToList ( ) ;
213+ PerformAction ( new DescriptionHolder ( "Sort {0}" , this ) ,
214+ ( ) => { DoSort ( sorter , false ) ; } ,
215+ ( ) => { DoUnsortRoot ( restore_sort ) ; }
216+ ) ;
217+ }
218+ }
219+
220+ private void DoUnsortRecursive ( NbtCompound reference )
221+ {
222+ var order = Tags . OrderBy ( x => reference . IndexOf ( x . Name ) ) . ToList ( ) ;
223+ foreach ( var tag in order )
224+ {
225+ if ( tag is NbtCompound sub )
226+ sub . DoUnsortRecursive ( ( NbtCompound ) reference [ tag . Name ] ) ;
227+ else if ( tag is NbtList list )
228+ UnsortListChildren ( list , ( NbtList ) reference [ tag . Name ] ) ;
229+ }
230+ DoUnsortRoot ( order ) ;
231+ }
232+
233+ private static void UnsortListChildren ( NbtList list , NbtList reference )
234+ {
235+ if ( list . ListType == NbtTagType . Compound )
236+ {
237+ for ( int i = 0 ; i < list . Count ; i ++ )
238+ {
239+ ( ( NbtCompound ) list [ i ] ) . DoUnsortRecursive ( ( NbtCompound ) reference [ i ] ) ;
240+ }
241+ }
242+ else if ( list . ListType == NbtTagType . List )
243+ {
244+ for ( int i = 0 ; i < list . Count ; i ++ )
245+ {
246+ UnsortListChildren ( ( NbtList ) list [ i ] , ( NbtList ) reference [ i ] ) ;
247+ }
248+ }
249+ }
250+
251+ private void DoUnsortRoot ( List < NbtTag > order )
252+ {
253+ DoClear ( ) ;
254+ DoAddRange ( order ) ;
255+ }
256+
257+ private void DoSort ( IComparer < NbtTag > sorter , bool recursive )
258+ {
259+ var tags = Tags . OrderBy ( x => x , sorter ) . ToList ( ) ;
260+ foreach ( var tag in tags )
261+ {
262+ if ( recursive )
263+ {
264+ if ( tag is NbtCompound sub )
265+ sub . DoSort ( sorter , true ) ;
266+ else if ( tag is NbtList list )
267+ SortListChildren ( list , sorter ) ;
268+ }
269+ }
270+ DoClear ( ) ;
271+ DoAddRange ( tags ) ;
272+ }
273+
274+ private static void SortListChildren ( NbtList list , IComparer < NbtTag > sorter )
275+ {
276+ if ( list . ListType == NbtTagType . Compound )
277+ {
278+ foreach ( NbtCompound item in list )
279+ {
280+ item . DoSort ( sorter , true ) ;
281+ }
282+ }
283+ else if ( list . ListType == NbtTagType . List )
284+ {
285+ foreach ( NbtList item in list )
286+ {
287+ SortListChildren ( item , sorter ) ;
288+ }
289+ }
290+ }
291+
200292
201293 /// <summary> Removes the tag with the specified name from this NbtCompound. </summary>
202294 /// <param name="tagName"> The name of the tag to remove. </param>
0 commit comments