22
33import ca .spottedleaf .moonrise .common .PlatformHooks ;
44import com .google .common .base .Preconditions ;
5+ import com .google .common .collect .ImmutableMap ;
56import com .google .common .collect .Multimap ;
67import com .google .common .io .Files ;
78import com .google .gson .JsonElement ;
1213import com .mojang .logging .LogUtils ;
1314import com .mojang .serialization .Dynamic ;
1415import com .mojang .serialization .JsonOps ;
16+ import io .papermc .paper .adventure .PaperAdventure ;
17+ import io .papermc .paper .entity .EntitySerializationFlag ;
1518import io .papermc .paper .registry .RegistryKey ;
1619import java .io .File ;
1720import java .io .IOException ;
2528import java .util .Set ;
2629import java .util .logging .Level ;
2730import java .util .stream .Stream ;
28- import io . papermc . paper . entity . EntitySerializationFlag ;
31+ import net . kyori . adventure . key . Key ;
2932import net .minecraft .SharedConstants ;
3033import net .minecraft .advancements .AdvancementHolder ;
34+ import net .minecraft .advancements .AdvancementNode ;
35+ import net .minecraft .advancements .AdvancementTree ;
36+ import net .minecraft .advancements .TreeNodePosition ;
3137import net .minecraft .commands .Commands ;
3238import net .minecraft .commands .arguments .item .ItemParser ;
3339import net .minecraft .core .registries .BuiltInRegistries ;
3844import net .minecraft .nbt .StringTag ;
3945import net .minecraft .nbt .Tag ;
4046import net .minecraft .nbt .TagParser ;
47+ import net .minecraft .resources .RegistryOps ;
4148import net .minecraft .resources .ResourceLocation ;
4249import net .minecraft .server .MinecraftServer ;
4350import net .minecraft .server .level .ServerLevel ;
@@ -299,9 +306,9 @@ private static File getBukkitDataPackFolder() {
299306 }
300307
301308 @ Override
302- public Advancement loadAdvancement (NamespacedKey key , String advancement ) {
303- Preconditions . checkArgument ( Bukkit . getAdvancement ( key ) == null , "Advancement %s already exists" , key );
304- ResourceLocation resourceKey = CraftNamespacedKey . toMinecraft ( key );
309+ public Advancement loadAdvancement (Key key , String advancement , boolean persist ) {
310+ ResourceLocation resourceKey = PaperAdventure . asVanilla ( key );
311+ Preconditions . checkArgument ( MinecraftServer . getServer (). getAdvancements (). get ( resourceKey ) == null , "Advancement %s already exists" , key );
305312
306313 JsonElement jsonelement = JsonParser .parseString (advancement );
307314 final net .minecraft .resources .RegistryOps <JsonElement > ops = CraftRegistry .getMinecraftRegistry ().createSerializationContext (JsonOps .INSTANCE ); // Paper - use RegistryOps
@@ -326,30 +333,101 @@ public Advancement loadAdvancement(NamespacedKey key, String advancement) {
326333 }
327334 }
328335
329- Advancement bukkit = Bukkit . getAdvancement ( key );
330-
331- if ( bukkit != null ) {
332- File file = new File (CraftMagicNumbers .getBukkitDataPackFolder (), "data" + File .separator + key .getNamespace () + File .separator + "advancements" + File .separator + key .getKey () + ".json" );
333- file .getParentFile ().mkdirs ();
336+ AdvancementHolder nmsAdvancement = MinecraftServer . getServer (). getAdvancements (). get ( resourceKey );
337+ if ( nmsAdvancement != null ) {
338+ if ( persist ) {
339+ File file = new File (CraftMagicNumbers .getBukkitDataPackFolder (), "data" + File .separator + key .namespace () + File .separator + "advancements" + File .separator + key .value () + ".json" );
340+ file .getParentFile ().mkdirs ();
334341
335- try {
336- Files .write (advancement , file , StandardCharsets .UTF_8 );
337- } catch (IOException ex ) {
338- Bukkit .getLogger ().log (Level .SEVERE , "Error saving advancement " + key , ex );
342+ try {
343+ Files .write (advancement , file , StandardCharsets .UTF_8 );
344+ } catch (IOException ex ) {
345+ Bukkit .getLogger ().log (Level .SEVERE , "Error saving advancement " + key , ex );
346+ }
339347 }
340348
341349 MinecraftServer .getServer ().getPlayerList ().getPlayers ().forEach (player -> {
342350 player .getAdvancements ().reload (MinecraftServer .getServer ().getAdvancements ());
343351 player .getAdvancements ().flushDirty (player , false );
344352 });
345353
346- return bukkit ;
354+ return nmsAdvancement . toBukkit () ;
347355 }
348356 }
349357
350358 return null ;
351359 }
352360
361+ @ Override
362+ public List <Advancement > loadAdvancements (final Map <Key , String > advancements , final boolean persist ) {
363+ for (Map .Entry <Key , String > entry : advancements .entrySet ()) {
364+ Preconditions .checkArgument (MinecraftServer .getServer ().getAdvancements ().get (PaperAdventure .asVanilla (entry .getKey ())) == null , "Advancement %s already exists" , entry .getKey ());
365+ }
366+
367+ final List <LoadAdvancementEntry > mappedAdvancements = new ArrayList <>(advancements .size ());
368+ for (final Map .Entry <Key , String > entry : advancements .entrySet ()) {
369+ mappedAdvancements .add (new LoadAdvancementEntry (entry .getKey (), entry .getValue (), PaperAdventure .asVanilla (entry .getKey ()), JsonParser .parseString (entry .getValue ())));
370+ }
371+
372+ final List <Advancement > outAdvancements = new ArrayList <>(mappedAdvancements .size ());
373+ final ImmutableMap .Builder <ResourceLocation , AdvancementHolder > mapBuilder = ImmutableMap .builder ();
374+ mapBuilder .putAll (MinecraftServer .getServer ().getAdvancements ().advancements );
375+
376+ final RegistryOps <JsonElement > ops = CraftRegistry .getMinecraftRegistry ().createSerializationContext (JsonOps .INSTANCE );
377+ final List <AdvancementHolder > advancementHolders = new ArrayList <>(mappedAdvancements .size ());
378+ for (final LoadAdvancementEntry entry : mappedAdvancements ) {
379+ final net .minecraft .advancements .Advancement advancement = net .minecraft .advancements .Advancement .CODEC .parse (ops , entry .nmsAdvancement ()).getOrThrow (JsonParseException ::new );
380+ if (advancement == null ) {
381+ continue ;
382+ }
383+
384+ final AdvancementHolder holder = new AdvancementHolder (entry .nmsResourceLocation (), advancement );
385+ mapBuilder .put (entry .nmsResourceLocation (), holder );
386+ advancementHolders .add (holder );
387+ }
388+
389+ MinecraftServer .getServer ().getAdvancements ().advancements = mapBuilder .build ();
390+
391+ final AdvancementTree tree = MinecraftServer .getServer ().getAdvancements ().tree ();
392+ tree .addAll (advancementHolders );
393+
394+ for (LoadAdvancementEntry entry : mappedAdvancements ) {
395+ // recalculate advancement position
396+ final AdvancementNode node = tree .get (entry .nmsResourceLocation ());
397+ if (node != null ) {
398+ final AdvancementNode root = node .root ();
399+ if (root .holder ().value ().display ().isPresent ()) {
400+ TreeNodePosition .run (root );
401+ }
402+ }
403+
404+ AdvancementHolder nmsAdvancement = MinecraftServer .getServer ().getAdvancements ().get (entry .nmsResourceLocation );
405+ if (nmsAdvancement != null ) {
406+ if (persist ) {
407+ File file = new File (CraftMagicNumbers .getBukkitDataPackFolder (), "data" + File .separator + entry .key ().namespace () + File .separator + "advancements" + File .separator + entry .key ().value () + ".json" );
408+ file .getParentFile ().mkdirs ();
409+
410+ try {
411+ Files .write (entry .rawAdvancement (), file , StandardCharsets .UTF_8 );
412+ } catch (IOException ex ) {
413+ Bukkit .getLogger ().log (Level .SEVERE , "Error saving advancement " + entry .key (), ex );
414+ }
415+ }
416+
417+ outAdvancements .add (nmsAdvancement .toBukkit ());
418+ }
419+ }
420+
421+ if (!outAdvancements .isEmpty ()) {
422+ MinecraftServer .getServer ().getPlayerList ().getPlayers ().forEach (player -> {
423+ player .getAdvancements ().reload (MinecraftServer .getServer ().getAdvancements ());
424+ player .getAdvancements ().flushDirty (player , false );
425+ });
426+ }
427+
428+ return outAdvancements ;
429+ }
430+
353431 @ Override
354432 public boolean removeAdvancement (NamespacedKey key ) {
355433 File file = new File (CraftMagicNumbers .getBukkitDataPackFolder (), "data" + File .separator + key .getNamespace () + File .separator + "advancements" + File .separator + key .getKey () + ".json" );
@@ -860,4 +938,6 @@ public io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager<org.bukkit.
860938 public org .bukkit .inventory .ItemStack createEmptyStack () {
861939 return CraftItemStack .asCraftMirror (null );
862940 }
941+
942+ private record LoadAdvancementEntry (Key key , String rawAdvancement , ResourceLocation nmsResourceLocation , JsonElement nmsAdvancement ) {}
863943}
0 commit comments