Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ dependencies {
// tasmod dependencies
embed "com.dselent:bigarraylist:1.6"
embed "com.github.KaptainWutax:SeedUtils:b6a383113c"

implementation "com.google.code.gson:gson:2.14.0"

// loom dependencies
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings ploceus.mcpMappings(project.mcp_channel, project.mcp_mcversion, project.mcp_build)
Expand Down
58 changes: 58 additions & 0 deletions src/main/java/com/minecrafttas/mctcommon/json/FineField.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.minecrafttas.mctcommon.json;

import com.google.gson.JsonElement;

public class FineField {

private final String name;
private final FineMode mode;
private final FineSerializer serializer;
private final FineDeserializer deserializer;

public FineField(String name, FineMode mode) {
this.name = name;
this.mode = mode;
this.serializer = null;
this.deserializer = null;
}

public FineField(String name, FineSerializer serializer, FineDeserializer deserializer) {
this.name = name;
this.mode = FineMode.CUSTOM;
this.serializer = serializer;
this.deserializer = deserializer;
}

public static enum FineMode {
FINE,
EXCLUDED,
GSON,
CUSTOM;
}

public String getName() {
return name;
}

public FineMode getMode() {
return mode;
}

public JsonElement serialize(Object obj) {
return serializer.serialize(obj);
}

public Object deserialize(JsonElement element) {
return deserializer.deserialize(element);
}

@FunctionalInterface
public static interface FineSerializer {
public JsonElement serialize(Object obj);
}

@FunctionalInterface
public static interface FineDeserializer {
public Object deserialize(JsonElement element);
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/minecrafttas/mctcommon/json/FineGson.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.minecrafttas.mctcommon.json;

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

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

/**
* A fine grained gson replacement
*
* @author Scribble
*/
public class FineGson {

private Map<Class<?>, FineTypeAdapter> typeAdapters = new HashMap<>();

private final Gson gsonInstance;

public FineGson(Gson gsonInstance) {
this.gsonInstance = gsonInstance;
}

public void registerTypeAdapter(Class<?> type, FineTypeAdapter adapter) {
typeAdapters.put(type, adapter);
}

public JsonElement serialize(Object obj) {
Class<?> type = obj.getClass();
if (!typeAdapters.containsKey(type))
return gsonInstance.toJsonTree(obj);

FineTypeAdapter adapter = typeAdapters.get(type);
return adapter.serialize(obj, this);
}

public Object deserialize(JsonElement element, Class<?> type) {
if (!typeAdapters.containsKey(type))
return gsonInstance.fromJson(element, type);

FineTypeAdapter adapter = typeAdapters.get(type);

return adapter.deserialize(element, type, this);
}

public Gson getGsonInstance() {
return gsonInstance;
}
}
146 changes: 146 additions & 0 deletions src/main/java/com/minecrafttas/mctcommon/json/FineTypeAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
package com.minecrafttas.mctcommon.json;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.minecrafttas.mctcommon.json.FineField.FineDeserializer;
import com.minecrafttas.mctcommon.json.FineField.FineMode;
import com.minecrafttas.mctcommon.json.FineField.FineSerializer;
import com.minecrafttas.tasmod.util.JsonUtils;

public abstract class FineTypeAdapter {

private final List<FineField> fineFields = new ArrayList<>();

private final List<FineField> additionalFields = new ArrayList<>();

public void register(String name, FineMode mode) {
register(new FineField(name, mode));
}

public void register(String name, FineSerializer customSerializer, FineDeserializer customDeserializer) {
register(new FineField(name, customSerializer, customDeserializer));
}

public void register(FineField field) {
this.fineFields.add(field);
}

public void registerAdditional(String name, FineSerializer customSerializer, FineDeserializer customDeserializer) {
this.additionalFields.add(new FineField(name, customSerializer, customDeserializer));
}

public JsonElement serialize(Object obj, FineGson fineJson) throws RuntimeException {
JsonObject out = new JsonObject();

Class<?> clazz = obj.getClass();
List<Field> clazzFields = getFieldList(clazz);

if (clazzFields.size() != fineFields.size()) {
throw new RuntimeException(String.format("Can't serialize %s: The field count differs: %s!=%s", clazz.getSimpleName(), clazzFields.size(), fineFields.size()));
}

for (int i = 0; i < clazzFields.size(); i++) {
Field field = clazzFields.get(i);
FineField fineField = fineFields.get(i);

Object fieldValue = null;
try {
field.setAccessible(true);
fieldValue = field.get(obj);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
continue;
}

String fieldName = fineField.getName();
System.out.println(String.format("[%s] Serializing field %s (%s)", obj.getClass(), field.getName(), fieldName));
switch (fineField.getMode()) {
case CUSTOM:
out.add(fieldName, fineField.serialize(fieldValue));
break;
case FINE:
out.add(fieldName, fineJson.serialize(fieldValue));
break;
case GSON:
out.add(fieldName, fineJson.getGsonInstance().toJsonTree(fieldValue));
break;

case EXCLUDED:
default:
break;
}
}

for (FineField fineField : additionalFields) {
out.add(fineField.getName(), fineField.serialize(null));
}
return out;
}

public Object deserialize(JsonElement element, Class<?> clazz, FineGson fineJson) {
List<Field> clazzFields = getFieldList(clazz);

if (clazzFields.size() != fineFields.size()) {
throw new RuntimeException(String.format("Can't deserialize %s: The field count differs: %s!=%s", clazz.getSimpleName(), clazzFields.size(), fineFields.size()));
}

JsonObject elementObj = element.getAsJsonObject();

Object out = constructNew(clazz);

for (int i = 0; i < clazzFields.size(); i++) {
Field field = clazzFields.get(i);
field.setAccessible(true);
FineField fineField = fineFields.get(i);
String fieldName = fineField.getName();
JsonElement fieldElement = elementObj.get(fieldName);

Object fieldValue = null;
switch (fineField.getMode()) {
case CUSTOM:
fieldValue = fineField.deserialize(fieldElement);
break;
case FINE:
fieldValue = fineJson.deserialize(fieldElement, field.getType());
break;
case GSON:
fieldValue = fineJson.getGsonInstance().fromJson(fieldElement, field.getType());
break;

case EXCLUDED:
default:
break;
}
if (fieldValue != null) {
try {
field.set(out, fieldValue);
} catch (IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
return out;
}

protected Object constructNew(Class<?> clazz) {
return JsonUtils.constructNew(clazz);
}

public static List<Field> getFieldList(Class<?> clazz) {
List<Field> fields = new ArrayList<>();
for (Field field : clazz.getDeclaredFields()) {
if (!field.getName().startsWith("this"))
fields.add(field);
}

Class<?> superclazz = clazz.getSuperclass();
if (superclazz != Object.class)
fields.addAll(getFieldList(superclazz));

return fields;
}
}
44 changes: 33 additions & 11 deletions src/main/java/com/minecrafttas/tasmod/TASmod.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.minecrafttas.tasmod;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.logging.log4j.LogManager;
Expand Down Expand Up @@ -31,6 +32,7 @@
import com.minecrafttas.tasmod.handlers.PlayUntilHandler;
import com.minecrafttas.tasmod.ktrng.GlobalRNG;
import com.minecrafttas.tasmod.ktrng.builtin.MathRNG;
import com.minecrafttas.tasmod.ktrng.builtin.SquidRNG;
import com.minecrafttas.tasmod.ktrng.builtin.WorldSeedRNG;
import com.minecrafttas.tasmod.ktrng.events.KillTheRNGMonitor;
import com.minecrafttas.tasmod.ktrng.handlers.UUIDHandler;
Expand All @@ -42,10 +44,13 @@
import com.minecrafttas.tasmod.savestates.handlers.SavestateGuiHandlerServer;
import com.minecrafttas.tasmod.savestates.handlers.SavestateResourcePackHandler;
import com.minecrafttas.tasmod.savestates.storage.builtin.ClientMotionStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.EntityBatSpawnPositionStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.EntitySquidRotationStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.EntityTickTimersStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.EntityAiTaskStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.EntityStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.KTRNGSeedStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.entity.BatSpawnPositionSubStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.entity.CreeperDetonateSubStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.entity.LivingTickTimersSubStorage;
import com.minecrafttas.tasmod.savestates.storage.builtin.entity.SquidRotationSubStorage;
import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer;
import com.minecrafttas.tasmod.ticksync.TickSyncServer;
import com.minecrafttas.tasmod.util.LoggerMarkers;
Expand Down Expand Up @@ -102,14 +107,14 @@ public class TASmod implements ModInitializer, EventServerStart, EventServerInit
public static GlobalRNG globalRandomness;

public static KTRNGSeedStorage seedStorage = new KTRNGSeedStorage();
public static EntityTickTimersStorage entityTickTimers = new EntityTickTimersStorage();
public static EntityBatSpawnPositionStorage entityBatSpawnPositionStorage = new EntityBatSpawnPositionStorage();
public static EntitySquidRotationStorage entitySquidRotationStorage = new EntitySquidRotationStorage();
public static EntityAiTaskStorage entityAiTaskStorage = new EntityAiTaskStorage();

public static MathRNG mathRandomness = new MathRNG(0);

public static WorldSeedRNG worldSeedRandomness = new WorldSeedRNG(0);

public static SquidRNG squidRNG = new SquidRNG(0L);

public static KillTheRNGMonitor debugRand = new KillTheRNGMonitor();

public static UUIDHandler uuidHandler = new UUIDHandler();
Expand Down Expand Up @@ -173,6 +178,7 @@ public void onServerStart(MinecraftServer server) {
EventListenerRegistry.register(globalRandomness);
}
mathRandomness = new MathRNG(0);
squidRNG.setSeed(globalRandomness.getCurrentSeed() + 1000L);
}

@Override
Expand Down Expand Up @@ -239,21 +245,37 @@ public void onServerStop(MinecraftServer mcserver) {
private void registerSavestateStorage() {
TASmodAPIRegistry.SAVESTATE_STORAGE.register(motionStorage);
TASmodAPIRegistry.SAVESTATE_STORAGE.register(seedStorage);
TASmodAPIRegistry.SAVESTATE_STORAGE.register(entityTickTimers);
TASmodAPIRegistry.SAVESTATE_STORAGE.register(entityBatSpawnPositionStorage);
TASmodAPIRegistry.SAVESTATE_STORAGE.register(entitySquidRotationStorage);
//@formatter:off
TASmodAPIRegistry.SAVESTATE_STORAGE.register(
new EntityStorage(
new BatSpawnPositionSubStorage(),
new CreeperDetonateSubStorage(),
new SquidRotationSubStorage(),
new LivingTickTimersSubStorage()
)
);
//@formatter:on
TASmodAPIRegistry.SAVESTATE_STORAGE.register(entityAiTaskStorage);
}

public static MinecraftServer getServerInstance() {
return serverInstance;
}

private void loadConfig(MinecraftServer server) {
Path configDir = server.getDataDirectory().toPath();
Path configDir = server.getDataDirectory().toPath().resolve("config");

if (!Files.exists(configDir)) {
try {
Files.createDirectory(configDir);
} catch (IOException e) {
LOGGER.catching(e);
}
}

ConfigurationRegistry SERVER_CONFIG_REGISTRY = new ConfigurationRegistry();
SERVER_CONFIG_REGISTRY.register(TASmodServerConfig.values());
config = new Configuration("TASmod Server Configuration", configDir.resolve("tasmod.cfg"), SERVER_CONFIG_REGISTRY);
config = new Configuration("TASmod Server Configuration", configDir.resolve("tasmod_server.cfg"), SERVER_CONFIG_REGISTRY);

config.load();
config.save();
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/minecrafttas/tasmod/TASmodClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ private void loadConfig(Minecraft mc) {
LOGGER.catching(e);
}
}
config = new Configuration("TASmod configuration", configDir.resolve("tasmod.cfg"), CLIENT_CONFIG_REGISTRY);
config = new Configuration("TASmod configuration", configDir.resolve("tasmod_client.cfg"), CLIENT_CONFIG_REGISTRY);

config.load();
config.save();
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/minecrafttas/tasmod/ktrng/builtin/SquidRNG.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.minecrafttas.tasmod.ktrng.builtin;

import com.minecrafttas.tasmod.ktrng.RandomBase;

public class SquidRNG extends RandomBase {

public SquidRNG(long l) {
super(l);
}

@Override
public String getExtensionName() {
return "SquidRNG";
}

}
Loading