diff --git a/.gitignore b/.gitignore index b63da45..0d8ed17 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ build/ .idea/jarRepositories.xml .idea/compiler.xml .idea/libraries/ +.idea/sonarlint/ *.iws *.iml *.ipr diff --git a/BaseLua/build.gradle.kts b/BaseLua/build.gradle.kts deleted file mode 100644 index 2bf5838..0000000 --- a/BaseLua/build.gradle.kts +++ /dev/null @@ -1,45 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - id("java-library") - kotlin("jvm") version "1.9.10" -} - -group = "org.anime_game_servers" -version = "0.1" - -repositories { - mavenCentral() -} - -dependencies { - testImplementation(platform("org.junit:junit-bom:5.9.1")) - testImplementation("org.junit.jupiter:junit-jupiter") - implementation("com.google.code.findbugs:jsr305:3.0.2") - implementation("com.esotericsoftware:reflectasm:1.11.9") - implementation(kotlin("stdlib-jdk8")) - implementation("io.github.oshai:kotlin-logging-jvm:5.1.0") -} - -tasks.test { - useJUnitPlatform() -} -val compileKotlin: KotlinCompile by tasks -compileKotlin.kotlinOptions { - jvmTarget = "17" -} -val compileTestKotlin: KotlinCompile by tasks -compileTestKotlin.kotlinOptions { - jvmTarget = "17" -} - - - -publishing { - publications { - create("maven") { - from(components["kotlin"]) - artifactId = "BaseLua" - } - } -} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaEngine.java b/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaEngine.java deleted file mode 100644 index a78b3b2..0000000 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaEngine.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.anime_game_servers.lua.engine; - -import org.anime_game_servers.lua.models.IntValueEnum; -import org.anime_game_servers.lua.models.ScriptType; -import org.anime_game_servers.lua.serialize.Serializer; - -import java.nio.file.Path; - -public interface LuaEngine { - ScriptConfig getScriptConfig(); - - > boolean addGlobalEnumByOrdinal(String name, T[] enumArray); - - & IntValueEnum> boolean addGlobalEnumByIntValue(String name, T[] enumArray); - - boolean addGlobalStaticClass(String name, Class staticClass); - - boolean addObject(String name, Object object); - - Serializer getSerializer(); - - default LuaScript getScript(String scriptName, ScriptType scriptType){ - final Path scriptPath = getScriptConfig().getScriptLoader().getScriptPath(scriptName); - return getScript(scriptPath, scriptType); - } - LuaScript getScript(Path scriptPath, ScriptType scriptType); - - LuaTable getTable(Object table); - - LuaTable createTable(); - -} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaTable.java b/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaTable.java deleted file mode 100644 index aa51d27..0000000 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaTable.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.anime_game_servers.lua.engine; - -import javax.annotation.Nullable; -import java.util.Set; - -public interface LuaTable { - boolean has(String key); - - @Nullable - Object get(String key); - - @Nullable - Object get(int key); - - int getInt(String key); - - int optInt(String key, int defaultValue); - - int getInt(int key); - - int optInt(int key, int defaultValue); - - void set(int key, int value); - - void set(String key, int value); - - double getDouble(String key); - - double optDouble(String key, double defaultValue); - - double getDouble(int key); - - double optDouble(int key, double defaultValue); - - float getFloat(String key); - - float optFloat(String key, float defaultValue); - - float getFloat(int key); - - float optFloat(int key, float defaultValue); - - void set(int key, double value); - - void set(String key, double value); - - boolean getBoolean(String key); - - boolean optBoolean(String key, boolean defaultValue); - - boolean getBoolean(int key); - - boolean optBoolean(int key, boolean defaultValue); - - void set(int key, boolean value); - - void set(String key, boolean value); - - String getString(String key); - - String optString(String key, String defaultValue); - - String getString(int key); - - String optString(int key, String defaultValue); - - void set(int key, String value); - - void set(String key, String value); - - @Nullable - LuaTable getTable(String key); - - @Nullable - LuaTable getTable(int key); - - void set(int key, LuaTable value); - - void set(String key, LuaTable value); - - Set getKeys(); - - int[] getAsIntArray(); - - int getSize(); - - Object getRawTable(); -} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/models/IntValueEnum.kt b/BaseLua/src/main/java/org/anime_game_servers/lua/models/IntValueEnum.kt deleted file mode 100644 index ecb2f01..0000000 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/models/IntValueEnum.kt +++ /dev/null @@ -1,5 +0,0 @@ -package org.anime_game_servers.lua.models - -interface IntValueEnum { - fun getValue(): Int -} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/BaseSerializer.java b/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/BaseSerializer.java deleted file mode 100644 index 452413c..0000000 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/BaseSerializer.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.anime_game_servers.lua.serialize; - - -import com.esotericsoftware.reflectasm.ConstructorAccess; -import com.esotericsoftware.reflectasm.MethodAccess; -import io.github.oshai.kotlinlogging.KLogger; -import io.github.oshai.kotlinlogging.KotlinLogging; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -public abstract class BaseSerializer implements Serializer { - private static KLogger logger = KotlinLogging.INSTANCE.logger(BaseSerializer.class.getName()); - - protected static final Map, MethodAccess> methodAccessCache = new ConcurrentHashMap<>(); - protected static final Map, ConstructorAccess> constructorCache = new ConcurrentHashMap<>(); - protected static final Map, Map> fieldMetaCache = new ConcurrentHashMap<>(); - public abstract List toList(Class type, Object obj); - - public abstract T toObject(Class type, Object obj); - - public abstract Map toMap(Class type, Object obj); - - - protected String getSetterName(String fieldName) { - if (fieldName == null || fieldName.length() == 0) { - return null; - } - if (fieldName.length() == 1) { - return "set" + fieldName.toUpperCase(); - } - return "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1); - } - - protected Map cacheType(Class type) { - if (fieldMetaCache.containsKey(type)) { - return fieldMetaCache.get(type); - } - if (!constructorCache.containsKey(type)) { - constructorCache.putIfAbsent(type, ConstructorAccess.get(type)); - } - var methodAccess = Optional.ofNullable(methodAccessCache.get(type)).orElse(MethodAccess.get(type)); - methodAccessCache.putIfAbsent(type, methodAccess); - - var fieldMetaMap = new HashMap(); - var methodNameSet = new HashSet<>(Arrays.stream(methodAccess.getMethodNames()).toList()); - - Class classtype = type; - while(classtype!=null){ - Arrays.stream(classtype.getDeclaredFields()) - .forEach(field -> { - if(methodNameSet.contains(getSetterName(field.getName()))) { - var setter = getSetterName(field.getName()); - var index = methodAccess.getIndex(setter); - fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType(), field)); - } else { - field.setAccessible(true); - fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), null, -1, field.getType(), field)); - } - }); - classtype = classtype.getSuperclass(); - } - - Arrays.stream(type.getFields()) - .filter(field -> !fieldMetaMap.containsKey(field.getName())) - .filter(field -> methodNameSet.contains(getSetterName(field.getName()))) - .forEach(field -> { - var setter = getSetterName(field.getName()); - var index = methodAccess.getIndex(setter); - fieldMetaMap.put(field.getName(), new FieldMeta(field.getName(), setter, index, field.getType(), field)); - }); - - fieldMetaCache.put(type, fieldMetaMap); - return fieldMetaMap; - } - - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, int value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null){ - fieldMeta.getField().setInt(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, double value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null) { - fieldMeta.getField().setDouble(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, float value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null) { - fieldMeta.getField().setFloat(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, long value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null) { - fieldMeta.getField().setLong(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, boolean value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null) { - fieldMeta.getField().setBoolean(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } - protected void set(Object object, @Nonnull FieldMeta fieldMeta, @Nullable MethodAccess methodAccess, Object value){ - try { - if (methodAccess != null && fieldMeta.getSetter() != null) { - methodAccess.invoke(object, fieldMeta.getIndex(), value); - } else if(fieldMeta.getField() != null) { - fieldMeta.getField().set(object, value); - } - } catch (Exception ex){ - logger.warn(ex, () -> "Failed to set field "+fieldMeta.getName()+" of type "+fieldMeta.getType()+" to value "+ value); - } - } -} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/Serializer.java b/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/Serializer.java deleted file mode 100644 index 6cf5531..0000000 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/Serializer.java +++ /dev/null @@ -1,4 +0,0 @@ -package org.anime_game_servers.lua.serialize; - -public interface Serializer { -} diff --git a/GILua/build.gradle.kts b/GILua/build.gradle.kts index deb283d..cb923e1 100644 --- a/GILua/build.gradle.kts +++ b/GILua/build.gradle.kts @@ -2,20 +2,22 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java-library") - kotlin("jvm") version "1.9.10" + kotlin("jvm") } -group = "org.anime_game_servers" +group = "org.anime_game_servers.lua" version = "0.1" repositories { mavenCentral() + mavenLocal() } dependencies { testImplementation(platform("org.junit:junit-bom:5.9.1")) testImplementation("org.junit.jupiter:junit-jupiter") - api(project(":BaseLua")) + implementation("org.anime_game_servers.lua:base-jvm:0.1") + api("org.anime_game_servers.core:gi:0.1") implementation("com.google.code.findbugs:jsr305:3.0.2") implementation(kotlin("stdlib-jdk8")) compileOnly("org.projectlombok:lombok:1.18.30") diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/Position.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/Position.java index cc05012..0b3e8a1 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/Position.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/Position.java @@ -1,8 +1,9 @@ package org.anime_game_servers.gi_lua.models; import com.github.davidmoten.rtreemulti.geometry.Point; +import org.anime_game_servers.core.gi.models.Vector; -public interface Position { +public interface Position extends Vector { float getX(); float getY(); float getZ(); diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ChallengeEventMarkType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ChallengeEventMarkType.java index 7f3f841..fd6c1fd 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ChallengeEventMarkType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ChallengeEventMarkType.java @@ -1,5 +1,9 @@ package org.anime_game_servers.gi_lua.models.constants; + +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum ChallengeEventMarkType { CHALLENGE_EVENT_NONE, FLIGHT_TIME, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EntityType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EntityType.java index 9fffab3..377e323 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EntityType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EntityType.java @@ -1,12 +1,16 @@ package org.anime_game_servers.gi_lua.models.constants; + +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum EntityType { - NONE, - AVATAR, - MONSTER, + NONE, // + AVATAR, // + MONSTER, // NPC, - GADGET, - REGION, + GADGET, // + REGION, // WEAPON, WEATHER, SCENE, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EventType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EventType.java index 15e8794..77d8632 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EventType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/EventType.java @@ -1,5 +1,9 @@ package org.anime_game_servers.gi_lua.models.constants; + +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public class EventType { public static final int EVENT_NONE = 0; /** diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ExhibitionPlayType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ExhibitionPlayType.java index ded3bf8..5c27a0e 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ExhibitionPlayType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ExhibitionPlayType.java @@ -1,5 +1,9 @@ package org.anime_game_servers.gi_lua.models.constants; + +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum ExhibitionPlayType { Challenge, Gallery, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FatherChallengeProperty.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FatherChallengeProperty.java index ba7d1e3..6697987 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FatherChallengeProperty.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FatherChallengeProperty.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum FatherChallengeProperty { DURATION, CUR_SUCC, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FlowSuiteOperatePolicy.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FlowSuiteOperatePolicy.java index e70b896..6b9cdd0 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FlowSuiteOperatePolicy.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/FlowSuiteOperatePolicy.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum FlowSuiteOperatePolicy { DEFAULT, COMPLETE diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupKillPolicy.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupKillPolicy.java index d916514..97419ad 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupKillPolicy.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupKillPolicy.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum GroupKillPolicy { GROUP_KILL_NONE, GROUP_KILL_ALL, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupLoadStrategy.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupLoadStrategy.java index 4a4d856..226661f 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupLoadStrategy.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/GroupLoadStrategy.java @@ -1,6 +1,6 @@ package org.anime_game_servers.gi_lua.models.constants; -import org.anime_game_servers.lua.models.IntValueEnum; +import org.anime_game_servers.core.base.interfaces.IntValueEnum; public enum GroupLoadStrategy implements IntValueEnum { GROUP_LOAD_NONE(0), diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/QuestState.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/QuestState.java deleted file mode 100644 index 3bb0753..0000000 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/QuestState.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.anime_game_servers.gi_lua.models.constants; - -import kotlin.collections.MapsKt; -import org.anime_game_servers.lua.models.IntValueEnum; - -import java.util.Arrays; - -public enum QuestState implements IntValueEnum { - NONE(0), - UNSTARTED(1), - UNFINISHED(2), - FINISHED(3), - FAILED(4); - private final int value; - - private QuestState(int value) { - this.value = value; - } - - @Override - public int getValue() { - return value; - } -} diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptGadgetState.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptGadgetState.java index d37548d..d948835 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptGadgetState.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptGadgetState.java @@ -1,5 +1,10 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaNames; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic +@LuaNames(names = {"GadgetState"}) public class ScriptGadgetState { public static final int Default = 0; public static final int GatherDrop = 1; diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptRegionShape.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptRegionShape.java index f6cb714..f4b8bec 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptRegionShape.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/ScriptRegionShape.java @@ -1,5 +1,10 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaNames; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic +@LuaNames(names = {"RegionShape"}) public class ScriptRegionShape { public static final int NONE = 0; public static final int SPHERE = 1; diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/SealBattleType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/SealBattleType.java index f706463..6d2c0f5 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/SealBattleType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/SealBattleType.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum SealBattleType { NONE, ENERGY_CHARGE, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/VisionLevelType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/VisionLevelType.java index 45616bf..162dd0f 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/VisionLevelType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/VisionLevelType.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum VisionLevelType { VISION_LEVEL_NORMAL, VISION_LEVEL_LITTLE_REMOTE, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreType.java index 73f9b89..94c5e5a 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreType.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants.temporary; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum GalleryProgressScoreType { GALLERY_PROGRESS_SCORE_NONE, GALLERY_PROGRESS_SCORE_NO_DEGRADE diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreUIType.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreUIType.java index ca8a1a2..7b2af0f 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreUIType.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/constants/temporary/GalleryProgressScoreUIType.java @@ -1,5 +1,8 @@ package org.anime_game_servers.gi_lua.models.constants.temporary; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; + +@LuaStatic public enum GalleryProgressScoreUIType { GALLERY_PROGRESS_SCORE_UI_TYPE_NONE, GALLERY_PROGRESS_SCORE_UI_TYPE_BUOYANT_COMBAT, diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/loader/GIScriptLoader.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/loader/GIScriptLoader.java index 340ba15..b72f122 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/loader/GIScriptLoader.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/loader/GIScriptLoader.java @@ -3,12 +3,6 @@ package org.anime_game_servers.gi_lua.models.loader; import io.github.oshai.kotlinlogging.KLogger; import io.github.oshai.kotlinlogging.KotlinLogging; import lombok.val; -import org.anime_game_servers.gi_lua.models.constants.*; -import org.anime_game_servers.gi_lua.models.constants.ExhibitionPlayType; -import org.anime_game_servers.gi_lua.models.constants.FlowSuiteOperatePolicy; -import org.anime_game_servers.gi_lua.models.constants.temporary.GalleryProgressScoreType; -import org.anime_game_servers.gi_lua.models.constants.temporary.GalleryProgressScoreUIType; -import org.anime_game_servers.gi_lua.script_lib.ScriptLib; import org.anime_game_servers.lua.engine.BaseScriptLoader; import org.anime_game_servers.lua.engine.LuaEngine; import org.anime_game_servers.lua.engine.LuaScript; @@ -16,7 +10,6 @@ import org.anime_game_servers.lua.engine.ScriptConfig; import org.anime_game_servers.lua.models.ScriptType; import javax.script.ScriptException; -import java.lang.annotation.ElementType; import java.nio.file.Path; public interface GIScriptLoader extends BaseScriptLoader { @@ -71,24 +64,9 @@ public interface GIScriptLoader extends BaseScriptLoader { } default void addDefaultsForEngine(LuaEngine luaEngine){ - luaEngine.addGlobalEnumByIntValue("QuestState", QuestState.values()); - luaEngine.addGlobalEnumByOrdinal("EntityType", EntityType.values()); - luaEngine.addGlobalEnumByOrdinal("ElementType", ElementType.values()); - - luaEngine.addGlobalEnumByOrdinal("GroupKillPolicy", GroupKillPolicy.values()); - luaEngine.addGlobalEnumByOrdinal("SealBattleType", SealBattleType.values()); - luaEngine.addGlobalEnumByOrdinal("FatherChallengeProperty", FatherChallengeProperty.values()); - luaEngine.addGlobalEnumByOrdinal("ChallengeEventMarkType", ChallengeEventMarkType.values()); - luaEngine.addGlobalEnumByOrdinal("VisionLevelType", VisionLevelType.values()); - luaEngine.addGlobalEnumByOrdinal("ExhibitionPlayType", ExhibitionPlayType.values()); - luaEngine.addGlobalEnumByOrdinal("FlowSuiteOperatePolicy", FlowSuiteOperatePolicy.values()); - luaEngine.addGlobalEnumByOrdinal("GalleryProgressScoreUIType", GalleryProgressScoreUIType.values()); - luaEngine.addGlobalEnumByOrdinal("GalleryProgressScoreType", GalleryProgressScoreType.values()); - - luaEngine.addGlobalStaticClass("EventType", EventType.class); - luaEngine.addGlobalStaticClass("GadgetState", ScriptGadgetState.class); - luaEngine.addGlobalStaticClass("RegionShape", ScriptRegionShape.class); - luaEngine.addGlobalStaticClass("ScriptLib", ScriptLib.class); + LuaEngine.registerNamespace("org.anime_game_servers.core.gi"); + LuaEngine.registerNamespace("org.anime_game_servers.gi_lua"); + luaEngine.addGlobals(); } default boolean loadSceneReplacementScript(ScriptParser parser){ @@ -102,8 +80,11 @@ public interface GIScriptLoader extends BaseScriptLoader { default boolean loadSceneMetaScript(int sceneId, ScriptParser parser){ return loadData(ScriptSource.SCENE, sceneId, "scene"+sceneId+".lua", ScriptType.DATA_STORAGE, parser); } - default boolean loadSceneBlockScript(int sceneId, int blockId, ScriptParser parser){ - return loadData(ScriptSource.SCENE, sceneId, "scene"+sceneId+"_block"+blockId+".lua", ScriptType.DATA_STORAGE, parser); + default boolean loadSceneBlockScript(ScriptSource scriptSource, int targetId, int blockId, ScriptParser parser){ + if(scriptSource == ScriptSource.SCENE) + return loadData(scriptSource, targetId, "scene"+targetId+"_block"+blockId+".lua", ScriptType.DATA_STORAGE, parser); + else + return loadData(scriptSource, targetId, "activity"+targetId+"_block"+blockId+".lua", ScriptType.DATA_STORAGE, parser); } default boolean loadSceneGroupScript(ScriptSource scriptSource, int targetId, int groupId, ScriptParser parser){ if(scriptSource == ScriptSource.SCENE) diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/ActivityMeta.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/ActivityMeta.java new file mode 100644 index 0000000..484ec52 --- /dev/null +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/ActivityMeta.java @@ -0,0 +1,89 @@ +package org.anime_game_servers.gi_lua.models.scene; + +import io.github.oshai.kotlinlogging.KLogger; +import io.github.oshai.kotlinlogging.KotlinLogging; +import lombok.Getter; +import lombok.ToString; +import lombok.val; +import org.anime_game_servers.gi_lua.models.loader.GIScriptLoader; +import org.anime_game_servers.gi_lua.models.scene.block.SceneBlock; +import org.anime_game_servers.gi_lua.models.scene.block.SceneGroupInfo; +import org.anime_game_servers.gi_lua.models.scene.group.SceneGroup; +import org.anime_game_servers.lua.engine.LuaScript; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@ToString +@Getter +public class ActivityMeta { + private static KLogger logger = KotlinLogging.INSTANCE.logger(ActivityMeta.class.getName()); + + private int activityId; + private SceneMeta parent; + private List blockIds; + private Map blocks; + private Map groupsInfos; + private Map groups; + + public static ActivityMeta of(SceneMeta parent, int sceneId, GIScriptLoader scriptLoader) { + return new ActivityMeta(parent,sceneId) + .load(scriptLoader); + } + + private ActivityMeta(SceneMeta parent, int activityId) { + this.activityId = activityId; + this.parent = parent; + } + + public ActivityMeta load(GIScriptLoader scriptLoader) { + if(!loadActivityMeta(scriptLoader)){ + return null; + } + loadBlocks(scriptLoader); + prepareGroups(); + return this; + } + + private boolean loadActivityMeta(GIScriptLoader scriptLoader){ + return scriptLoader.loadActivityMetaScript(activityId, (cs -> { + // Create blocks + this.blockIds = cs.getGlobalVariableList("blocks", Integer.class); + })); + } + + private void loadBlocks(GIScriptLoader scriptLoader){ + this.blocks = new HashMap<>(blockIds.size()); + this.groupsInfos = new HashMap<>(); + for(val blockId : blockIds){ + val block = SceneBlock.of(parent, this, blockId, scriptLoader); + this.blocks.put(blockId, block); + } + } + + private void prepareGroups(){ + this.groups = new HashMap<>(groupsInfos.size()); + for(val groupInfo : groupsInfos.values()){ + val group = SceneGroup.of(groupInfo); + this.groups.put(groupInfo.getId(), group); + } + } + + @Nullable + public SceneGroup getGroup(int id) { + return groups.get(id); + } + + @Nullable + public SceneGroupInfo getGroupInfo(int id) { + return groupsInfos.get(id); + } + + @Nullable + public SceneBlock getBlock(int id) { + return blocks.get(id); + } + +} diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/SceneMeta.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/SceneMeta.java index 834b627..a402c44 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/SceneMeta.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/SceneMeta.java @@ -24,6 +24,7 @@ public class SceneMeta { private int sceneId; private SceneConfig config; private List blockIds; + private Map activities = new HashMap<>(); private Map blocks; private Map groupsInfos; private Map groups; @@ -76,11 +77,38 @@ public class SceneMeta { this.blocks = new HashMap<>(blockIds.size()); this.groupsInfos = new HashMap<>(); for(val blockId : blockIds){ - val block = SceneBlock.of(this, 0, blockId, scriptLoader); + val block = SceneBlock.of(this, null, blockId, scriptLoader); this.blocks.put(blockId, block); } } + public void loadActivity(GIScriptLoader scriptLoader, int activityId){ + if(sceneId != 3){ + return; + } + var meta = activities.get(activityId); + if(meta == null){ + meta = ActivityMeta.of(this, activityId, scriptLoader); + activities.put(activityId, meta); + } + this.blocks.putAll(meta.getBlocks()); + this.groupsInfos.putAll(meta.getGroupsInfos()); + this.groups.putAll(meta.getGroups()); + } + + private void unloadActivity(int activityId){ + if(sceneId != 3){ + return; + } + var meta = activities.get(activityId); + if(meta == null){ + return; + } + this.blocks.keySet().removeAll(meta.getBlocks().keySet()); + this.groupsInfos.keySet().removeAll(meta.getGroupsInfos().keySet()); + this.groups.keySet().removeAll(meta.getGroups().keySet()); + } + private void prepareGroups(){ this.groups = new HashMap<>(groupsInfos.size()); for(val groupInfo : groupsInfos.values()){ diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/block/SceneBlock.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/block/SceneBlock.java index 572a183..94fb8f8 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/block/SceneBlock.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/block/SceneBlock.java @@ -5,9 +5,12 @@ import io.github.oshai.kotlinlogging.KLogger; import io.github.oshai.kotlinlogging.KotlinLogging; import lombok.*; import org.anime_game_servers.gi_lua.models.PositionImpl; +import org.anime_game_servers.gi_lua.models.loader.ScriptSource; +import org.anime_game_servers.gi_lua.models.scene.ActivityMeta; import org.anime_game_servers.gi_lua.models.scene.SceneMeta; import org.anime_game_servers.gi_lua.models.loader.GIScriptLoader; +import javax.annotation.Nullable; import java.util.Map; import java.util.stream.Collectors; @@ -25,20 +28,22 @@ public class SceneBlock { // internal only private transient boolean loaded; // Not an actual variable in the scripts either private transient SceneMeta meta; // Not an actual variable in the scripts either + private transient ActivityMeta activityMeta; // Not an actual variable in the scripts either private int sceneId; private int activityId; private int id; - public static SceneBlock of(SceneMeta sceneMeta, int activityId, int blockId, GIScriptLoader scriptLoader) { - val block = new SceneBlock(sceneMeta.getSceneId(), activityId, blockId, sceneMeta); + public static SceneBlock of(SceneMeta sceneMeta, @Nullable ActivityMeta activityMeta, int blockId, GIScriptLoader scriptLoader) { + val block = new SceneBlock(sceneMeta.getSceneId(), activityMeta != null ? activityMeta.getActivityId() : 0, blockId, sceneMeta, activityMeta); block.load(scriptLoader); return block; } - private SceneBlock(int sceneId, int activityId, int blockId, SceneMeta meta) { + private SceneBlock(int sceneId, int activityId, int blockId, SceneMeta meta, ActivityMeta activityMeta) { this.id = blockId; this.sceneId = sceneId; this.activityId = activityId; this.meta = meta; + this.activityMeta = activityMeta; } public void setLoaded(boolean loaded) { @@ -50,7 +55,10 @@ public class SceneBlock { return this; } this.setLoaded(true); - if( !scriptLoader.loadSceneBlockScript(sceneId, id, (cs -> { + + val scriptType = activityId == 0 ? ScriptSource.SCENE : ScriptSource.ACTIVITY; + val typeId = activityId == 0 ? sceneId : activityId; + if( !scriptLoader.loadSceneBlockScript(scriptType, typeId, id, (cs -> { // Set groups this.groupInfo = cs.getGlobalVariableList("groups", SceneGroupInfo.class).stream() .collect(Collectors.toMap(x -> x.getId(), y -> y, (a, b) -> a)); @@ -64,7 +72,12 @@ public class SceneBlock { }))){ return null; } - meta.getGroupsInfos().putAll(this.groupInfo); + if(activityMeta!=null) { + activityMeta.getGroupsInfos().putAll(this.groupInfo); + } else { + meta.getGroupsInfos().putAll(this.groupInfo); + } + logger.debug(() -> "Successfully loaded block " + this.id + " in scene "+sceneId+"."); return this; } diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/group/SceneRegion.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/group/SceneRegion.java index 54ff576..258cd37 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/group/SceneRegion.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/models/scene/group/SceneRegion.java @@ -1,7 +1,7 @@ package org.anime_game_servers.gi_lua.models.scene.group; import lombok.Getter; -import org.anime_game_servers.gi_lua.models.Position; +import org.anime_game_servers.core.gi.models.Vector; import org.anime_game_servers.gi_lua.models.PositionImpl; import org.anime_game_servers.gi_lua.models.constants.EntityType; import org.anime_game_servers.gi_lua.models.constants.ScriptRegionShape; @@ -24,7 +24,7 @@ public class SceneRegion extends SceneObject{ private List team_ability_group; private boolean is_trigger_reload_group = false; - public boolean contains(Position position) { + public boolean contains(Vector position) { switch (shape) { case ScriptRegionShape.CUBIC: return (Math.abs(pos.getX() - position.getX()) <= size.getX()/2f) && diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ControllerLuaContext.kt b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ControllerLuaContext.kt index 6bf66dc..56ec666 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ControllerLuaContext.kt +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ControllerLuaContext.kt @@ -1,5 +1,11 @@ package org.anime_game_servers.gi_lua.script_lib +/** + * Lua context for calls to a Gadget Controller scripts functions. + * This context always contains a reference to the entity that calls the controller function + */ interface ControllerLuaContext : LuaContext { val gadget:GadgetEntity + + fun > getScriptLibHandlerProvider(): ScriptLibControllerHandlerProvider } diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/GroupEventLuaContext.kt b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/GroupEventLuaContext.kt index 95f2b44..ee073b7 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/GroupEventLuaContext.kt +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/GroupEventLuaContext.kt @@ -3,9 +3,13 @@ package org.anime_game_servers.gi_lua.script_lib import org.anime_game_servers.gi_lua.models.scene.group.SceneGroup import org.anime_game_servers.gi_lua.models.ScriptArgs -interface GroupEventLuaContext: LuaContext { +interface GroupEventLuaContext : LuaContext { fun getGroupInstance(): SceneGroup fun getArgs(): ScriptArgs fun getScriptLibHandlerProvider(): ScriptLibGroupHandlerProvider + /*override fun uid() = getArgs().uid + override fun source_entity_id() = getArgs().source_eid + override fun target_entity_id() = getArgs().target_eid*/ + } \ No newline at end of file diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/LuaContext.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/LuaContext.java index 6d1d083..1e6b2cb 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/LuaContext.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/LuaContext.java @@ -5,4 +5,9 @@ import org.anime_game_servers.lua.engine.LuaEngine; public interface LuaContext { LuaEngine getEngine(); ScriptLibHandler getScriptLibHandler(); + + // fields used by some scripts + /*int uid(); + int source_entity_id(); + int target_entity_id();*/ } diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLib.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLib.java index 0ec6c35..df64cc0 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLib.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLib.java @@ -3,6 +3,7 @@ package org.anime_game_servers.gi_lua.script_lib; import io.github.oshai.kotlinlogging.KLogger; import io.github.oshai.kotlinlogging.KotlinLogging; import lombok.val; +import org.anime_game_servers.core.base.annotations.lua.LuaStatic; import org.anime_game_servers.gi_lua.models.constants.*; import org.anime_game_servers.gi_lua.models.constants.ExhibitionPlayType; import org.anime_game_servers.gi_lua.models.constants.FlowSuiteOperatePolicy; @@ -10,12 +11,11 @@ import org.anime_game_servers.gi_lua.models.constants.temporary.GalleryProgressS import org.anime_game_servers.gi_lua.models.constants.temporary.GalleryProgressScoreUIType; import org.anime_game_servers.lua.engine.LuaTable; -import java.util.ArrayList; - import static org.anime_game_servers.gi_lua.utils.ScriptUtils.luaToPos; import static org.anime_game_servers.gi_lua.utils.ScriptUtils.posToLua; import static org.anime_game_servers.gi_lua.script_lib.ScriptLibErrors.*; +@LuaStatic public class ScriptLib { /** @@ -701,7 +701,7 @@ public class ScriptLib { val isSkipUi = transportationParams.optBoolean("is_skip_ui", false); - if(targetsTable==null || targetsTable.getSize()==0 || luaPos == null){ + if(targetsTable==null || targetsTable.getSize() ==0 || luaPos == null){ scriptLogger.error(() -> "[TransPlayerToPos] Invalid params, either missing uid_list or pos"); return 1; } @@ -722,7 +722,7 @@ public class ScriptLib { val isSkipUi = transportationParams.optBoolean("is_skip_ui", false); - if(targetsTable==null || targetsTable.getSize()==0 || luaPos == null){ + if(targetsTable==null || targetsTable.getSize() ==0 || luaPos == null){ scriptLogger.error(() -> "[TransPlayerToPos] Invalid params, either missing uid_list or pos"); return 1; } @@ -841,25 +841,26 @@ public class ScriptLib { val killPolicyId = table.optInt("kill_policy", -1); if(groupId == -1){ scriptLogger.error(() -> "KillGroupEntity: groupId not set"); - return 1; + return INVALID_PARAMETER_TABLE_CONTENT.getValue(); } if(killPolicyId == -1){ - scriptLogger.error(() -> "KillGroupEntity: kill_policy not set"); return killByCfgIds(context, groupId, table); } return killByGroupPolicy(context, groupId, killPolicyId); } private static int killByGroupPolicy(GroupEventLuaContext context, int groupId, int killPolicyId){ + scriptLogger.debug(() -> "KillGroupEntity: kill by group policy"); if(killPolicyId >= GroupKillPolicy.values().length){ scriptLogger.error(() -> "KillGroupEntity: kill_policy out of bounds"); - return 2; + return INVALID_PARAMETER.getValue(); } val policy = GroupKillPolicy.values()[killPolicyId]; return context.getScriptLibHandler().KillGroupEntityByPolicy(context, groupId, policy); } private static int killByCfgIds(GroupEventLuaContext context, int groupId, LuaTable luaTable){ + scriptLogger.debug(() -> "KillGroupEntity: kill by cfg ids"); val monsterList = luaTable.getTable("monsters"); val gadgetList = luaTable.getTable("gadgets"); val monsters = monsterList != null ? monsterList.getAsIntArray() : new int[0]; @@ -970,11 +971,11 @@ public class ScriptLib { val galleryId = param4.optInt("gallery_id", -1); if(exhibitionTypeIndex < 0 || exhibitionTypeIndex >= ExhibitionPlayType.values().length){ scriptLogger.error(() -> "Invalid exhibition type " + exhibitionTypeIndex); - return 1; + return INVALID_PARAMETER_TABLE_CONTENT.getValue(); } if (galleryId == -1){ scriptLogger.error(() -> "Invalid gallery id " + galleryId); - return 2; + return INVALID_PARAMETER_TABLE_CONTENT.getValue(); } val exhibitionTypeEnum = ExhibitionPlayType.values()[exhibitionTypeIndex]; return context.getScriptLibHandler().AddExhibitionAccumulableDataAfterSuccess(context, uid, param2, param3, exhibitionTypeEnum, galleryId); @@ -1098,56 +1099,109 @@ public class ScriptLib { * Methods used in EntityControllers/using ControllerLuaContext */ - public static int SetGadgetState(ControllerLuaContext context, int gadgetState) { - return context.getScriptLibHandler().SetGadgetState(context, gadgetState); + public static int SetGadgetState(ControllerLuaContext context, int gadgetState) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.SetGadgetState(context, gadgetState); } - public static int GetGadgetState(ControllerLuaContext context) { - return context.getScriptLibHandler().GetGadgetState(context); + public static int GetGadgetState(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetGadgetState(context); } - public static int ResetGadgetState(ControllerLuaContext context, int gadgetState) { - return context.getScriptLibHandler().ResetGadgetState(context, gadgetState); + public static int ResetGadgetState(ControllerLuaContext context, int gadgetState) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.ResetGadgetState(context, gadgetState); } - public static int SetGearStartValue(ControllerLuaContext context, int startValue) { - return context.getScriptLibHandler().SetGearStartValue(context, startValue); + public static int SetGearStartValue(ControllerLuaContext context, int startValue) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.SetGearStartValue(context, startValue); } - public static int GetGearStartValue(ControllerLuaContext context) { - return context.getScriptLibHandler().GetGearStartValue(context); + public static int GetGearStartValue(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetGearStartValue(context); } - public static int SetGearStopValue(ControllerLuaContext context, int startValue) { - return context.getScriptLibHandler().SetGearStopValue(context, startValue); + public static int SetGearStopValue(ControllerLuaContext context, int startValue) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.SetGearStopValue(context, startValue); } - public static int GetGearStopValue(ControllerLuaContext context) { - return context.getScriptLibHandler().GetGearStopValue(context); + public static int GetGearStopValue(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetGearStopValue(context); } - public static int GetGadgetStateBeginTime(ControllerLuaContext context) { - return context.getScriptLibHandler().GetGadgetStateBeginTime(context); + public static int GetGadgetStateBeginTime(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetGadgetStateBeginTime(context); } - public static int GetContextGadgetConfigId(ControllerLuaContext context) { - return context.getScriptLibHandler().GetContextGadgetConfigId(context); + public static int GetContextGadgetConfigId(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetContextGadgetConfigId(context); } - public static int GetContextGroupId(ControllerLuaContext context) { - return context.getScriptLibHandler().GetContextGroupId(context); + public static int GetContextGroupId(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.GetContextGroupId(context); } - public static int SetGadgetEnableInteract(ControllerLuaContext context, int groupId, int configId, boolean enable) { - return context.getScriptLibHandler().SetGadgetEnableInteract(context, groupId, configId, enable); + public static int SetGadgetEnableInteract(ControllerLuaContext context, int groupId, int configId, boolean enable) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return handler.SetGadgetEnableInteract(context, groupId, configId, enable); } - public static int DropSubfield(ControllerLuaContext context, Object paramsTable) { + public static int DropSubfield(ControllerLuaContext context, Object paramsTable) { val params = context.getEngine().getTable(paramsTable); - return context.getScriptLibHandler().DropSubfield(context, params); + + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return NOT_IMPLEMENTED.getValue(); + } + return context.getScriptLibHandlerProvider().getGadgetControllerHandler().DropSubfield(context, params); } - public static int[] GetGatherConfigIdList(ControllerLuaContext context) { - return context.getScriptLibHandler().GetGatherConfigIdList(context); + public static int[] GetGatherConfigIdList(ControllerLuaContext context) { + val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler(); + if(handler == null){ + return null; + } + return handler.GetGatherConfigIdList(context); } } diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibControllerHandlerProvider.kt b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibControllerHandlerProvider.kt new file mode 100644 index 0000000..a65c8c4 --- /dev/null +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibControllerHandlerProvider.kt @@ -0,0 +1,8 @@ +package org.anime_game_servers.gi_lua.script_lib + +import org.anime_game_servers.gi_lua.script_lib.handler.GadgetControllerHandler + +interface ScriptLibControllerHandlerProvider> { + fun getScriptLibHandler(): ScriptLibHandler<*, *> + fun getGadgetControllerHandler(): GadgetControllerHandler? +} \ No newline at end of file diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibErrors.kt b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibErrors.kt index 58db7a6..dd580af 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibErrors.kt +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibErrors.kt @@ -1,6 +1,6 @@ package org.anime_game_servers.gi_lua.script_lib -import org.anime_game_servers.lua.models.IntValueEnum +import org.anime_game_servers.core.base.interfaces.IntValueEnum enum class ScriptLibErrors(private val _value:Int): IntValueEnum { NOT_IMPLEMENTED(-100), diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibHandler.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibHandler.java index 6ab0ffe..27d04cf 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibHandler.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/script_lib/ScriptLibHandler.java @@ -1,7 +1,8 @@ package org.anime_game_servers.gi_lua.script_lib; import lombok.val; -import org.anime_game_servers.gi_lua.models.Position; +import org.anime_game_servers.core.gi.enums.QuestState; +import org.anime_game_servers.core.gi.models.Vector; import org.anime_game_servers.gi_lua.models.constants.*; import org.anime_game_servers.gi_lua.models.constants.ExhibitionPlayType; import org.anime_game_servers.gi_lua.models.constants.FlowSuiteOperatePolicy; @@ -118,7 +119,7 @@ public interface ScriptLibHandler> { + /** + * Changes the state of the gadget that called the controller. + */ + fun SetGadgetState(context: ControllerEventContext, gadgetState: Int): Int + + /** + * Returns the current state of the gadget that called the controller. + */ + fun GetGadgetState(context: ControllerEventContext): Int + + /** + * Resets the gadgets state to its state when born state. + */ + fun ResetGadgetState(context: ControllerEventContext, gadgetState: Int): Int + + fun SetGearStartValue(context: ControllerEventContext, startValue: Int): Int + + fun GetGearStartValue(context: ControllerEventContext): Int + + fun SetGearStopValue(context: ControllerEventContext, startValue: Int): Int + + fun GetGearStopValue(context: ControllerEventContext): Int + + fun GetGadgetStateBeginTime(context: ControllerEventContext): Int + + /** + * Returns the config id of the gadget that called the controller. + */ + fun GetContextGadgetConfigId(context: ControllerEventContext): Int + + /** + * Returns the group id of the gadget that called the controller. + */ + fun GetContextGroupId(context: ControllerEventContext): Int + + /** + * Sets a gadget interacteable based on the config id and group id. + */ + fun SetGadgetEnableInteract(context: ControllerEventContext, groupId: Int, configId: Int, enable: Boolean): Int + + fun DropSubfield(context: ControllerEventContext, paramsTable: LuaTable?): Int + + fun GetGatherConfigIdList(context: ControllerEventContext): IntArray? +} \ No newline at end of file diff --git a/GILua/src/main/java/org/anime_game_servers/gi_lua/utils/ScriptUtils.java b/GILua/src/main/java/org/anime_game_servers/gi_lua/utils/ScriptUtils.java index 3d8fca0..35e4320 100644 --- a/GILua/src/main/java/org/anime_game_servers/gi_lua/utils/ScriptUtils.java +++ b/GILua/src/main/java/org/anime_game_servers/gi_lua/utils/ScriptUtils.java @@ -1,14 +1,14 @@ package org.anime_game_servers.gi_lua.utils; import lombok.val; -import org.anime_game_servers.gi_lua.models.Position; +import org.anime_game_servers.core.gi.models.Vector; import org.anime_game_servers.gi_lua.models.PositionImpl; import org.anime_game_servers.lua.engine.LuaEngine; import org.anime_game_servers.lua.engine.LuaTable; public class ScriptUtils { - public static LuaTable posToLua(Position position, LuaEngine engine){ + public static LuaTable posToLua(Vector position, LuaEngine engine){ var result = engine.createTable(); if(position != null){ result.set("x", position.getX()); @@ -23,7 +23,7 @@ public class ScriptUtils { return result; } - public static Position luaToPos(LuaTable position){ + public static Vector luaToPos(LuaTable position){ val result = new PositionImpl(); if(position != null){ result.setX(position.optInt("x", 0)); diff --git a/JNLuaEngine/build.gradle.kts b/JNLuaEngine/build.gradle.kts index c96906a..a643d01 100644 --- a/JNLuaEngine/build.gradle.kts +++ b/JNLuaEngine/build.gradle.kts @@ -2,10 +2,10 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java-library") - kotlin("jvm") version "1.9.10" + kotlin("jvm") } -group = "org.anime_game_servers" +group = "org.anime_game_servers.lua" version = "0.1" repositories { @@ -15,7 +15,7 @@ repositories { dependencies { testImplementation(platform("org.junit:junit-bom:5.9.1")) testImplementation("org.junit.jupiter:junit-jupiter") - implementation(project(":BaseLua")) + implementation("org.anime_game_servers.lua:base-jvm:0.1") implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("org.anime_game_servers:JNLua_GC:0.1.0") implementation(kotlin("stdlib-jdk8")) @@ -30,11 +30,11 @@ tasks.test { } val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } val compileTestKotlin: KotlinCompile by tasks compileTestKotlin.kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } publishing { diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.java b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.java deleted file mode 100644 index a37f108..0000000 --- a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.java +++ /dev/null @@ -1,111 +0,0 @@ -package org.anime_game_servers.jnlua_engine; - -import io.github.oshai.kotlinlogging.KLogger; -import io.github.oshai.kotlinlogging.KotlinLogging; -import lombok.Getter; -import org.anime_game_servers.lua.engine.LuaEngine; -import org.anime_game_servers.lua.engine.LuaScript; -import org.anime_game_servers.lua.engine.LuaTable; -import org.anime_game_servers.lua.engine.ScriptConfig; -import org.anime_game_servers.lua.models.IntValueEnum; -import org.anime_game_servers.lua.models.ScriptType; -import org.jetbrains.annotations.Nullable; -import org.terasology.jnlua.JavaFunction; - -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleBindings; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.AbstractMap; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -public class JNLuaEngine implements LuaEngine { - private static KLogger logger = KotlinLogging.INSTANCE.logger(JNLuaEngine.class.getName()); - @Getter - private final ScriptEngineManager manager; - @Getter(onMethod = @__(@Override)) - private final JNLuaSerializer serializer; - @Getter - private final SimpleBindings bindings; - @Getter(onMethod = @__(@Override)) - private final ScriptConfig scriptConfig; - - public JNLuaEngine(ScriptConfig scriptConfig) { - this.scriptConfig = scriptConfig; - this.manager = new ScriptEngineManager(); - this.bindings = new SimpleBindings(); - this.serializer = new JNLuaSerializer(); - - this.bindings.put("print", (JavaFunction) luaState -> { - logger.debug(() -> "[LUA] print " + luaState.checkString(1)); - return 1; - }); - - } - - @Override - public > boolean addGlobalEnumByOrdinal(String name, T[] enumArray) { - Map table = new HashMap<>(); - Arrays.stream(enumArray).forEach(e -> { - table.put(e.name(), e.ordinal()); - table.put(e.name().toUpperCase(), e.ordinal()); - }); - bindings.put(name, table); - return true; - } - - @Override - public & IntValueEnum> boolean addGlobalEnumByIntValue(String name, T[] enumArray) { - Map table = new HashMap<>(); - Arrays.stream(enumArray).forEach(e -> { - table.put(e.name(), e.getValue()); - table.put(e.name().toUpperCase(), e.getValue()); - }); - bindings.put(name, table); - return true; - } - - @Override - public boolean addGlobalStaticClass(String name, Class staticClass) { - try { - bindings.put(name, new StaticClassWrapper(staticClass)); - return true; - } catch (Exception e) { - logger.error("Failed to add static class to lua engine: " + name, e); - } - return false; - } - - @Override - public boolean addObject(String name, Object object) { - bindings.put(name, object); - return false; - } - - @Nullable - @Override - public LuaScript getScript(Path scriptPath, ScriptType scriptType) { - if (!Files.exists(scriptPath)) return null; - - try { - return new JNLuaScript(this, scriptPath, scriptType); - } catch (IOException | ScriptException e) { - throw new RuntimeException(e); - } - } - - @Override - public LuaTable getTable(Object table) { - return new JNLuaTable((AbstractMap) table); - } - - @Override - public LuaTable createTable() { - return new JNLuaTable(new HashMap<>()); - } -} diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.kt b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.kt new file mode 100644 index 0000000..42054e0 --- /dev/null +++ b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaEngine.kt @@ -0,0 +1,83 @@ +package org.anime_game_servers.jnlua_engine + +import io.github.oshai.kotlinlogging.KotlinLogging.logger +import org.anime_game_servers.lua.engine.LuaEngine +import org.anime_game_servers.lua.engine.LuaScript +import org.anime_game_servers.lua.engine.LuaTable +import org.anime_game_servers.lua.engine.ScriptConfig +import org.anime_game_servers.lua.models.ScriptType +import org.terasology.jnlua.JavaFunction +import org.terasology.jnlua.LuaState +import java.io.IOException +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import javax.script.ScriptEngineManager +import javax.script.ScriptException +import javax.script.SimpleBindings + +class JNLuaEngine(override val scriptConfig: ScriptConfig) : LuaEngine { + val manager = ScriptEngineManager() + + override val serializer: JNLuaSerializer = JNLuaSerializer() + + val bindings = SimpleBindings() + + init { + bindings["print"] = JavaFunction { luaState: LuaState -> + logger.debug { "[LUA] print " + luaState.checkString(1) } + 1 + } + } + + override fun > addGlobalEnum(name: String, enumArray: Array): Boolean { + val table: MutableMap = HashMap() + Arrays.stream(enumArray).forEach { e: T -> + val fieldName = getEnumFieldName(e) + val value = getEnumFieldValue(e) + table[fieldName] = value + table[fieldName.uppercase(Locale.getDefault())] = value + } + bindings[name] = table + return true + } + + override fun addGlobalStaticClass(name: String, staticClass: Class<*>): Boolean { + try { + bindings[name] = StaticClassWrapper(staticClass) + return true + } catch (e: Exception) { + logger.error(e) { "Failed to add static class to lua engine: $name" } + } + return false + } + + override fun addObject(name: String, `object`: Any): Boolean { + bindings[name] = `object` + return false + } + + override fun getScript(scriptPath: Path, scriptType: ScriptType): LuaScript? { + if (!Files.exists(scriptPath)) return null + + try { + return JNLuaScript(this, scriptPath, scriptType) + } catch (e: IOException) { + throw RuntimeException(e) + } catch (e: ScriptException) { + throw RuntimeException(e) + } + } + + override fun getTable(table: Any): LuaTable? { + return JNLuaTable((table as AbstractMap<*, *>)) + } + + override fun createTable(): LuaTable { + return JNLuaTable(HashMap()) + } + + companion object { + private val logger = logger(JNLuaEngine::class.java.name) + } +} diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaSerializer.java b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaSerializer.java index 43696bf..ddcf195 100644 --- a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaSerializer.java +++ b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaSerializer.java @@ -166,7 +166,6 @@ public class JNLuaSerializer extends BaseSerializer { set(object, fieldMeta, methodAccess, listObj); } else { set(object, fieldMeta, methodAccess, serialize(fieldMeta.getType(), fieldMeta.getField(), (LuaValueProxy) keyValue)); - //methodAccess.invoke(object, fieldMeta.index, keyValue); } } catch (Exception ex) { logger.error(ex, () -> "Exception serializing"); diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.java b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.java deleted file mode 100644 index 2b7fd17..0000000 --- a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.java +++ /dev/null @@ -1,255 +0,0 @@ -package org.anime_game_servers.jnlua_engine; - -import lombok.val; -import org.anime_game_servers.lua.engine.LuaTable; -import org.jetbrains.annotations.Nullable; - -import java.util.AbstractMap; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -public class JNLuaTable implements LuaTable { - - AbstractMap table; - - JNLuaTable(AbstractMap table) { - this.table = (AbstractMap) table; - } - - @Override - public boolean has(String key) { - return table.containsKey(key); - } - - @Override - public Object get(String key) { - return table.get(key); - } - - @Override - public Object get(int key) { - return table.get(key); - } - - @Override - public int getInt(String key) { - return ((Number) table.get(key)).intValue(); - } - - @Override - public int optInt(String key, int defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).intValue(); - return defaultValue; - } - - @Override - public int getInt(int key) { - return ((Number) table.get(key)).intValue(); - } - - @Override - public int optInt(int key, int defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).intValue(); - return defaultValue; - } - - @Override - public void set(int key, int value) { - table.put(key, value); - } - - @Override - public void set(String key, int value) { - table.put(key, value); - } - - @Override - public double getDouble(String key) { - return ((Number) table.get(key)).doubleValue(); - } - - @Override - public double optDouble(String key, double defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).doubleValue(); - return defaultValue; - } - - @Override - public double getDouble(int key) { - return ((Number) table.get(key)).doubleValue(); - } - - @Override - public double optDouble(int key, double defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).doubleValue(); - return defaultValue; - } - - @Override - public float getFloat(String key) { - return ((Number) table.get(key)).floatValue(); - } - - @Override - public float optFloat(String key, float defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).floatValue(); - return defaultValue; - } - - @Override - public float getFloat(int key) { - return ((Number) table.get(key)).floatValue(); - } - - @Override - public float optFloat(int key, float defaultValue) { - val value = table.get(key); - if (value instanceof Number) - return ((Number) value).floatValue(); - return defaultValue; - } - - @Override - public void set(int key, double value) { - table.put(key, value); - } - - @Override - public void set(String key, double value) { - table.put(key, value); - } - - @Override - public boolean getBoolean(String key) { - return (Boolean) table.get(key); - } - - @Override - public boolean optBoolean(String key, boolean defaultValue) { - val value = table.get(key); - if (value instanceof Boolean) - return (boolean) value; - return defaultValue; - } - - @Override - public boolean getBoolean(int key) { - return (Boolean) table.get(key); - } - - @Override - public boolean optBoolean(int key, boolean defaultValue) { - val value = table.get(key); - if (value instanceof Boolean) - return (boolean) value; - return defaultValue; - } - - @Override - public void set(int key, boolean value) { - table.put(key, value); - } - - @Override - public void set(String key, boolean value) { - table.put(key, value); - } - - @Override - public String getString(String key) { - return (String) table.get(key); - } - - @Override - public String optString(String key, String defaultValue) { - val value = table.get(key); - if (value instanceof String) - return (String) value; - return defaultValue; - } - - @Override - public String getString(int key) { - return (String) table.get(key); - } - - @Override - public String optString(int key, String defaultValue) { - val value = table.get(key); - if (value instanceof String) - return (String) value; - return defaultValue; - } - - @Override - public void set(int key, String value) { - table.put(key, value); - } - - @Override - public void set(String key, String value) { - table.put(key, value); - } - - @Nullable - @Override - public LuaTable getTable(String key) { - return new JNLuaTable((AbstractMap) table.get(key)); - } - - @Nullable - @Override - public LuaTable getTable(int key) { - return new JNLuaTable((AbstractMap) table.get(key)); - } - - @Override - public void set(int key, LuaTable value) { - table.put(key, value.getRawTable()); - } - - @Override - public void set(String key, LuaTable value) { - table.put(key, value.getRawTable()); - } - - @Override - public Set getKeys() { - //TODO check if this is correct - val keys = table.keySet(); - if (keys != null) { - return (Set) (Set) keys; - } - return IntStream.rangeClosed(1, table.size()).mapToObj(String::valueOf).collect(Collectors.toSet()); - } - - @Override - public int[] getAsIntArray() { - int[] result = new int[table.size()]; - for (int i = 0; i < table.size(); i++) { - result[i] = (Integer) table.get(i + 1); - } - return result; - } - - @Override - public int getSize() { - return table.size(); - } - - @Override - public Object getRawTable() { - return table; - } -} diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.kt b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.kt new file mode 100644 index 0000000..bbcd444 --- /dev/null +++ b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/JNLuaTable.kt @@ -0,0 +1,188 @@ +package org.anime_game_servers.jnlua_engine + +import org.anime_game_servers.lua.engine.LuaTable +import java.util.* +import java.util.stream.Collectors +import java.util.stream.IntStream + +class JNLuaTable internal constructor(table: AbstractMap<*, *>) : LuaTable { + var table: AbstractMap + + init { + this.table = table as AbstractMap + } + + override fun has(key: String): Boolean { + return table.containsKey(key) + } + + override fun get(key: String): Any? { + return table[key] + } + + override fun get(key: Int): Any? { + return table[key] + } + + override fun getInt(key: String): Int { + return (table[key] as Number).toInt() + } + + override fun optInt(key: String, defaultValue: Int): Int { + val value = table[key] + return (value as? Number)?.toInt() ?: defaultValue + } + + override fun getInt(key: Int): Int { + return (table[key] as Number).toInt() + } + + override fun optInt(key: Int, defaultValue: Int): Int { + val value = table[key] + return (value as? Number)?.toInt() ?: defaultValue + } + + override fun set(key: Int, value: Int) { + table[key] = value + } + + override fun set(key: String, value: Int) { + table[key] = value + } + + override fun getDouble(key: String): Double { + return (table[key] as Number).toDouble() + } + + override fun optDouble(key: String, defaultValue: Double): Double { + val value = table[key] + return (value as? Number)?.toDouble() ?: defaultValue + } + + override fun getDouble(key: Int): Double { + return (table[key] as Number).toDouble() + } + + override fun optDouble(key: Int, defaultValue: Double): Double { + val value = table[key] + return (value as? Number)?.toDouble() ?: defaultValue + } + + override fun getFloat(key: String): Float { + return (table[key] as Number).toFloat() + } + + override fun optFloat(key: String, defaultValue: Float): Float { + val value = table[key] + return (value as? Number)?.toFloat() ?: defaultValue + } + + override fun getFloat(key: Int): Float { + return (table[key] as Number).toFloat() + } + + override fun optFloat(key: Int, defaultValue: Float): Float { + val value = table[key] + return (value as? Number)?.toFloat() ?: defaultValue + } + + override fun set(key: Int, value: Double) { + table[key] = value + } + + override fun set(key: String, value: Double) { + table[key] = value + } + + override fun getBoolean(key: String): Boolean { + return table[key] as Boolean + } + + override fun optBoolean(key: String, defaultValue: Boolean): Boolean { + val value = table[key] + return value as? Boolean ?: defaultValue + } + + override fun getBoolean(key: Int): Boolean { + return table[key] as Boolean + } + + override fun optBoolean(key: Int, defaultValue: Boolean): Boolean { + val value = table[key] + return value as? Boolean ?: defaultValue + } + + override fun set(key: Int, value: Boolean) { + table[key] = value + } + + override fun set(key: String, value: Boolean) { + table[key] = value + } + + override fun getString(key: String): String { + return table[key] as String + } + + override fun optString(key: String, defaultValue: String?): String? { + val value = table[key] + return value as? String ?: defaultValue + } + + override fun getString(key: Int): String { + return table[key] as String + } + + override fun optString(key: Int, defaultValue: String?): String? { + val value = table[key] + return value as? String ?: defaultValue + } + + override fun set(key: Int, value: String) { + table[key] = value + } + + override fun set(key: String, value: String) { + table[key] = value + } + + override fun getTable(key: String): LuaTable? { + return (table[key] as? AbstractMap<*, *>?)?.let { JNLuaTable(it) } + } + + override fun getTable(key: Int): LuaTable? { + return (table[key] as? AbstractMap<*, *>?)?.let { JNLuaTable(it) } + } + + override fun set(key: Int, value: LuaTable) { + table[key] = value.getRawTable() + } + + override fun set(key: String, value: LuaTable) { + table[key] = value.getRawTable() + } + + override fun getKeys(): Set { + //TODO check if this is correct + return table.keys.let { + it as? Set + } ?: IntStream.rangeClosed(1, table.size).mapToObj { i: Int -> java.lang.String.valueOf(i) } + .collect(Collectors.toSet()) + } + + override fun getAsIntArray(): IntArray { + val result = IntArray(table.size) + for (i in 0 until table.size) { + result[i] = (table[i + 1] as Int) + } + return result + } + + override fun getSize(): Int { + return table.size + } + + override fun getRawTable(): Any { + return table + } +} diff --git a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/StaticClassWrapper.java b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/StaticClassWrapper.java index 86e6a9f..e43fde0 100644 --- a/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/StaticClassWrapper.java +++ b/JNLuaEngine/src/main/java/org/anime_game_servers/jnlua_engine/StaticClassWrapper.java @@ -5,7 +5,11 @@ import lombok.Data; import javax.annotation.Nonnull; -@Data @AllArgsConstructor +@Data public class StaticClassWrapper { @Nonnull private Class staticClass; + + public StaticClassWrapper(@Nonnull Class staticClass){ + this.staticClass = staticClass; + } } diff --git a/LuaJEngine/build.gradle.kts b/LuaJEngine/build.gradle.kts index 7566034..34a777f 100644 --- a/LuaJEngine/build.gradle.kts +++ b/LuaJEngine/build.gradle.kts @@ -2,9 +2,10 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java-library") + kotlin("jvm") } -group = "org.anime_game_servers" +group = "org.anime_game_servers.lua" version = "0.1" repositories { @@ -14,13 +15,14 @@ repositories { dependencies { testImplementation(platform("org.junit:junit-bom:5.9.1")) testImplementation("org.junit.jupiter:junit-jupiter") - implementation(project(":BaseLua")) + implementation("org.anime_game_servers.lua:base-jvm:0.1") implementation("com.google.code.findbugs:jsr305:3.0.2") implementation("org.anime_game_servers:luaj:3.0.3") compileOnly("org.projectlombok:lombok:1.18.30") annotationProcessor("org.projectlombok:lombok:1.18.30") implementation("com.esotericsoftware:reflectasm:1.11.9") implementation("io.github.oshai:kotlin-logging-jvm:5.1.0") + implementation(kotlin("stdlib-jdk8")) } tasks.test { @@ -35,3 +37,6 @@ publishing { } } } +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.java b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.java deleted file mode 100644 index f370edb..0000000 --- a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.anime_game_servers.luaj_engine; - -import io.github.oshai.kotlinlogging.KLogger; -import io.github.oshai.kotlinlogging.KotlinLogging; -import lombok.Getter; -import lombok.val; -import org.anime_game_servers.lua.engine.LuaEngine; -import org.anime_game_servers.lua.engine.LuaScript; -import org.anime_game_servers.lua.engine.ScriptConfig; -import org.anime_game_servers.lua.models.IntValueEnum; -import org.anime_game_servers.lua.models.ScriptType; -import org.luaj.vm2.LuaTable; -import org.luaj.vm2.lib.ResourceFinder; -import org.luaj.vm2.lib.jse.CoerceJavaToLua; -import org.luaj.vm2.script.LuajContext; - -import javax.annotation.Nullable; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Arrays; - -public class LuaJEngine implements LuaEngine { - private static KLogger logger = KotlinLogging.INSTANCE.logger(LuaJEngine.class.getName()); - private final ScriptEngineManager manager; - private final LuajContext context; - - @Getter(onMethod = @__(@Override)) - private final ScriptConfig scriptConfig; - - @Getter - private final ScriptEngine engine; - @Getter(onMethod = @__(@Override)) - private final LuaJSerializer serializer; - - public LuaJEngine(ScriptConfig scriptConfig) { - this.scriptConfig = scriptConfig; - manager = new ScriptEngineManager(); - engine = manager.getEngineByName("luaj"); - - serializer = new LuaJSerializer(); - context = (LuajContext) engine.getContext(); - - // Set engine to replace require as a temporary fix to missing scripts - context.globals.finder = new ResourceFinder() { - @Override - public InputStream findResource(String filename) { - val scriptPath = scriptConfig.getScriptLoader().getScriptPath(filename); - val stream = scriptConfig.getScriptLoader().openScript(scriptPath); - return stream!=null ? stream : new ByteArrayInputStream(new byte[0]); - } - - @Override - public boolean useRawParamString() { - return true; - } - }; - } - - @Override - public > boolean addGlobalEnumByOrdinal(String name, T[] enumArray) { - LuaTable table = new LuaTable(); - Arrays.stream(enumArray).forEach(e -> { - table.set(e.name(), e.ordinal()); - table.set(e.name().toUpperCase(), e.ordinal()); - }); - context.globals.set(name, table); - return true; - } - - @Override - public & IntValueEnum> boolean addGlobalEnumByIntValue(String name, T[] enumArray) { - LuaTable table = new LuaTable(); - Arrays.stream(enumArray).forEach(e -> { - table.set(e.name(), e.getValue()); - table.set(e.name().toUpperCase(), e.getValue()); - }); - context.globals.set(name, table); - return true; - } - - @Override - public boolean addGlobalStaticClass(String name, Class staticClass) { - try { - context.globals.set(name, CoerceJavaToLua.coerce(staticClass.getConstructor().newInstance())); - return true; - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | - NoSuchMethodException e) { - logger.error(e, () -> "Failed to add static class to lua engine: " + name); - } - return false; - } - - @Override - public boolean addObject(String name, Object object) { - context.globals.set(name, CoerceJavaToLua.coerce(object)); - return true; - } - - @Nullable - @Override - public LuaScript getScript(Path scriptPath, ScriptType scriptType) { - if (!Files.exists(scriptPath)) return null; - - try { - return new LuaJScript(this, scriptPath); - } catch (IOException | ScriptException e) { - throw new RuntimeException(e); - } - } - - @Override - public org.anime_game_servers.lua.engine.LuaTable getTable(Object table) { - if (table instanceof LuaTable) - return new LuaJTable(this, (LuaTable) table); - throw new IllegalArgumentException("Table must be a LuaTable"); - } - - @Override - public org.anime_game_servers.lua.engine.LuaTable createTable() { - return new LuaJTable(this, new LuaTable()); - } -} diff --git a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.kt b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.kt new file mode 100644 index 0000000..462e574 --- /dev/null +++ b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJEngine.kt @@ -0,0 +1,105 @@ +package org.anime_game_servers.luaj_engine + +import io.github.oshai.kotlinlogging.KotlinLogging.logger +import org.anime_game_servers.lua.engine.LuaEngine +import org.anime_game_servers.lua.engine.LuaScript +import org.anime_game_servers.lua.engine.LuaTable +import org.anime_game_servers.lua.engine.ScriptConfig +import org.anime_game_servers.lua.models.ScriptType +import org.luaj.vm2.lib.ResourceFinder +import org.luaj.vm2.lib.jse.CoerceJavaToLua +import org.luaj.vm2.script.LuajContext +import java.io.ByteArrayInputStream +import java.io.IOException +import java.io.InputStream +import java.lang.reflect.InvocationTargetException +import java.nio.file.Files +import java.nio.file.Path +import java.util.* +import javax.script.ScriptEngine +import javax.script.ScriptEngineManager +import javax.script.ScriptException + +class LuaJEngine(override val scriptConfig: ScriptConfig) : LuaEngine { + private val manager = ScriptEngineManager() + private val context: LuajContext + + val engine: ScriptEngine = manager.getEngineByName("luaj") + + override val serializer: LuaJSerializer = LuaJSerializer() + + init { + context = engine.context as LuajContext + + // Set engine to replace require as a temporary fix to missing scripts + context.globals.finder = object : ResourceFinder { + override fun findResource(filename: String): InputStream { + val scriptPath = scriptConfig.scriptLoader.getScriptPath(filename) + val stream = scriptConfig.scriptLoader.openScript(scriptPath!!) + return stream ?: ByteArrayInputStream(ByteArray(0)) + } + + override fun useRawParamString(): Boolean { + return true + } + } + } + + override fun > addGlobalEnum(name: String, enumArray: Array): Boolean { + val table = org.luaj.vm2.LuaTable() + Arrays.stream(enumArray).forEach { e: T -> + val fieldName = getEnumFieldName(e) + val value = getEnumFieldValue(e) + table[fieldName] = value + table[fieldName.uppercase(Locale.getDefault())] = value + } + context.globals[name] = table + return true + } + + override fun addGlobalStaticClass(name: String, staticClass: Class<*>): Boolean { + try { + context.globals[name] = CoerceJavaToLua.coerce(staticClass.getConstructor().newInstance()) + return true + } catch (e: InstantiationException) { + logger.error(e) { "Failed to add static class to lua engine: $name" } + } catch (e: IllegalAccessException) { + logger.error(e) { "Failed to add static class to lua engine: $name" } + } catch (e: InvocationTargetException) { + logger.error(e) { "Failed to add static class to lua engine: $name" } + } catch (e: NoSuchMethodException) { + logger.error(e) { "Failed to add static class to lua engine: $name" } + } + return false + } + + override fun addObject(name: String, `object`: Any): Boolean { + context.globals[name] = CoerceJavaToLua.coerce(`object`) + return true + } + + override fun getScript(scriptPath: Path, scriptType: ScriptType): LuaScript? { + if (!Files.exists(scriptPath)) return null + + try { + return LuaJScript(this, scriptPath) + } catch (e: IOException) { + throw RuntimeException(e) + } catch (e: ScriptException) { + throw RuntimeException(e) + } + } + + override fun getTable(table: Any): LuaTable? { + if (table is org.luaj.vm2.LuaTable) return LuaJTable(this, table) + throw IllegalArgumentException("Table must be a LuaTable") + } + + override fun createTable(): LuaTable { + return LuaJTable(this, org.luaj.vm2.LuaTable()) + } + + companion object { + private val logger = logger(LuaJEngine::class.java.name) + } +} diff --git a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJSerializer.java b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJSerializer.java index 8c6f072..0ebce25 100644 --- a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJSerializer.java +++ b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJSerializer.java @@ -2,9 +2,12 @@ package org.anime_game_servers.luaj_engine; import io.github.oshai.kotlinlogging.KLogger; import io.github.oshai.kotlinlogging.KotlinLogging; +import kotlin.Pair; +import lombok.val; import org.anime_game_servers.lua.serialize.BaseSerializer; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; +import org.luaj.vm2.ast.Str; import javax.annotation.Nullable; import java.lang.reflect.Field; @@ -31,34 +34,39 @@ public class LuaJSerializer extends BaseSerializer { @Override public Map toMap(Class type, Object obj) { - return serializeMap(type, (LuaTable) obj); + return serializeMap(String.class, type, (LuaTable) obj); } @Nullable private T valueToType(Class type, LuaValue keyValue) { - T object = null; + Object object = null; if (keyValue.istable()) { object = serialize(type, null, keyValue.checktable()); } else if (keyValue.isint()) { - object = (T) (Integer) keyValue.toint(); + object = (Integer) keyValue.toint(); } else if (keyValue.isnumber()) { - object = (T) (Float) keyValue.tofloat(); // terrible... + object = (Float) keyValue.tofloat(); // terrible... } else if (keyValue.isstring()) { - object = (T) keyValue.tojstring(); + object = keyValue.tojstring(); } else if (keyValue.isboolean()) { - object = (T) (Boolean) keyValue.toboolean(); + object = (Boolean) keyValue.toboolean(); } else { - object = (T) keyValue; + object = keyValue; } if (object == null) { logger.warn(() -> "Can't serialize value: "+keyValue+" to type: "+type); } - return object; + + if(String.class.isAssignableFrom(type)){ + return (T) String.valueOf(object); + } else { + return (T) object; + } } - private Map serializeMap(Class type, LuaTable table) { - Map map = new HashMap<>(); + private Map serializeMap(Class typeKey, Class typeValue, LuaTable table) { + Map map = new HashMap<>(); if (table == null) { return map; @@ -66,16 +74,24 @@ public class LuaJSerializer extends BaseSerializer { try { LuaValue[] keys = table.keys(); - for (LuaValue k : keys) { + for (LuaValue luaKey : keys) { try { - LuaValue keyValue = table.get(k); - T object = valueToType(type, keyValue); - - if (object != null) { - map.put(String.valueOf(k), object); + K key = valueToType(typeKey, luaKey); + if(key == null){ + logger.warn(() -> "Can't serialize key: "+luaKey+" to type: "+typeKey); + continue; } - } catch (Exception ex) { + LuaValue luaValue = table.get(luaKey); + V value = valueToType(typeValue, luaValue); + if(value == null){ + logger.warn(() -> "Can't serialize value: "+value+" to type: "+typeValue); + continue; + } + + map.put(key, value); + } catch (Exception ex) { + logger.debug(ex, () -> "Exception serializing map"); } } } catch (Exception e) { @@ -125,6 +141,34 @@ public class LuaJSerializer extends BaseSerializer { return null; } + private Pair, Class> getMapTypes(Class type, @Nullable Field field) { + Class key = null; + Class value = null; + if (field == null) { + val types = type.getTypeParameters(); + if(types.length < 2){ + return null; + } + key = types.getClass(); + value = types.getClass(); + } + else { + Type fieldType = field.getGenericType(); + if (fieldType instanceof ParameterizedType) { + val types = ((ParameterizedType) fieldType).getActualTypeArguments(); + if(types.length < 2){ + return null; + } + key = (Class) types[0]; + value = (Class) types[1]; + } + } + if(key!=null && value!=null){ + return new Pair<>(key, value); + } + + return null; + } public T serialize(Class type, @Nullable Field field, LuaTable table) { T object = null; @@ -138,6 +182,18 @@ public class LuaJSerializer extends BaseSerializer { return null; } } + if (type == Map.class) { + try { + val mapTypes = getMapTypes(type, field); + if(mapTypes == null){ + return null; + } + return (T) serializeMap(mapTypes.component1(), mapTypes.component2(), table); + } catch (Exception e) { + logger.error("Exception while serializing {}", type.getName(), e); + return null; + } + } try { if (!fieldMetaCache.containsKey(type)) { diff --git a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJValue.java b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJValue.java index d62d052..f4d4142 100644 --- a/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJValue.java +++ b/LuaJEngine/src/main/java/org/anime_game_servers/luaj_engine/LuaJValue.java @@ -1,8 +1,8 @@ package org.anime_game_servers.luaj_engine; -import org.anime_game_servers.lua.engine.LuaValue; +import org.anime_game_servers.lua.engine.LuaValueJvm; -public class LuaJValue implements LuaValue { +public class LuaJValue implements LuaValueJvm { private final org.luaj.vm2.LuaValue value; private final LuaJEngine engine; diff --git a/base/build.gradle.kts b/base/build.gradle.kts new file mode 100644 index 0000000..940712c --- /dev/null +++ b/base/build.gradle.kts @@ -0,0 +1,60 @@ +plugins { + kotlin("multiplatform") +} + +group = "org.anime_game_servers.lua" +version = "0.1" + +kotlin { + jvm { + jvmToolchain(17) + withJava() + testRuns["test"].executionTask.configure { + useJUnitPlatform() + } + } + js(IR) { + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } + } + } + } + val hostOs = System.getProperty("os.name") + val isMingwX64 = hostOs.startsWith("Windows") + val nativeTarget = when { + hostOs == "Mac OS X" -> macosX64("native") + hostOs == "Linux" -> linuxX64("native") + isMingwX64 -> mingwX64("native") + else -> throw GradleException("Host OS is not supported in Kotlin/Native.") + } + + + sourceSets { + val commonMain by getting { + dependencies { + api("org.anime_game_servers.core:base:0.1") + implementation(kotlin("reflect")) + } + } + val commonTest by getting { + } + val jvmMain by getting { + dependencies { + api("org.anime_game_servers.core:base-jvm:0.1") + implementation("io.github.oshai:kotlin-logging-jvm:5.1.0") + implementation("com.esotericsoftware:reflectasm:1.11.9") + implementation("com.google.code.findbugs:jsr305:3.0.2") + implementation(kotlin("reflect")) + implementation ("org.reflections:reflections:0.10.2") + } + } + val jvmTest by getting + val jsMain by getting + val jsTest by getting + val nativeMain by getting + val nativeTest by getting + } +} \ No newline at end of file diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaValue.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/engine/LuaValue.kt similarity index 91% rename from BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaValue.kt rename to base/src/commonMain/kotlin/org/anime_game_servers/lua/engine/LuaValue.kt index 7e579be..dfea14d 100644 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaValue.kt +++ b/base/src/commonMain/kotlin/org/anime_game_servers/lua/engine/LuaValue.kt @@ -15,5 +15,4 @@ interface LuaValue { fun asDouble(): Double fun asFloat(): Float fun asString(): String? - fun asObject(type: Class): T? } diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/models/BooleanLuaValue.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValue.kt similarity index 71% rename from BaseLua/src/main/java/org/anime_game_servers/lua/models/BooleanLuaValue.kt rename to base/src/commonMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValue.kt index 5ed163e..04e1edb 100644 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/models/BooleanLuaValue.kt +++ b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValue.kt @@ -1,6 +1,8 @@ package org.anime_game_servers.lua.models -class BooleanLuaValue(private val value: Boolean) : MockLuaValue() { +import kotlin.jvm.JvmField + +open class BooleanLuaValue(private val value: Boolean) : MockLuaValue { override fun isBoolean() = true override fun asBoolean() = value @@ -10,10 +12,6 @@ class BooleanLuaValue(private val value: Boolean) : MockLuaValue() { override fun asFloat() = if (value) 1f else 0f override fun asString() = value.toString() - override fun asObject(type: Class): T? { - return if (type == Boolean::class.java) type.cast(value) as T else null - } - companion object { @JvmField val TRUE = BooleanLuaValue(true) diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/models/IntLuaValue.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/IntLuaValue.kt similarity index 72% rename from BaseLua/src/main/java/org/anime_game_servers/lua/models/IntLuaValue.kt rename to base/src/commonMain/kotlin/org/anime_game_servers/lua/models/IntLuaValue.kt index 2ebc6da..fb57af3 100644 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/models/IntLuaValue.kt +++ b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/IntLuaValue.kt @@ -1,6 +1,8 @@ package org.anime_game_servers.lua.models -class IntLuaValue(private val value: Int) : MockLuaValue() { +import kotlin.jvm.JvmField + +open class IntLuaValue(protected val value: Int) : MockLuaValue { override fun isInteger() = true override fun asBoolean() = value != 0 @@ -10,10 +12,6 @@ class IntLuaValue(private val value: Int) : MockLuaValue() { override fun asFloat() = value.toFloat() override fun asString() = value.toString() - override fun asObject(type: Class): T? { - return if (type == Number::class.java) type.cast(value) as T? else null - } - companion object { @JvmField val ZERO = IntLuaValue(0) diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/models/MockLuaValue.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/MockLuaValue.kt similarity index 90% rename from BaseLua/src/main/java/org/anime_game_servers/lua/models/MockLuaValue.kt rename to base/src/commonMain/kotlin/org/anime_game_servers/lua/models/MockLuaValue.kt index fd970d7..9dd508e 100644 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/models/MockLuaValue.kt +++ b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/MockLuaValue.kt @@ -2,7 +2,7 @@ package org.anime_game_servers.lua.models import org.anime_game_servers.lua.engine.LuaValue -abstract class MockLuaValue : LuaValue { +interface MockLuaValue : LuaValue { override fun isNull() = false override fun isBoolean() = false override fun isInteger() = false diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/models/ScriptType.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/models/ScriptType.kt similarity index 100% rename from BaseLua/src/main/java/org/anime_game_servers/lua/models/ScriptType.kt rename to base/src/commonMain/kotlin/org/anime_game_servers/lua/models/ScriptType.kt diff --git a/base/src/commonMain/kotlin/org/anime_game_servers/lua/serialize/Serializer.kt b/base/src/commonMain/kotlin/org/anime_game_servers/lua/serialize/Serializer.kt new file mode 100644 index 0000000..96bf63f --- /dev/null +++ b/base/src/commonMain/kotlin/org/anime_game_servers/lua/serialize/Serializer.kt @@ -0,0 +1,3 @@ +package org.anime_game_servers.lua.serialize + +interface Serializer diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/BaseScriptLoader.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/BaseScriptLoader.kt similarity index 100% rename from BaseLua/src/main/java/org/anime_game_servers/lua/engine/BaseScriptLoader.kt rename to base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/BaseScriptLoader.kt diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaEngine.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaEngine.kt new file mode 100644 index 0000000..04fe108 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaEngine.kt @@ -0,0 +1,85 @@ +package org.anime_game_servers.lua.engine + +import org.anime_game_servers.core.base.annotations.lua.LuaNames +import org.anime_game_servers.core.base.annotations.lua.LuaStatic +import org.anime_game_servers.core.base.interfaces.IntKey +import org.anime_game_servers.core.base.interfaces.IntValueEnum +import org.anime_game_servers.lua.models.ScriptType +import org.anime_game_servers.lua.serialize.Serializer +import org.reflections.Reflections +import java.nio.file.Path + +interface LuaEngine { + val scriptConfig: ScriptConfig + + fun > addGlobalEnum(name: String, enumArray: Array): Boolean + + fun addGlobalStaticClass(name: String, staticClass: Class<*>): Boolean + + fun addObject(name: String, `object`: Any): Boolean + + val serializer: Serializer? + + fun getScript(scriptName: String, scriptType: ScriptType): LuaScript? { + val scriptPath = scriptConfig.scriptLoader.getScriptPath(scriptName) ?: return null + return getScript(scriptPath, scriptType) + } + + fun getScript(scriptPath: Path, scriptType: ScriptType): LuaScript? + + fun getTable(table: Any): LuaTable? + + fun createTable(): LuaTable + + fun getEnumFieldName(enumValue: Enum<*>): String { + return enumValue::class.java.getField(enumValue.name).getAnnotation(LuaNames::class.java)?.let { + it.names.firstOrNull() ?: enumValue.name + } ?: enumValue.name + } + fun getEnumFieldValue(enumValue: Enum<*>): Int { + return when (enumValue){ + is IntValueEnum -> enumValue.getValue() + is IntKey -> enumValue.getIntKey() + else -> enumValue.ordinal + } + } + + private fun getLuaName(classObject: Class<*>): String { + return classObject.getAnnotation(LuaNames::class.java)?.let { + it.names.firstOrNull() ?: classObject.simpleName + } ?: classObject.simpleName + } + + fun addGlobals() { + registeredEnums.forEach { enumClass -> + val enumArray = enumClass.enumConstants + addGlobalEnum(getLuaName(enumClass), enumArray) + } + registeredStaticClasses.forEach { staticClass -> + addGlobalStaticClass(getLuaName(staticClass), staticClass) + } + } + + companion object { + + var registeredEnums : MutableList>> = mutableListOf() + var registeredStaticClasses : MutableList> = mutableListOf() + @JvmStatic + fun registerNamespace(namespace: String){ + val reflector = Reflections(namespace) + registerDefaults(reflector) + } + @JvmStatic + fun registerDefaults(reflector: Reflections){ + reflector.getTypesAnnotatedWith(LuaStatic::class.java).forEach { annotatedClass -> + when{ + annotatedClass.isAnnotation -> return@forEach + annotatedClass.isEnum -> { + registeredEnums.add(annotatedClass as Class>) + } + else -> registeredStaticClasses.add(annotatedClass) + } + } + } + } +} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaScript.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaScript.kt similarity index 73% rename from BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaScript.kt rename to base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaScript.kt index 01327da..8f80b75 100644 --- a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/LuaScript.kt +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaScript.kt @@ -1,13 +1,12 @@ package org.anime_game_servers.lua.engine -import javax.annotation.Nonnull import javax.script.ScriptException interface LuaScript { - fun hasMethod(@Nonnull methodName: String): Boolean + fun hasMethod(methodName: String): Boolean @Throws(ScriptException::class, NoSuchMethodException::class) - fun callMethod(@Nonnull methodName: String, vararg args: Any?): LuaValue? + fun callMethod(methodName: String, vararg args: Any?): LuaValue? @Throws(ScriptException::class) fun evaluate() diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaTable.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaTable.kt new file mode 100644 index 0000000..8dd4913 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaTable.kt @@ -0,0 +1,81 @@ +package org.anime_game_servers.lua.engine + +interface LuaTable { + fun has(key: String): Boolean + + fun get(key: String): Any? + + fun get(key: Int): Any? + + fun getInt(key: String): Int + + fun optInt(key: String, defaultValue: Int): Int + + fun getInt(key: Int): Int + + fun optInt(key: Int, defaultValue: Int): Int + + fun set(key: Int, value: Int) + + fun set(key: String, value: Int) + + fun getDouble(key: String): Double + + fun optDouble(key: String, defaultValue: Double): Double + + fun getDouble(key: Int): Double + + fun optDouble(key: Int, defaultValue: Double): Double + + fun getFloat(key: String): Float + + fun optFloat(key: String, defaultValue: Float): Float + + fun getFloat(key: Int): Float + + fun optFloat(key: Int, defaultValue: Float): Float + + fun set(key: Int, value: Double) + + fun set(key: String, value: Double) + + fun getBoolean(key: String): Boolean + + fun optBoolean(key: String, defaultValue: Boolean): Boolean + + fun getBoolean(key: Int): Boolean + + fun optBoolean(key: Int, defaultValue: Boolean): Boolean + + fun set(key: Int, value: Boolean) + + fun set(key: String, value: Boolean) + + fun getString(key: String): String? + + fun optString(key: String, defaultValue: String?): String? + + fun getString(key: Int): String? + + fun optString(key: Int, defaultValue: String?): String? + + fun set(key: Int, value: String) + + fun set(key: String, value: String) + + fun getTable(key: String): LuaTable? + + fun getTable(key: Int): LuaTable? + + fun set(key: Int, value: LuaTable) + + fun set(key: String, value: LuaTable) + + fun getKeys(): Set + + fun getAsIntArray(): IntArray + + fun getSize(): Int + + fun getRawTable(): Any? +} diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaValueJvm.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaValueJvm.kt new file mode 100644 index 0000000..b8e1b83 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/LuaValueJvm.kt @@ -0,0 +1,5 @@ +package org.anime_game_servers.lua.engine + +interface LuaValueJvm : LuaValue { + fun asObject(type: Class): T? +} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/engine/ScriptConfig.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/ScriptConfig.kt similarity index 100% rename from BaseLua/src/main/java/org/anime_game_servers/lua/engine/ScriptConfig.kt rename to base/src/jvmMain/kotlin/org/anime_game_servers/lua/engine/ScriptConfig.kt diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValueJvm.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValueJvm.kt new file mode 100644 index 0000000..7a4c2e8 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/BooleanLuaValueJvm.kt @@ -0,0 +1,17 @@ +package org.anime_game_servers.lua.models + +import org.anime_game_servers.lua.engine.LuaValueJvm + +class BooleanLuaValueJvm(private val value: Boolean) : BooleanLuaValue(value), LuaValueJvm { + + override fun asObject(type: Class): T? { + return if (type == Boolean::class.java) type.cast(value) as T else null + } + + companion object { + @JvmField + val TRUE = BooleanLuaValueJvm(true) + @JvmField + val FALSE = BooleanLuaValueJvm(false) + } +} diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/IntLuaValueJvm.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/IntLuaValueJvm.kt new file mode 100644 index 0000000..d48e718 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/models/IntLuaValueJvm.kt @@ -0,0 +1,18 @@ +package org.anime_game_servers.lua.models + +import org.anime_game_servers.lua.engine.LuaValueJvm + +class IntLuaValueJvm(value: Int) : IntLuaValue(value), LuaValueJvm { + override fun asObject(type: Class): T? { + return if (type == Number::class.java) type.cast(value) as T? else null + } + + companion object { + @JvmField + val ZERO = IntLuaValueJvm(0) + @JvmField + val ONE = IntLuaValueJvm(1) + @JvmField + val N_ONE = IntLuaValueJvm(-1) + } +} diff --git a/base/src/jvmMain/kotlin/org/anime_game_servers/lua/serialize/BaseSerializer.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/serialize/BaseSerializer.kt new file mode 100644 index 0000000..90f1fe5 --- /dev/null +++ b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/serialize/BaseSerializer.kt @@ -0,0 +1,153 @@ +package org.anime_game_servers.lua.serialize + +import com.esotericsoftware.reflectasm.ConstructorAccess +import com.esotericsoftware.reflectasm.MethodAccess +import io.github.oshai.kotlinlogging.KotlinLogging.logger +import java.lang.reflect.Field +import java.util.* +import java.util.concurrent.ConcurrentHashMap +import javax.annotation.Nonnull + + +abstract class BaseSerializer : Serializer { + abstract fun toList(type: Class?, obj: Any?): List? + + abstract fun toObject(type: Class?, obj: Any?): T + + abstract fun toMap(type: Class?, obj: Any?): Map? + + protected fun getSetterName(fieldName: String?): String? { + if (fieldName == null || fieldName.length == 0) { + return null + } + if (fieldName.length == 1) { + return "set" + fieldName.uppercase(Locale.getDefault()) + } + return "set" + fieldName[0].uppercaseChar() + fieldName.substring(1) + } + + protected fun cacheType(type: Class): Map { + if (fieldMetaCache.containsKey(type)) { + return fieldMetaCache[type]!! + } + if (!constructorCache.containsKey(type)) { + constructorCache.putIfAbsent(type, ConstructorAccess.get(type)) + } + val methodAccess = Optional.ofNullable(methodAccessCache[type]).orElse(MethodAccess.get(type)) + methodAccessCache.putIfAbsent(type, methodAccess) + + val fieldMetaMap = HashMap() + val methodNameSet = HashSet(Arrays.stream(methodAccess.methodNames).toList()) + + var classtype: Class<*>? = type + while (classtype != null) { + Arrays.stream(classtype.declaredFields) + .forEach { field: Field -> + if (methodNameSet.contains(getSetterName(field.name))) { + val setter = getSetterName(field.name) + val index = methodAccess.getIndex(setter) + fieldMetaMap[field.name] = FieldMeta(field.name, setter, index, field.type, field) + } else { + field.isAccessible = true + fieldMetaMap[field.name] = FieldMeta(field.name, null, -1, field.type, field) + } + } + classtype = classtype.superclass + } + + Arrays.stream(type.fields) + .filter { field: Field -> !fieldMetaMap.containsKey(field.name) } + .filter { field: Field -> methodNameSet.contains(getSetterName(field.name)) } + .forEach { field: Field -> + val setter = getSetterName(field.name) + val index = methodAccess.getIndex(setter) + fieldMetaMap[field.name] = FieldMeta(field.name, setter, index, field.type, field) + } + + fieldMetaCache[type] = fieldMetaMap + return fieldMetaMap + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Int) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field.setInt(`object`, value) + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Double) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field.setDouble(`object`, value) + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Float) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field.setFloat(`object`, value) + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Long) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field.setLong(`object`, value) + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Boolean) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field.setBoolean(`object`, value) + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + protected fun set(`object`: Any?, @Nonnull fieldMeta: FieldMeta, methodAccess: MethodAccess?, value: Any) { + try { + if (methodAccess != null && fieldMeta.setter != null) { + methodAccess.invoke(`object`, fieldMeta.index, value) + } else if (fieldMeta.field != null) { + fieldMeta.field[`object`] = value + } + } catch (ex: Exception) { + logger.warn(ex) { "Failed to set field " + fieldMeta.name + " of type " + fieldMeta.type + " to value " + value } + } + } + + companion object { + private val logger = logger(BaseSerializer::class.java.name) + + @JvmField + protected val methodAccessCache: MutableMap, MethodAccess> = ConcurrentHashMap() + @JvmField + protected val constructorCache: MutableMap, ConstructorAccess<*>> = ConcurrentHashMap() + @JvmField + protected val fieldMetaCache: MutableMap, Map> = ConcurrentHashMap() + } +} diff --git a/BaseLua/src/main/java/org/anime_game_servers/lua/serialize/FieldMeta.kt b/base/src/jvmMain/kotlin/org/anime_game_servers/lua/serialize/FieldMeta.kt similarity index 100% rename from BaseLua/src/main/java/org/anime_game_servers/lua/serialize/FieldMeta.kt rename to base/src/jvmMain/kotlin/org/anime_game_servers/lua/serialize/FieldMeta.kt diff --git a/build.gradle.kts b/build.gradle.kts index 5c0297d..d0bb9a7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("java") id("maven-publish") - kotlin("jvm") version "1.9.10" + kotlin("multiplatform") version "1.9.22" apply false } group = "org.anime_game_servers" @@ -13,15 +13,15 @@ repositories { mavenCentral() } -dependencies { +/*dependencies { testImplementation(platform("org.junit:junit-bom:5.9.1")) testImplementation("org.junit.jupiter:junit-jupiter") implementation(kotlin("stdlib-jdk8")) -} +}*/ -tasks.test { +/*tasks.test { useJUnitPlatform() -} +}*/ allprojects { apply(plugin ="maven-publish") @@ -53,11 +53,11 @@ allprojects { } } } -val compileKotlin: KotlinCompile by tasks +/*val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { jvmTarget = "1.8" } val compileTestKotlin: KotlinCompile by tasks compileTestKotlin.kotlinOptions { jvmTarget = "1.8" -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index c2769bd..22b771d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -2,4 +2,4 @@ rootProject.name = "AnimeGameLua" include("LuaJEngine") include("JNLuaEngine") include("GILua") -include("BaseLua") +include("base")