Skip to content

Commit

Permalink
Rewrite entity extractor
Browse files Browse the repository at this point in the history
Fixed some bugs and added proper default values for fields. Partially
adapted from #571.

Co-authored-by: SelfMadeSystem <sms@shoghisimon.cc>
  • Loading branch information
rj00a and SelfMadeSystem committed Feb 16, 2024
1 parent 1791a7d commit ad3186b
Show file tree
Hide file tree
Showing 5 changed files with 393 additions and 267 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,33 @@
import net.minecraft.network.encryption.PlayerPublicKey;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;

import java.util.UUID;

import org.jetbrains.annotations.Nullable;

public class DummyPlayerEntity extends PlayerEntity {
public static final DummyPlayerEntity INSTANCE;

static {
INSTANCE = Main.magicallyInstantiate(DummyPlayerEntity.class);
INSTANCE = new DummyPlayerEntity(DummyWorld.INSTANCE, new BlockPos(0, 0, 0), 0,
new GameProfile(new UUID(0xDEADBEEF, 0xDEADBEEF), "dummy"),
null);

try {
var dataTrackerField = Entity.class.getDeclaredField("dataTracker");
dataTrackerField.setAccessible(true);
dataTrackerField.set(INSTANCE, new DataTracker(INSTANCE));

INSTANCE.initDataTracker();
INSTANCE.setHealth(20); // idk why player health is set to 1 by default
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}

private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile, @Nullable PlayerPublicKey publicKey) {
private DummyPlayerEntity(World world, BlockPos pos, float yaw, GameProfile gameProfile,
@Nullable PlayerPublicKey publicKey) {
super(world, pos, yaw, gameProfile);
}

Expand Down
67 changes: 52 additions & 15 deletions extractor/src/main/java/rs/valence/extractor/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;

import net.fabricmc.api.ModInitializer;
Expand All @@ -20,26 +21,13 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.TreeMap;
import java.nio.charset.StandardCharsets;

public class Main implements ModInitializer {
public static final String MOD_ID = "valence_extractor";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);

/**
* Magically creates an instance of a <i>concrete</i> class without calling its constructor.
*/
public static <T> T magicallyInstantiate(Class<T> clazz) {
var rf = ReflectionFactory.getReflectionFactory();
try {
var objCon = Object.class.getDeclaredConstructor();
var con = rf.newConstructorForSerialization(clazz, objCon);
return clazz.cast(con.newInstance());
} catch (Throwable e) {
throw new IllegalArgumentException("Failed to magically instantiate " + clazz.getName(), e);
}
}

@Override
public void onInitialize() {
ServerLifecycleEvents.SERVER_STARTING.register(server -> {
Expand Down Expand Up @@ -85,7 +73,7 @@ public void onInitialize() {
}
}

LOGGER.info("Done!");
LOGGER.info("Done! Errors below this line can be ignored.");

server.shutdown();
});
Expand All @@ -101,7 +89,56 @@ public interface Extractor {
public record Pair<T, U>(T left, U right) {
}

/**
* Magically creates an instance of a <i>concrete</i> class without calling its constructor.
*/
public static <T> T magicallyInstantiate(Class<T> clazz) {
var rf = ReflectionFactory.getReflectionFactory();
try {
var objCon = Object.class.getDeclaredConstructor();
var con = rf.newConstructorForSerialization(clazz, objCon);
return clazz.cast(con.newInstance());
} catch (Throwable e) {
throw new IllegalArgumentException("Failed to magically instantiate " + clazz.getName(), e);
}
}

public static void writeJson(DataOutput output, Gson gson, JsonElement element) throws IOException {
output.write(gson.toJson(element).getBytes(StandardCharsets.UTF_8));
}

/**
* Converts a string to PascalCase.
*
* @param str The string to convert.
* @return The converted string.
*/
public static String toPascalCase(String str) {
StringBuilder result = new StringBuilder();
boolean capitalizeNext = true;

for (char c : str.toCharArray()) {
if (Character.isWhitespace(c) || c == '_') {
capitalizeNext = true;
} else if (capitalizeNext) {
result.append(Character.toUpperCase(c));
capitalizeNext = false;
} else {
result.append(Character.toLowerCase(c));
}
}

return result.toString();
}

/**
* Converts a TreeMap to a JsonArray, ignoring the keys.
*/
public static <A, B extends JsonElement> JsonArray treeMapToJsonArray(TreeMap<A, B> map) {
var array = new JsonArray();
for (var value : map.values()) {
array.add(value);
}
return array;
}
}
34 changes: 0 additions & 34 deletions extractor/src/main/java/rs/valence/extractor/ValenceUtils.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import net.minecraft.registry.Registries;
import net.minecraft.server.MinecraftServer;
import rs.valence.extractor.Main;
import rs.valence.extractor.ValenceUtils;

public class Effects implements Main.Extractor {
public Effects() {
Expand All @@ -34,7 +33,7 @@ public void extract(MinecraftServer server, DataOutput output, Gson gson) throws
effectJson.addProperty("translation_key", effect.getTranslationKey());
effectJson.addProperty("color", effect.getColor());
effectJson.addProperty("instant", effect.isInstant());
effectJson.addProperty("category", ValenceUtils.toPascalCase(effect.getCategory().name()));
effectJson.addProperty("category", Main.toPascalCase(effect.getCategory().name()));

var attributeModifiersJson = new JsonArray();

Expand Down
Loading

0 comments on commit ad3186b

Please sign in to comment.