From 5f8cc47e87b5b965849c8049bbfa4bcd0182eede Mon Sep 17 00:00:00 2001 From: Melledy <52122272+Melledy@users.noreply.github.com> Date: Thu, 19 May 2022 02:28:25 -0700 Subject: [PATCH] Fix bad casting exceptions with scene garbages objects --- .../emu/grasscutter/game/world/Scene.java | 1 + .../scripts/SceneScriptManager.java | 5 +++- .../emu/grasscutter/scripts/ScriptUtils.java | 28 +++++++++++++++++++ .../grasscutter/scripts/data/SceneGroup.java | 16 +++++++++-- .../scripts/serializer/LuaSerializer.java | 15 ++++++++-- 5 files changed, 60 insertions(+), 5 deletions(-) create mode 100644 src/main/java/emu/grasscutter/scripts/ScriptUtils.java diff --git a/src/main/java/emu/grasscutter/game/world/Scene.java b/src/main/java/emu/grasscutter/game/world/Scene.java index 57f11fa69..c1b6a2208 100644 --- a/src/main/java/emu/grasscutter/game/world/Scene.java +++ b/src/main/java/emu/grasscutter/game/world/Scene.java @@ -599,6 +599,7 @@ public class Scene { .map(g -> scriptManager.createGadget(group.id, group.block_id, g)).toList()); entities.addAll(suiteData.sceneMonsters.stream() .map(mob -> scriptManager.createMonster(group.id, group.block_id, mob)).toList()); + suite++; } while (suite < group.init_config.end_suite); } diff --git a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java index 11041dee8..5dd25a1df 100644 --- a/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java +++ b/src/main/java/emu/grasscutter/scripts/SceneScriptManager.java @@ -164,7 +164,10 @@ public class SceneScriptManager { public void loadGroupFromScript(SceneGroup group) { group.load(getScene().getId()); - group.variables.forEach(var -> this.getVariables().put(var.name, var.value)); + if (group.variables != null) { + group.variables.forEach(var -> this.getVariables().put(var.name, var.value)); + } + this.sceneGroups.put(group.id, group); if(group.regions != null){ diff --git a/src/main/java/emu/grasscutter/scripts/ScriptUtils.java b/src/main/java/emu/grasscutter/scripts/ScriptUtils.java new file mode 100644 index 000000000..b79fef9d6 --- /dev/null +++ b/src/main/java/emu/grasscutter/scripts/ScriptUtils.java @@ -0,0 +1,28 @@ +package emu.grasscutter.scripts; + +import java.util.HashMap; + +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; + +import emu.grasscutter.Grasscutter; + +public class ScriptUtils { + + public static HashMap toMap(LuaTable table) { + HashMap map = new HashMap<>(); + LuaValue[] rootKeys = table.keys(); + for (LuaValue k : rootKeys) { + if (table.get(k).istable()) { + map.put(k, toMap(table.get(k).checktable())); + } else { + map.put(k, table.get(k)); + } + } + return map; + } + + public static void print(LuaTable table) { + Grasscutter.getLogger().info(toMap(table).toString()); + } +} diff --git a/src/main/java/emu/grasscutter/scripts/data/SceneGroup.java b/src/main/java/emu/grasscutter/scripts/data/SceneGroup.java index fb67c518f..c0fb9ac78 100644 --- a/src/main/java/emu/grasscutter/scripts/data/SceneGroup.java +++ b/src/main/java/emu/grasscutter/scripts/data/SceneGroup.java @@ -9,6 +9,10 @@ import lombok.ToString; import javax.script.Bindings; import javax.script.CompiledScript; import javax.script.ScriptException; + +import org.luaj.vm2.LuaTable; +import org.luaj.vm2.LuaValue; + import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -106,9 +110,17 @@ public class SceneGroup { suites = ScriptLoader.getSerializer().toList(SceneSuite.class, bindings.get("suites")); regions = ScriptLoader.getSerializer().toList(SceneRegion.class, bindings.get("regions")); - garbages = ScriptLoader.getSerializer().toObject(SceneGarbage.class, bindings.get("garbages")); init_config = ScriptLoader.getSerializer().toObject(SceneInitConfig.class, bindings.get("init_config")); - + + // Garbages TODO fix properly later + Object garbagesValue = bindings.get("garbages"); + if (garbagesValue != null && garbagesValue instanceof LuaValue garbagesTable) { + garbages = new SceneGarbage(); + if (garbagesTable.checktable().get("gadgets") != LuaValue.NIL) { + garbages.gadgets = ScriptLoader.getSerializer().toList(SceneGadget.class, garbagesTable.checktable().get("gadgets").checktable()); + } + } + // Add variables to suite variables = ScriptLoader.getSerializer().toList(SceneVar.class, bindings.get("variables")); diff --git a/src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java b/src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java index 948be1739..8e668c48a 100644 --- a/src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java +++ b/src/main/java/emu/grasscutter/scripts/serializer/LuaSerializer.java @@ -2,6 +2,9 @@ package emu.grasscutter.scripts.serializer; import com.esotericsoftware.reflectasm.ConstructorAccess; import com.esotericsoftware.reflectasm.MethodAccess; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.scripts.ScriptUtils; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Data; @@ -9,6 +12,8 @@ import lombok.experimental.FieldDefaults; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -31,6 +36,10 @@ public class LuaSerializer implements Serializer { public List serializeList(Class type, LuaTable table) { List list = new ArrayList<>(); + if (table == null) { + return list; + } + try { LuaValue[] keys = table.keys(); for (LuaValue k : keys) { @@ -79,7 +88,7 @@ public class LuaSerializer implements Serializer { } try { - if(!methodAccessCache.containsKey(type)){ + if (!methodAccessCache.containsKey(type)) { cacheType(type); } var methodAccess = methodAccessCache.get(type); @@ -87,9 +96,10 @@ public class LuaSerializer implements Serializer { object = (T) constructorCache.get(type).newInstance(); - if(table == null){ + if (table == null) { return object; } + LuaValue[] keys = table.keys(); for (LuaValue k : keys) { try { @@ -117,6 +127,7 @@ public class LuaSerializer implements Serializer { } } } catch (Exception e) { + Grasscutter.getLogger().info(ScriptUtils.toMap(table).toString()); e.printStackTrace(); }