mirror of
https://github.com/Anime-Game-Servers/AnimeGamesLua.git
synced 2024-11-23 04:19:41 +00:00
[Refactoring] Refactored ScriptLoader handling to make it more flexible
This commit is contained in:
parent
44caa6d85d
commit
4daa7f98a4
@ -25,6 +25,11 @@ dependencies {
|
||||
implementation("com.github.davidmoten:rtree-multi:0.1")
|
||||
implementation("io.github.oshai:kotlin-logging-jvm:5.1.0")
|
||||
}
|
||||
tasks.withType<KotlinCompile>().configureEach {
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
|
@ -0,0 +1,82 @@
|
||||
package org.anime_game_servers.gi_lua.models.loader
|
||||
|
||||
import org.anime_game_servers.lua.engine.BaseScriptLoader
|
||||
import org.anime_game_servers.lua.models.ScriptType
|
||||
|
||||
interface SceneScriptParams : BaseScriptLoader.ScriptLoadParams {
|
||||
val scriptSource: ScriptSource
|
||||
val targetId: Int
|
||||
|
||||
override fun getBaseDirectory() = if(scriptSource == ScriptSource.ACTIVITY)
|
||||
"Activity/$targetId/"
|
||||
else "Scene/$targetId/"
|
||||
}
|
||||
data class SceneGroupScriptLoadParams(
|
||||
override val scriptSource: ScriptSource,
|
||||
override val targetId: Int,
|
||||
val groupId: Int
|
||||
) : SceneScriptParams {
|
||||
override fun getScriptName(): String = if(scriptSource == ScriptSource.ACTIVITY)
|
||||
"activity${targetId}_group${groupId}.lua"
|
||||
else "scene${targetId}_group${groupId}.lua"
|
||||
override fun getScriptType(): ScriptType = ScriptType.EXECUTABLE
|
||||
}
|
||||
|
||||
data class SceneBlockScriptLoadParams(
|
||||
override val scriptSource: ScriptSource,
|
||||
override val targetId: Int,
|
||||
val blockId: Int
|
||||
) : SceneScriptParams {
|
||||
override fun getScriptName(): String = if(scriptSource == ScriptSource.ACTIVITY)
|
||||
"activity${targetId}_block${blockId}.lua"
|
||||
else "scene${targetId}_block${blockId}.lua"
|
||||
}
|
||||
|
||||
data class SceneDummyPointScriptLoadParams(
|
||||
val sceneId: Int
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Scene/$sceneId/"
|
||||
override fun getScriptName(): String = "scene${sceneId}_dummy_points.lua"
|
||||
}
|
||||
|
||||
data class SceneMetaScriptLoadParams(
|
||||
val sceneId: Int
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Scene/$sceneId/"
|
||||
override fun getScriptName(): String = "scene$sceneId.lua"
|
||||
}
|
||||
|
||||
data class ActivityMetaScriptLoadParams(
|
||||
val activityId: Int
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Activity/$activityId/"
|
||||
override fun getScriptName(): String = "activity$activityId.lua"
|
||||
}
|
||||
|
||||
class SceneReplacementScriptLoadParams : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Scene/"
|
||||
override fun getScriptName(): String = "groups_replacement.lua"
|
||||
}
|
||||
|
||||
data class ShardQuestScriptLoadParams(
|
||||
val questId: Int
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Quest/Share/"
|
||||
override fun getScriptName(): String = "Q${questId}ShareConfig.lua"
|
||||
}
|
||||
data class GadgetScriptLoadParams(
|
||||
val gadgetScript: String
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
override fun getBaseDirectory() = "Gadget/"
|
||||
override fun getScriptName(): String = gadgetScript
|
||||
override fun getScriptType(): ScriptType = ScriptType.EXECUTABLE
|
||||
}
|
||||
data class CommonScriptLoadParams(
|
||||
val commonPath: String,
|
||||
val commonScript: String
|
||||
) : BaseScriptLoader.ScriptLoadParams {
|
||||
// TODO constructor that accepts a single common parameter from lua
|
||||
override fun getBaseDirectory() = "Common/$commonPath"
|
||||
override fun getScriptName(): String = commonScript
|
||||
override fun getScriptType(): ScriptType = ScriptType.EXECUTABLE
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
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.lua.engine.BaseScriptLoader;
|
||||
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.ScriptType;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public interface GIScriptLoader extends BaseScriptLoader {
|
||||
KLogger logger = KotlinLogging.INSTANCE.logger(GIScriptLoader.class.getName());
|
||||
LuaScript getScript(ScriptSource scriptSource, int typeId, String scriptName, Path scriptPath, ScriptType scriptType);
|
||||
ScriptConfig getScriptConfig();
|
||||
|
||||
default LuaScript getScript(ScriptSource scriptSource, String scriptName, Path scriptPath, ScriptType scriptType){
|
||||
if (scriptSource.getNeedsId())
|
||||
throw new IllegalArgumentException("ScriptSource "+scriptSource.name()+" needs an id");
|
||||
return getScript(scriptSource, 0, scriptName, scriptPath, scriptType);
|
||||
}
|
||||
|
||||
default Path getScriptPath(ScriptSource type, String scriptName){
|
||||
if (type.getNeedsId())
|
||||
throw new IllegalArgumentException("ScriptSource "+type.name()+" needs an id");
|
||||
return getScriptPath(type, 0, scriptName);
|
||||
}
|
||||
|
||||
default Path getScriptPath(ScriptSource type, int typeId, String scriptName){
|
||||
val basePath = switch (type) {
|
||||
case SCENE -> "Scene/" + typeId + "/" + scriptName;
|
||||
case SCENE_REPLACEMENT -> "Scene/" + scriptName;
|
||||
case ACTIVITY-> "Activity/" + typeId + "/" + scriptName;
|
||||
case COMMON -> "Common/" + scriptName;
|
||||
case GADGET -> "Gadget/" + scriptName;
|
||||
case SHARED_QUESTS -> "Quest/Share/" + scriptName;
|
||||
};
|
||||
return getScriptPath(basePath);
|
||||
}
|
||||
|
||||
default boolean loadData(ScriptSource type, int typeId, String scriptName, ScriptType scriptType, ScriptParser parser) {
|
||||
val path = getScriptPath(type, typeId, scriptName);
|
||||
val cs = getScript(type, typeId, scriptName, path, scriptType);
|
||||
|
||||
if (cs == null) {
|
||||
logger.warn(() -> "No script found for "+type.name()+" " + typeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Eval script
|
||||
try {
|
||||
cs.evaluate();
|
||||
|
||||
parser.parse(cs);
|
||||
|
||||
} catch (ScriptException exception) {
|
||||
logger.error(exception, () -> "An error occurred while running the script "+scriptName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
default void addDefaultsForEngine(LuaEngine luaEngine){
|
||||
LuaEngine.registerNamespace("org.anime_game_servers.core.gi");
|
||||
LuaEngine.registerNamespace("org.anime_game_servers.gi_lua");
|
||||
luaEngine.addGlobals();
|
||||
}
|
||||
|
||||
default boolean loadSceneReplacementScript(ScriptParser parser){
|
||||
return loadData(ScriptSource.SCENE_REPLACEMENT, 0, "groups_replacement.lua", ScriptType.DATA_STORAGE, parser);
|
||||
}
|
||||
|
||||
default boolean loadSharedQuestScript(ScriptParser parser, int questId){
|
||||
return loadData(ScriptSource.SHARED_QUESTS, questId, "Q"+questId+"ShareConfig.lua", ScriptType.DATA_STORAGE, parser);
|
||||
}
|
||||
|
||||
default boolean loadSceneMetaScript(int sceneId, ScriptParser parser){
|
||||
return loadData(ScriptSource.SCENE, sceneId, "scene"+sceneId+".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)
|
||||
return loadData(scriptSource, targetId, "scene"+targetId+"_group"+groupId+".lua", ScriptType.EXECUTABLE, parser);
|
||||
else
|
||||
return loadData(scriptSource, targetId, "activity"+targetId+"_group"+groupId+".lua", ScriptType.EXECUTABLE, parser);
|
||||
}
|
||||
default boolean loadSceneDummyPoints(int sceneId, ScriptParser parser){
|
||||
return loadData(ScriptSource.SCENE, sceneId, "scene"+sceneId+"_dummy_points.lua", ScriptType.DATA_STORAGE, parser);
|
||||
}
|
||||
|
||||
default boolean loadActivityMetaScript(int activityId, ScriptParser parser){
|
||||
return loadData(ScriptSource.ACTIVITY, activityId, "activity"+activityId+".lua", ScriptType.DATA_STORAGE, parser);
|
||||
}
|
||||
default boolean loadActivityBlockScript(int activityId, int blockId, ScriptParser parser){
|
||||
return loadData(ScriptSource.ACTIVITY, activityId, "activity"+activityId+"_block"+blockId+".lua", ScriptType.DATA_STORAGE, parser);
|
||||
}
|
||||
|
||||
|
||||
interface ScriptParser {
|
||||
void parse(LuaScript script) throws ScriptException;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package org.anime_game_servers.gi_lua.models.loader
|
||||
|
||||
import io.github.oshai.kotlinlogging.KLogger
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging.logger
|
||||
import org.anime_game_servers.lua.engine.BaseScriptLoader
|
||||
import org.anime_game_servers.lua.engine.LuaEngine
|
||||
|
||||
@JvmDefaultWithCompatibility
|
||||
interface GIScriptLoader : BaseScriptLoader {
|
||||
|
||||
fun addDefaultsForEngine(luaEngine: LuaEngine) {
|
||||
LuaEngine.registerNamespace("org.anime_game_servers.core.gi")
|
||||
LuaEngine.registerNamespace("org.anime_game_servers.gi_lua")
|
||||
luaEngine.addGlobals()
|
||||
}
|
||||
|
||||
override fun getRequireScriptParams(scriptName: String): BaseScriptLoader.ScriptLoadParams {
|
||||
val path = scriptName.substringBeforeLast('/', "").let {
|
||||
if (it.isEmpty()) "" else "$it/"
|
||||
}
|
||||
val file = scriptName.substringAfterLast('/').let {
|
||||
if(!it.endsWith(".lua")) "${it}.lua" else it
|
||||
}
|
||||
return CommonScriptLoadParams(path, file)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val logger: KLogger = logger(GIScriptLoader::class.java.name)
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import io.github.oshai.kotlinlogging.KotlinLogging;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.gi_lua.models.loader.ActivityMetaScriptLoadParams;
|
||||
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;
|
||||
@ -48,7 +49,8 @@ public class ActivityMeta {
|
||||
}
|
||||
|
||||
private boolean loadActivityMeta(GIScriptLoader scriptLoader){
|
||||
return scriptLoader.loadActivityMetaScript(activityId, (cs -> {
|
||||
val metaParams = new ActivityMetaScriptLoadParams(activityId);
|
||||
return scriptLoader.loadData(metaParams, (cs -> {
|
||||
// Create blocks
|
||||
this.blockIds = cs.getGlobalVariableList("blocks", Integer.class);
|
||||
}));
|
||||
|
@ -5,6 +5,8 @@ import io.github.oshai.kotlinlogging.KotlinLogging;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.gi_lua.models.loader.SceneDummyPointScriptLoadParams;
|
||||
import org.anime_game_servers.gi_lua.models.loader.SceneMetaScriptLoadParams;
|
||||
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;
|
||||
@ -54,7 +56,8 @@ public class SceneMeta {
|
||||
}
|
||||
|
||||
private boolean loadSceneMeta(GIScriptLoader scriptLoader){
|
||||
return scriptLoader.loadSceneMetaScript(sceneId, (cs -> {
|
||||
val sceneData = new SceneMetaScriptLoadParams(sceneId);
|
||||
return scriptLoader.loadData(sceneData, (cs -> {
|
||||
this.config = cs.getGlobalVariable("scene_config", SceneConfig.class);
|
||||
|
||||
// TODO optimize later
|
||||
@ -69,7 +72,8 @@ public class SceneMeta {
|
||||
}
|
||||
|
||||
private void loadDummyPoints(GIScriptLoader scriptLoader){
|
||||
scriptLoader.loadSceneDummyPoints(sceneId, (cs -> {
|
||||
val scriptParams = new SceneDummyPointScriptLoadParams(sceneId);
|
||||
scriptLoader.loadData(scriptParams, (cs -> {
|
||||
this.dummyPoints = cs.getGlobalVariableMap("dummy_points", DummyPoint.class);
|
||||
}));
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ 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.SceneBlockScriptLoadParams;
|
||||
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;
|
||||
@ -58,7 +59,8 @@ public class SceneBlock {
|
||||
|
||||
val scriptType = activityId == 0 ? ScriptSource.SCENE : ScriptSource.ACTIVITY;
|
||||
val typeId = activityId == 0 ? sceneId : activityId;
|
||||
if( !scriptLoader.loadSceneBlockScript(scriptType, typeId, id, (cs -> {
|
||||
val sceneBlockParams = new SceneBlockScriptLoadParams(scriptType, typeId, id);
|
||||
if( !scriptLoader.loadData(sceneBlockParams, (cs -> {
|
||||
// Set groups
|
||||
this.groupInfo = cs.getGlobalVariableList("groups", SceneGroupInfo.class).stream()
|
||||
.collect(Collectors.toMap(x -> x.getId(), y -> y, (a, b) -> a));
|
||||
|
@ -5,6 +5,7 @@ import io.github.oshai.kotlinlogging.KotlinLogging;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import lombok.val;
|
||||
import org.anime_game_servers.gi_lua.models.loader.SceneGroupScriptLoadParams;
|
||||
import org.anime_game_servers.gi_lua.models.scene.SceneMeta;
|
||||
import org.anime_game_servers.gi_lua.models.loader.ScriptSource;
|
||||
import org.anime_game_servers.gi_lua.models.scene.block.SceneGroupInfo;
|
||||
@ -95,7 +96,8 @@ public class SceneGroup {
|
||||
|
||||
val scriptType = activityId == 0 ? ScriptSource.SCENE : ScriptSource.ACTIVITY;
|
||||
val typeId = activityId == 0 ? sceneId : activityId;
|
||||
if (!scriptLoader.loadSceneGroupScript(scriptType, typeId, groupId, cs -> {
|
||||
val groupParams = new SceneGroupScriptLoadParams(scriptType, typeId, groupId);
|
||||
if (!scriptLoader.loadData(groupParams, cs -> {
|
||||
this.script = cs;
|
||||
// Set
|
||||
this.monsters = cs.getGlobalVariableList("monsters", SceneMonster.class).stream()
|
||||
|
@ -32,18 +32,17 @@ public class JNLuaRequireCommonFunction implements NamedJavaFunction {
|
||||
public int invoke(LuaState luaState) {
|
||||
val requiredName = luaState.checkString(1);
|
||||
luaState.remove(1);
|
||||
val path = "Common/" + requiredName + ".lua";
|
||||
val includePath = scriptConfig.getScriptLoader().getScriptPath(path);
|
||||
if (!Files.exists(includePath)) {
|
||||
logger.error(() -> "Require script not found. " + path);
|
||||
val params = scriptConfig.getScriptLoader().getRequireScriptParams(requiredName);
|
||||
val includeScript = scriptConfig.getScriptLoader().openScript(params);
|
||||
if (includeScript == null) {
|
||||
logger.error(() -> "Require script not found. " + params.getBasePath());
|
||||
return 1;
|
||||
}
|
||||
try {
|
||||
val includeScript = Files.newInputStream(includePath);
|
||||
luaState.load(includeScript, requiredName, "t");
|
||||
luaState.call(0, 0);
|
||||
} catch (IOException e) {
|
||||
logger.error(e, ()-> "Error on loading require script. " + path);
|
||||
logger.error(e, ()-> "Error on loading require script. " + params.getBasePath());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
|
@ -34,8 +34,8 @@ class LuaJEngine(override val scriptConfig: ScriptConfig) : LuaEngine {
|
||||
// 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!!)
|
||||
val params = scriptConfig.scriptLoader.getRequireScriptParams(filename)
|
||||
val stream = scriptConfig.scriptLoader.openScript(params)
|
||||
return stream ?: ByteArrayInputStream(ByteArray(0))
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,13 @@ kotlin {
|
||||
testRuns["test"].executionTask.configure {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
compilations.all {
|
||||
compileTaskProvider.configure {
|
||||
compilerOptions {
|
||||
freeCompilerArgs.add("-Xjvm-default=all")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
js(IR) {
|
||||
browser {
|
||||
@ -22,6 +29,7 @@ kotlin {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hostOs = System.getProperty("os.name")
|
||||
val isMingwX64 = hostOs.startsWith("Windows")
|
||||
val nativeTarget = when {
|
||||
|
@ -1,9 +1,58 @@
|
||||
package org.anime_game_servers.lua.engine
|
||||
|
||||
import io.github.oshai.kotlinlogging.KLogger
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.anime_game_servers.lua.models.ScriptType
|
||||
import java.io.InputStream
|
||||
import java.nio.file.Path
|
||||
import javax.script.ScriptException
|
||||
|
||||
@JvmDefaultWithCompatibility
|
||||
interface BaseScriptLoader {
|
||||
fun openScript(scriptPath: Path): InputStream?
|
||||
fun getScriptPath(scriptName: String): Path?
|
||||
fun getRequireScriptParams(scriptName: String): ScriptLoadParams
|
||||
fun openScript(params: ScriptLoadParams): InputStream?
|
||||
fun getScript(
|
||||
scriptLoadParams: ScriptLoadParams
|
||||
): LuaScript?
|
||||
|
||||
fun loadData(
|
||||
scriptLoadParams: ScriptLoadParams,
|
||||
parser: ScriptParser
|
||||
): Boolean {
|
||||
val cs = getScript(scriptLoadParams)
|
||||
|
||||
if (cs == null) {
|
||||
logger.warn { "No script found for " + scriptLoadParams.getBaseDirectory() }
|
||||
return false
|
||||
}
|
||||
|
||||
// Eval script
|
||||
try {
|
||||
cs.evaluate()
|
||||
|
||||
parser.parse(cs)
|
||||
} catch (exception: ScriptException) {
|
||||
logger.error(exception) { "An error occurred while running the script ${scriptLoadParams.getScriptName()}" }
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
interface ScriptLoadParams {
|
||||
fun getBaseDirectory(): String
|
||||
fun getScriptName(): String
|
||||
fun getBasePath(): String = getBaseDirectory() + getScriptName()
|
||||
fun getScriptType(): ScriptType = ScriptType.DATA_STORAGE
|
||||
}
|
||||
|
||||
interface ScriptParser {
|
||||
@Throws(ScriptException::class)
|
||||
fun parse(script: LuaScript)
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
val logger: KLogger = KotlinLogging.logger(BaseScriptLoader::class.java.name)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user