Skip to content

Commit

Permalink
Store data components in bytebuf form for mcpl
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexProgrammerDE committed Nov 5, 2024
1 parent 7eae4e6 commit 371787a
Show file tree
Hide file tree
Showing 8 changed files with 11,659 additions and 19,577 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.mojang.serialization.JsonOps;
import com.google.gson.JsonPrimitive;
import com.soulfiremc.generator.util.MCHelper;
import net.minecraft.core.component.DataComponentMap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.core.component.TypedDataComponent;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.world.item.Item;

import java.util.Base64;
import java.util.Map;
import java.util.Objects;

public class ItemsDataGenerator implements IDataGenerator {
public static JsonObject generateItem(Item item) {
Expand All @@ -35,11 +40,22 @@ public static JsonObject generateItem(Item item) {
itemDesc.addProperty("key", BuiltInRegistries.ITEM.getKey(item).toString());

var sortedComponentObj = new JsonObject();
DataComponentMap.CODEC.encodeStart(
MCHelper.getLevel().registryAccess().createSerializationContext(JsonOps.INSTANCE),
item.components()).result().orElseThrow().getAsJsonObject()
.entrySet().stream().sorted(Map.Entry.comparingByKey())
.forEach(e -> sortedComponentObj.add(e.getKey(), e.getValue()));
item.components().stream().map(typed -> {
ByteBuf buf = Unpooled.buffer();
RegistryFriendlyByteBuf registryBuf = new RegistryFriendlyByteBuf(buf, MCHelper.getLevel().registryAccess());
registryBuf.writeVarInt(BuiltInRegistries.DATA_COMPONENT_TYPE.getId(typed.type()));
writeComponent(registryBuf, typed);
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
buf.release();
String data = Base64.getEncoder().encodeToString(bytes);

return Map.entry(
Objects.requireNonNull(BuiltInRegistries.DATA_COMPONENT_TYPE.getKey(typed.type())).toString(),
data);
})
.sorted(Map.Entry.comparingByKey())
.forEach(e -> sortedComponentObj.add(e.getKey(), new JsonPrimitive(e.getValue())));
itemDesc.add("components", sortedComponentObj);

return itemDesc;
Expand All @@ -56,4 +72,8 @@ public JsonArray generateDataJson() {
BuiltInRegistries.ITEM.forEach(item -> resultArray.add(generateItem(item)));
return resultArray;
}

private static <T> void writeComponent(RegistryFriendlyByteBuf buf, TypedDataComponent<T> typed) {
typed.type().streamCodec().encode(buf, typed.value());
}
}
2 changes: 1 addition & 1 deletion data-generator/src/main/resources/templates/ItemType.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
public record ItemType(
int id,
Key key,
JsonDataComponents components) implements RegistryValue<ItemType> {
ByteDataComponents components) implements RegistryValue<ItemType> {
public static final Registry<ItemType> REGISTRY = new Registry<>(RegistryKeys.ITEM);

//@formatter:off
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* SoulFire
* Copyright (C) 2024 AlexProgrammerDE
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.soulfiremc.server.data;

import com.google.gson.JsonObject;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.soulfiremc.server.util.structs.GsonInstance;
import io.netty.buffer.Unpooled;
import lombok.extern.slf4j.Slf4j;
import org.geysermc.mcprotocollib.protocol.codec.MinecraftCodecHelper;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponent;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
import org.geysermc.mcprotocollib.protocol.data.game.item.component.ItemCodecHelper;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public record ByteDataComponents(Map<DataComponentType<?>, DataComponent<?, ?>> components) {
public static final TypeAdapter<ByteDataComponents> SERIALIZER = new TypeAdapter<>() {
@Override
public void write(JsonWriter out, ByteDataComponents value) {
throw new UnsupportedOperationException("ByteDataComponents serialization is not supported");
}

@Override
public ByteDataComponents read(JsonReader in) {
var parsedJson = GsonInstance.GSON.<JsonObject>fromJson(in, JsonObject.class);
var map = new HashMap<DataComponentType<?>, DataComponent<?, ?>>();
for (var entry : parsedJson.entrySet()) {
var value = entry.getValue().getAsString();
var bytes = Base64.getDecoder().decode(value);
var buf = Unpooled.wrappedBuffer(bytes);
var helper = new MinecraftCodecHelper();
var dataComponentType = DataComponentType.from(helper.readVarInt(buf));
var dataComponent = dataComponentType.readDataComponent(ItemCodecHelper.INSTANCE, buf);
map.put(dataComponentType, dataComponent);
}

return new ByteDataComponents(map);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public Key read(JsonReader in) throws IOException {
private static final Function<Map<Class<?>, TypeAdapter<?>>, Gson> GSON_FACTORY = (typeAdapters) -> {
var builder = new GsonBuilder()
.registerTypeAdapter(Key.class, RESOURCE_KEY_ADAPTER)
.registerTypeAdapter(JsonDataComponents.class, JsonDataComponents.SERIALIZER);
.registerTypeAdapter(ByteDataComponents.class, ByteDataComponents.SERIALIZER);

for (var entry : typeAdapters.entrySet()) {
builder.registerTypeAdapter(entry.getKey(), entry.getValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
public record ItemType(
int id,
Key key,
JsonDataComponents components) implements RegistryValue<ItemType> {
ByteDataComponents components) implements RegistryValue<ItemType> {
public static final Registry<ItemType> REGISTRY = new Registry<>(RegistryKeys.ITEM);

//@formatter:off
Expand Down

This file was deleted.

127 changes: 0 additions & 127 deletions server/src/main/java/com/soulfiremc/server/data/JsonToMCPLCodecs.java

This file was deleted.

Loading

0 comments on commit 371787a

Please sign in to comment.