mirror of
https://github.com/Anime-Game-Servers/AnimeGamesLua.git
synced 2024-11-23 04:19:41 +00:00
[Refactoring] Made BaseLua multiplatform, renamed it to base and moved some annotations to the core repo
* Added LuaStatic annotation to allow auto loading of lua enums/models * Added LuaNames annotation handling to allow alternate names in lua * Moved some more Scriptlib handlers into its own model * First draft of activity group handling * Moved some engine classes to kotlin
This commit is contained in:
parent
2d462753f2
commit
44caa6d85d
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@ build/
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
.idea/sonarlint/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
@ -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<MavenPublication>("maven") {
|
||||
from(components["kotlin"])
|
||||
artifactId = "BaseLua"
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
||||
<T extends Enum<T>> boolean addGlobalEnumByOrdinal(String name, T[] enumArray);
|
||||
|
||||
<T extends Enum<T> & 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();
|
||||
|
||||
}
|
@ -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<String> getKeys();
|
||||
|
||||
int[] getAsIntArray();
|
||||
|
||||
int getSize();
|
||||
|
||||
Object getRawTable();
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package org.anime_game_servers.lua.models
|
||||
|
||||
interface IntValueEnum {
|
||||
fun getValue(): Int
|
||||
}
|
@ -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<Class<?>, MethodAccess> methodAccessCache = new ConcurrentHashMap<>();
|
||||
protected static final Map<Class<?>, ConstructorAccess<?>> constructorCache = new ConcurrentHashMap<>();
|
||||
protected static final Map<Class<?>, Map<String, FieldMeta>> fieldMetaCache = new ConcurrentHashMap<>();
|
||||
public abstract <T> List<T> toList(Class<T> type, Object obj);
|
||||
|
||||
public abstract <T> T toObject(Class<T> type, Object obj);
|
||||
|
||||
public abstract <T> Map<String,T> toMap(Class<T> 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 <T> Map<String, FieldMeta> cacheType(Class<T> 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<String, FieldMeta>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
package org.anime_game_servers.lua.serialize;
|
||||
|
||||
public interface Serializer {
|
||||
}
|
@ -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")
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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<Integer> blockIds;
|
||||
private Map<Integer, SceneBlock> blocks;
|
||||
private Map<Integer, SceneGroupInfo> groupsInfos;
|
||||
private Map<Integer, SceneGroup> 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);
|
||||
}
|
||||
|
||||
}
|
@ -24,6 +24,7 @@ public class SceneMeta {
|
||||
private int sceneId;
|
||||
private SceneConfig config;
|
||||
private List<Integer> blockIds;
|
||||
private Map<Integer, ActivityMeta> activities = new HashMap<>();
|
||||
private Map<Integer, SceneBlock> blocks;
|
||||
private Map<Integer, SceneGroupInfo> groupsInfos;
|
||||
private Map<Integer, SceneGroup> 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()){
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<String> 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) &&
|
||||
|
@ -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<GadgetEntity> : LuaContext {
|
||||
val gadget:GadgetEntity
|
||||
|
||||
fun <T: ControllerLuaContext<GadgetEntity>> getScriptLibHandlerProvider(): ScriptLibControllerHandlerProvider<GadgetEntity, T>
|
||||
}
|
||||
|
@ -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 <T: GroupEventLuaContext> getScriptLibHandlerProvider(): ScriptLibGroupHandlerProvider<T>
|
||||
/*override fun uid() = getArgs().uid
|
||||
override fun source_entity_id() = getArgs().source_eid
|
||||
override fun target_entity_id() = getArgs().target_eid*/
|
||||
|
||||
}
|
@ -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();*/
|
||||
}
|
||||
|
@ -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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> 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<Object> context) {
|
||||
val handler = context.getScriptLibHandlerProvider().getGadgetControllerHandler();
|
||||
if(handler == null){
|
||||
return null;
|
||||
}
|
||||
return handler.GetGatherConfigIdList(context);
|
||||
}
|
||||
}
|
||||
|
@ -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<GadgetEntity, ControllerEventContext : ControllerLuaContext<GadgetEntity>> {
|
||||
fun getScriptLibHandler(): ScriptLibHandler<*, *>
|
||||
fun getGadgetControllerHandler(): GadgetControllerHandler<GadgetEntity, ControllerEventContext>?
|
||||
}
|
@ -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),
|
||||
|
@ -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<GroupEventContext extends GroupEventLuaContext
|
||||
* @param pos The position to spawn the gadget at
|
||||
* @param rot The rotation of the gadget when spawned
|
||||
*/
|
||||
int CreateGadgetByConfigIdByPos(GroupEventContext context, int configId, Position pos, Position rot);
|
||||
int CreateGadgetByConfigIdByPos(GroupEventContext context, int configId, Vector pos, Vector rot);
|
||||
|
||||
|
||||
/**
|
||||
@ -135,7 +136,7 @@ public interface ScriptLibHandler<GroupEventContext extends GroupEventLuaContext
|
||||
* @param position The position to spawn the vehicle at
|
||||
* @param rot The rotation to spawn the vehicle with
|
||||
*/
|
||||
int CreateVehicle(GroupEventContext context, int uid, int gadgetId, Position position, Position rot);
|
||||
int CreateVehicle(GroupEventContext context, int uid, int gadgetId, Vector position, Vector rot);
|
||||
|
||||
int CheckRemainGadgetCountByGroupId(GroupEventContext context, LuaTable table);
|
||||
|
||||
@ -150,8 +151,10 @@ public interface ScriptLibHandler<GroupEventContext extends GroupEventLuaContext
|
||||
int ChangeGroupGadget(GroupEventContext context, LuaTable table) ;
|
||||
|
||||
int GetSceneOwnerUid(GroupEventContext context);
|
||||
@Nonnull QuestState GetHostQuestState(GroupEventContext context, int questId);
|
||||
@Nonnull QuestState GetQuestState(GroupEventContext context, int entityId, int questId);
|
||||
@Nonnull
|
||||
QuestState GetHostQuestState(GroupEventContext context, int questId);
|
||||
@Nonnull
|
||||
QuestState GetQuestState(GroupEventContext context, int entityId, int questId);
|
||||
int ShowReminder(GroupEventContext context, int reminderId);
|
||||
int RemoveEntityByConfigId(GroupEventContext context, int groupId, EntityType entityType, int configId);
|
||||
int CreateGroupTimerEvent(GroupEventContext context, int groupID, String source, double time);
|
||||
@ -248,9 +251,9 @@ public interface ScriptLibHandler<GroupEventContext extends GroupEventLuaContext
|
||||
|
||||
int MoveAvatarByPointArray(GroupEventContext context, int uid, int targetId, LuaTable var3, String var4);
|
||||
|
||||
int MovePlayerToPos(GroupEventContext context, int[] targetUIds, Position pos, Position rot, int radius, boolean isSkipUi);
|
||||
int MovePlayerToPos(GroupEventContext context, int[] targetUIds, Vector pos, Vector rot, int radius, boolean isSkipUi);
|
||||
|
||||
int TransPlayerToPos(GroupEventContext context, int[] targetUIds, Position pos, Position rot, int radius, boolean isSkipUi);
|
||||
int TransPlayerToPos(GroupEventContext context, int[] targetUIds, Vector pos, Vector rot, int radius, boolean isSkipUi);
|
||||
|
||||
int PlayCutScene(GroupEventContext context, int cutsceneId, int var2);
|
||||
|
||||
@ -317,9 +320,9 @@ public interface ScriptLibHandler<GroupEventContext extends GroupEventLuaContext
|
||||
int GetAvatarEntityIdByUid(GroupEventContext context, int uid);
|
||||
|
||||
|
||||
Position GetPosByEntityId(GroupEventContext context, int entityId);
|
||||
Vector GetPosByEntityId(GroupEventContext context, int entityId);
|
||||
|
||||
Position GetRotationByEntityId(GroupEventContext context, int entityId);
|
||||
Vector GetRotationByEntityId(GroupEventContext context, int entityId);
|
||||
|
||||
ActivityOpenAndCloseTime GetActivityOpenAndCloseTimeByScheduleId(GroupEventContext context, int scheduleId);
|
||||
|
||||
@ -440,34 +443,4 @@ public interface ScriptLibHandler<GroupEventContext extends GroupEventLuaContext
|
||||
* @param val5 TODO
|
||||
*/
|
||||
int ExecuteGadgetLua(GroupEventLuaContext context, int groupId, int gadgetCfgId, int activityType, int var4, int val5);
|
||||
|
||||
/**
|
||||
* Methods used in EntityControllers/using ControllerEventContext
|
||||
*/
|
||||
|
||||
int SetGadgetState(ControllerEventContext context, int gadgetState);
|
||||
|
||||
int GetGadgetState(ControllerEventContext context);
|
||||
|
||||
int ResetGadgetState(ControllerEventContext context, int gadgetState) ;
|
||||
|
||||
int SetGearStartValue(ControllerEventContext context, int startValue);
|
||||
|
||||
int GetGearStartValue(ControllerEventContext context);
|
||||
|
||||
int SetGearStopValue(ControllerEventContext context, int startValue);
|
||||
|
||||
int GetGearStopValue(ControllerEventContext context) ;
|
||||
|
||||
int GetGadgetStateBeginTime(ControllerEventContext context);
|
||||
|
||||
int GetContextGadgetConfigId(ControllerEventContext context) ;
|
||||
|
||||
int GetContextGroupId(ControllerEventContext context);
|
||||
|
||||
int SetGadgetEnableInteract(ControllerEventContext context, int groupId, int configId, boolean enable);
|
||||
|
||||
int DropSubfield(ControllerEventContext context, LuaTable paramsTable);
|
||||
|
||||
int[] GetGatherConfigIdList(ControllerEventContext context);
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
package org.anime_game_servers.gi_lua.script_lib.handler
|
||||
|
||||
import org.anime_game_servers.gi_lua.script_lib.ControllerLuaContext
|
||||
import org.anime_game_servers.lua.engine.LuaTable
|
||||
|
||||
/**
|
||||
* Handler for scriptlib functions used in EntityControllers, which use the ControllerEventContext.
|
||||
* These are only callable from a gadget controller context.
|
||||
*/
|
||||
interface GadgetControllerHandler<GadgetEntity, ControllerEventContext : ControllerLuaContext<GadgetEntity>> {
|
||||
/**
|
||||
* 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?
|
||||
}
|
@ -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));
|
||||
|
@ -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 {
|
||||
|
@ -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 <T extends Enum<T>> boolean addGlobalEnumByOrdinal(String name, T[] enumArray) {
|
||||
Map<String, Integer> 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 <T extends Enum<T> & IntValueEnum> boolean addGlobalEnumByIntValue(String name, T[] enumArray) {
|
||||
Map<String, Integer> 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<>());
|
||||
}
|
||||
}
|
@ -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 <T : Enum<*>> addGlobalEnum(name: String, enumArray: Array<T>): Boolean {
|
||||
val table: MutableMap<String, Int> = 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<Any, Any>())
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val logger = logger(JNLuaEngine::class.java.name)
|
||||
}
|
||||
}
|
@ -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");
|
||||
|
@ -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<Object, Object> table;
|
||||
|
||||
JNLuaTable(AbstractMap<?, ?> table) {
|
||||
this.table = (AbstractMap<Object, Object>) 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<String> getKeys() {
|
||||
//TODO check if this is correct
|
||||
val keys = table.keySet();
|
||||
if (keys != null) {
|
||||
return (Set<String>) (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;
|
||||
}
|
||||
}
|
@ -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<Any, Any>
|
||||
|
||||
init {
|
||||
this.table = table as AbstractMap<Any, Any>
|
||||
}
|
||||
|
||||
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<String> {
|
||||
//TODO check if this is correct
|
||||
return table.keys.let {
|
||||
it as? Set<String>
|
||||
} ?: 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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
@ -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 <T extends Enum<T>> 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 <T extends Enum<T> & 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());
|
||||
}
|
||||
}
|
@ -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 <T : Enum<*>> addGlobalEnum(name: String, enumArray: Array<T>): 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)
|
||||
}
|
||||
}
|
@ -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 <T> Map<String, T> toMap(Class<T> type, Object obj) {
|
||||
return serializeMap(type, (LuaTable) obj);
|
||||
return serializeMap(String.class, type, (LuaTable) obj);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private <T> T valueToType(Class<T> 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 <T> Map<String, T> serializeMap(Class<T> type, LuaTable table) {
|
||||
Map<String, T> map = new HashMap<>();
|
||||
private <K,V> Map<K, V> serializeMap(Class<K> typeKey, Class<V> typeValue, LuaTable table) {
|
||||
Map<K, V> 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<?>, 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> T serialize(Class<T> 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)) {
|
||||
|
@ -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;
|
||||
|
||||
|
60
base/build.gradle.kts
Normal file
60
base/build.gradle.kts
Normal file
@ -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
|
||||
}
|
||||
}
|
@ -15,5 +15,4 @@ interface LuaValue {
|
||||
fun asDouble(): Double
|
||||
fun asFloat(): Float
|
||||
fun asString(): String?
|
||||
fun <T> asObject(type: Class<T>): T?
|
||||
}
|
@ -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 <T> asObject(type: Class<T>): T? {
|
||||
return if (type == Boolean::class.java) type.cast(value) as T else null
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val TRUE = BooleanLuaValue(true)
|
@ -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 <T> asObject(type: Class<T>): T? {
|
||||
return if (type == Number::class.java) type.cast(value) as T? else null
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val ZERO = IntLuaValue(0)
|
@ -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
|
@ -0,0 +1,3 @@
|
||||
package org.anime_game_servers.lua.serialize
|
||||
|
||||
interface Serializer
|
@ -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 <T : Enum<*>> addGlobalEnum(name: String, enumArray: Array<T>): 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<Class<Enum<*>>> = mutableListOf()
|
||||
var registeredStaticClasses : MutableList<Class<*>> = 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<Enum<*>>)
|
||||
}
|
||||
else -> registeredStaticClasses.add(annotatedClass)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
@ -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<String?>
|
||||
|
||||
fun getAsIntArray(): IntArray
|
||||
|
||||
fun getSize(): Int
|
||||
|
||||
fun getRawTable(): Any?
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package org.anime_game_servers.lua.engine
|
||||
|
||||
interface LuaValueJvm : LuaValue {
|
||||
fun <T> asObject(type: Class<T>): T?
|
||||
}
|
@ -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 <T> asObject(type: Class<T>): 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)
|
||||
}
|
||||
}
|
@ -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 <T> asObject(type: Class<T>): 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)
|
||||
}
|
||||
}
|
@ -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 <T> toList(type: Class<T>?, obj: Any?): List<T>?
|
||||
|
||||
abstract fun <T> toObject(type: Class<T>?, obj: Any?): T
|
||||
|
||||
abstract fun <T> toMap(type: Class<T>?, obj: Any?): Map<String?, T>?
|
||||
|
||||
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 <T> cacheType(type: Class<T>): Map<String, FieldMeta> {
|
||||
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<String, FieldMeta>()
|
||||
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<Class<*>, MethodAccess> = ConcurrentHashMap()
|
||||
@JvmField
|
||||
protected val constructorCache: MutableMap<Class<*>, ConstructorAccess<*>> = ConcurrentHashMap()
|
||||
@JvmField
|
||||
protected val fieldMetaCache: MutableMap<Class<*>, Map<String, FieldMeta>> = ConcurrentHashMap()
|
||||
}
|
||||
}
|
@ -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"
|
||||
}
|
||||
}*/
|
@ -2,4 +2,4 @@ rootProject.name = "AnimeGameLua"
|
||||
include("LuaJEngine")
|
||||
include("JNLuaEngine")
|
||||
include("GILua")
|
||||
include("BaseLua")
|
||||
include("base")
|
||||
|
Loading…
Reference in New Issue
Block a user