Skip to content

Commit ddf2537

Browse files
committed
Work on serialization of particles and itemstacks. Fixes Provider by using COMMAND_BUILD_CONTEXT
Still a WIP. Not for production, has lots of print statements for further debugging
1 parent 5f2794f commit ddf2537

File tree

1 file changed

+54
-67
lines changed
  • commandapi-platforms/commandapi-bukkit/commandapi-bukkit-nms/commandapi-bukkit-1.20.5/src/main/java/dev/jorel/commandapi/nms

1 file changed

+54
-67
lines changed

commandapi-platforms/commandapi-bukkit/commandapi-bukkit-nms/commandapi-bukkit-1.20.5/src/main/java/dev/jorel/commandapi/nms/NMS_1_20_R4.java

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@
3131
import java.util.HashSet;
3232
import java.util.Iterator;
3333
import java.util.List;
34+
import java.util.Locale;
3435
import java.util.Map;
3536
import java.util.Optional;
3637
import java.util.Set;
3738
import java.util.concurrent.CompletableFuture;
3839
import java.util.concurrent.atomic.AtomicInteger;
3940
import java.util.function.Predicate;
4041
import java.util.function.ToIntFunction;
41-
import java.util.stream.Stream;
4242

4343
import org.bukkit.Bukkit;
4444
import org.bukkit.Color;
@@ -89,6 +89,9 @@
8989
import com.mojang.brigadier.suggestion.Suggestions;
9090
import com.mojang.brigadier.tree.CommandNode;
9191
import com.mojang.logging.LogUtils;
92+
import com.mojang.serialization.Codec;
93+
import com.mojang.serialization.DataResult;
94+
import com.mojang.serialization.DynamicOps;
9295

9396
import dev.jorel.commandapi.CommandAPI;
9497
import dev.jorel.commandapi.CommandAPIHandler;
@@ -135,6 +138,7 @@
135138
import net.minecraft.commands.arguments.ScoreboardSlotArgument;
136139
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
137140
import net.minecraft.commands.arguments.blocks.BlockStateArgument;
141+
import net.minecraft.commands.arguments.blocks.BlockStateParser;
138142
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
139143
import net.minecraft.commands.arguments.coordinates.ColumnPosArgument;
140144
import net.minecraft.commands.arguments.coordinates.Vec2Argument;
@@ -149,9 +153,6 @@
149153
import net.minecraft.commands.functions.InstantiatedFunction;
150154
import net.minecraft.commands.synchronization.ArgumentUtils;
151155
import net.minecraft.core.BlockPos;
152-
import net.minecraft.core.HolderLookup.Provider;
153-
import net.minecraft.core.component.DataComponentMap;
154-
import net.minecraft.core.component.TypedDataComponent;
155156
import net.minecraft.core.particles.BlockParticleOption;
156157
import net.minecraft.core.particles.DustColorTransitionOptions;
157158
import net.minecraft.core.particles.DustParticleOptions;
@@ -164,6 +165,8 @@
164165
import net.minecraft.core.registries.BuiltInRegistries;
165166
import net.minecraft.core.registries.Registries;
166167
import net.minecraft.nbt.CompoundTag;
168+
import net.minecraft.nbt.NbtOps;
169+
import net.minecraft.nbt.Tag;
167170
import net.minecraft.network.chat.Component.Serializer;
168171
import net.minecraft.resources.ResourceLocation;
169172
import net.minecraft.server.MinecraftServer;
@@ -295,78 +298,62 @@ public final Map<String, HelpTopic> getHelpMap() {
295298
public String[] compatibleVersions() {
296299
return new String[] { "1.20.5" };
297300
};
301+
302+
private static String serializeNMSItemStack(ItemStack is) {
303+
String result = new ItemInput(is.getItemHolder(), is.getComponents()).serialize(COMMAND_BUILD_CONTEXT);
304+
System.out.println("Converted is: " + result);
305+
return result;
306+
}
298307

299308
@Differs(from = "1.20.4", by = "Everything")
300309
@Override
301310
public final String convert(org.bukkit.inventory.ItemStack is) {
302-
// Let's assume that this functionality has never been implemented thus far...
303-
final String itemStackKey = is.getType().getKey().toString();
304-
DataComponentMap components = CraftItemStack.asNMSCopy(is).getComponents();
311+
ItemStack itemStack = CraftItemStack.asNMSCopy(is);
305312

306-
// If we have components, add them to the end of the item stack string, such as
307-
// netherite_hoe[damage=5,repair_cost=2]
308-
final StringBuilder itemStackComponentsBuilder = new StringBuilder();
309-
if (!components.isEmpty()) {
310-
itemStackComponentsBuilder.append('[');
311-
312-
for (Iterator<TypedDataComponent<?>> iterator = components.iterator(); iterator.hasNext();) {
313-
final TypedDataComponent<?> component = iterator.next();
314-
itemStackComponentsBuilder.append(component.type());
315-
itemStackComponentsBuilder.append('=');
316-
317-
// TODO: We may have to format this object better (e.g. add quotes around strings)
318-
// but we'll find that in testing (hopefully?)
319-
itemStackComponentsBuilder.append(component.value());
320-
321-
if (iterator.hasNext()) {
322-
itemStackComponentsBuilder.append(',');
323-
}
324-
}
325-
326-
itemStackComponentsBuilder.append(']');
327-
}
313+
System.out.println(is.getType() + "Patch:");
314+
System.out.println(itemStack.getComponentsPatch());
315+
316+
// TODO: We need to figure out how to get this component patch
317+
// which contains the "minimal set of components" into a form
318+
// of standard components, which is then serializable.
328319

329-
return itemStackKey + itemStackComponentsBuilder.toString();
320+
System.out.println("Serialized:");
321+
System.out.println(serializeNMSItemStack(CraftItemStack.asNMSCopy(is)));
322+
return serializeNMSItemStack(CraftItemStack.asNMSCopy(is));
330323
}
331324

332325
@Differs(from = "1.20.4", by = "Everything")
333326
@Override
334327
public final String convert(ParticleData<?> particle) {
335-
final ParticleOptions options = CraftParticle.createParticleParam(particle.particle(), particle.data());
336-
final ResourceLocation particleKey = BuiltInRegistries.PARTICLE_TYPE.getKey(options.getType());
328+
System.out.println("Unpacking " + particle.particle().getKey());
329+
final ParticleOptions particleOptions = CraftParticle.createParticleParam(particle.particle(), particle.data());
330+
final ResourceLocation particleKey = BuiltInRegistries.PARTICLE_TYPE.getKey(particleOptions.getType());
331+
// /particle dust{scale:2,color:[1,2,2]}
332+
Codec codec = particleOptions.getType().codec().codec();
333+
DataResult result = codec.encodeStart(NbtOps.INSTANCE, particleOptions);
334+
Object o = result.result().get();
335+
System.out.println("UNPACKED to " + o);
336+
System.out.println(o.getClass().getName());
337337

338-
// The minimal "viable" solution...
339-
return particleKey.toString();
340-
//
341-
//
342-
//
338+
// .encodeStart(NbtOps.INSTANCE, particleOptions);
343339
//
344-
//
345-
// // Do I literally have to implement this for each particle type???
346-
// final Object particleData = particle.data();
347-
// String particleDataString = "";
348-
// if (particleData instanceof BlockParticleOption blockParticle) {
349-
// particleDataString = " " + BlockStateParser.serialize(blockParticle.getState());
350-
// } else if (particleData instanceof DustColorTransitionOptions a) {
351-
// RecordCodecBuilder.
352-
// }
353-
//
354-
// BlockParticleOption.class
355-
// DustColorTransitionOptions.class
356-
// DustParticleOptions.class
357-
// DustParticleOptionsBase.class
358-
// ItemParticleOption.class
359-
// ParticleOptions.class
360-
// ParticleType.class
361-
// ParticleTypes.class
362-
// SculkChargeParticleOptions.class
363-
// ShriekParticleOption.class
364-
// SimpleParticleType.class
365-
// VibrationParticleOption.class
366-
//
367-
// // TODO: Figure out what we're doing about this
368-
// BuiltInRegistries.PARTICLE_TYPE.getKey(particle.particle().getKey()).toString()
369-
// return CraftParticle.createParticleParam(particle.particle(), particle.data()).writeToString();
340+
//
341+
// // From RecipeManager#fromJson which isn't accessible
342+
// final Recipe recipe = Recipe.CODEC.parse(JsonOps.INSTANCE, p.second()).getOrThrow(JsonParseException::new);
343+
// return new RecipeHolder(new ResourceLocation(p.first()), recipe);
344+
345+
// particleOptions.getType().codec().decoder().;
346+
347+
348+
final String dataString;
349+
350+
if (o.toString().equals("{}")) {
351+
dataString = "";
352+
} else {
353+
dataString = o.toString();
354+
}
355+
356+
return particleKey.toString() + dataString;
370357
}
371358

372359
/**
@@ -445,7 +432,7 @@ public Advancement getAdvancement(CommandContext<CommandSourceStack> cmdCtx, Str
445432
@Differs(from = "1.20.4", by = "Serializer.toJson now needs a Provider")
446433
@Override
447434
public Component getAdventureChat(CommandContext<CommandSourceStack> cmdCtx, String key) throws CommandSyntaxException {
448-
return GsonComponentSerializer.gson().deserialize(Serializer.toJson(MessageArgument.getMessage(cmdCtx, key), Provider.create(Stream.of())));
435+
return GsonComponentSerializer.gson().deserialize(Serializer.toJson(MessageArgument.getMessage(cmdCtx, key), COMMAND_BUILD_CONTEXT));
449436
}
450437

451438
@Override
@@ -458,7 +445,7 @@ public NamedTextColor getAdventureChatColor(CommandContext<CommandSourceStack> c
458445
public final Component getAdventureChatComponent(CommandContext<CommandSourceStack> cmdCtx, String key) {
459446
// TODO: Figure out if an empty provider is suitable for this context
460447
return GsonComponentSerializer.gson()
461-
.deserialize(Serializer.toJson(ComponentArgument.getComponent(cmdCtx, key), Provider.create(Stream.of())));
448+
.deserialize(Serializer.toJson(ComponentArgument.getComponent(cmdCtx, key), COMMAND_BUILD_CONTEXT));
462449
}
463450

464451
@Override
@@ -508,7 +495,7 @@ public CommandSourceStack getBrigadierSourceFromCommandSender(
508495
@Differs(from = "1.20.4", by = "Serializer.toJson now needs a Provider")
509496
@Override
510497
public final BaseComponent[] getChat(CommandContext<CommandSourceStack> cmdCtx, String key) throws CommandSyntaxException {
511-
return ComponentSerializer.parse(Serializer.toJson(MessageArgument.getMessage(cmdCtx, key), Provider.create(Stream.of())));
498+
return ComponentSerializer.parse(Serializer.toJson(MessageArgument.getMessage(cmdCtx, key), COMMAND_BUILD_CONTEXT));
512499
}
513500

514501
@Override
@@ -1057,7 +1044,7 @@ public final void reloadDataPacks() {
10571044
@Override
10581045
public Message generateMessageFromJson(String json) {
10591046
// TODO: Same as #getAdventureChatComponent, figure out if an empty provider is suitable here
1060-
return Serializer.fromJson(json, Provider.create(Stream.of()));
1047+
return Serializer.fromJson(json, COMMAND_BUILD_CONTEXT);
10611048
}
10621049

10631050
@SuppressWarnings("unchecked")

0 commit comments

Comments
 (0)