/* * Created by Andrey Cherkashin (acherkashin) * http://acherkashin.me * * License * Copyright (c) 2015 Andrey Cherkashin * The project released under the MIT license: http://opensource.org/licenses/MIT */ package ragefist.core.environment.bindings; import com.juniform.JUniformMutableObject; import com.juniform.JUniformObject; import java.util.logging.Logger; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.TwoArgFunction; import org.luaj.vm2.lib.VarArgFunction; import org.luaj.vm2.lib.ZeroArgFunction; import ragefist.core.distribution.DistributedServerConnector.DistributedServerConnectorTask; import ragefist.core.environment.EnvironmentCallResultTask; import ragefist.core.environment.EnvironmentCallTask; import ragefist.core.environment.EnvironmentFunctionCallTask; import ragefist.core.environment.EnvironmentProcessor; import ragefist.core.environment.EnvironmentProcessor.EnvironmentBindingAPI; import ragefist.core.environment.EnvironmentRequestTask; import ragefist.core.util.FormatTools; /** * * @author acherkashin */ public class LuaEnvironment extends TwoArgFunction { private final EnvironmentBindingAPI _environment; // ---------------------------------------------------------------------- // // PUBLIC // ---------------------------------------------------------------------- // public LuaEnvironment(EnvironmentBindingAPI environment) { _environment = environment; } // ---------------------------------------------------------------------- // // BINDINGS // ---------------------------------------------------------------------- // @Override public LuaValue call(LuaValue modname, LuaValue env) { LuaTable table = LuaValue.tableOf(); // Getters table.set("getTime", lua_getTime); table.set("getId", lua_getId); // Process table.set("processTasks", lua_processTasks); table.set("reload", lua_reload); table.set("error", lua_error); // Events table.set("onRequest", lua_onRequest); table.set("onRequestFinish", lua_onRequestFinish); // Remote calls table.set("executeRemoteCode", lua_executeRemoteCode); table.set("executeRemoteFunction", lua_executeRemoteFunction); // Network table.set("notifyClient", lua_notifyClient); env.set("Environment", table); env.set("Extensions", LuaValue.tableOf()); return table; } ZeroArgFunction lua_getTime = new ZeroArgFunction() { @Override public LuaValue call() { long unixtime = System.currentTimeMillis() / 1000L; return LuaValue.valueOf(unixtime); } }; ZeroArgFunction lua_getId = new ZeroArgFunction() { @Override public LuaValue call() { return LuaValue.valueOf(_environment.getEnvironmentId()); } }; ZeroArgFunction lua_processTasks = new ZeroArgFunction() { @Override public LuaValue call() { _environment.processTasks(); return NIL; } }; OneArgFunction lua_error = new OneArgFunction() { @Override public LuaValue call(LuaValue lv) { Logger.getGlobal().severe("LUA ERROR: " + lv.tojstring()); return NIL; } }; ZeroArgFunction lua_reload = new ZeroArgFunction() { @Override public LuaValue call() { _environment.reload(); return NIL; } }; TwoArgFunction lua_notifyClient = new TwoArgFunction() { @Override public LuaValue call(LuaValue lv, LuaValue lv1) { int connectionId = lv.toint(); if (connectionId <= 0) { return LuaValue.FALSE; } if (lv1 == null) { return LuaValue.FALSE; } JUniformObject packet = FormatTools.fromLuaToJUniformObject(lv1); _environment.getServerController().sendMessageToClient(connectionId, packet); return LuaValue.TRUE; } }; OneArgFunction lua_onUserLogin = new OneArgFunction() { @Override public LuaValue call(LuaValue lv) { return NIL; } }; OneArgFunction lua_onRequest = new OneArgFunction() { @Override public LuaValue call(LuaValue lv) { return NIL; } }; TwoArgFunction lua_onRequestFinish = new TwoArgFunction() { @Override public LuaValue call(LuaValue lv, LuaValue lv1) { EnvironmentRequestTask task = (EnvironmentRequestTask)lv.touserdata(); task.completeWithData(lv1); //System.out.println("Request Task Finished: "+task.getId()); return NIL; } }; VarArgFunction lua_executeRemoteCode = new VarArgFunction() { @Override public Varargs invoke(Varargs args) { String serverGroup = args.tojstring(1); int serverId = args.toint(2); int envId = args.toint(3); String lua = args.tojstring(4); // pause current thread int pausedTaskId = _environment.getGlobals().get("Processor").get("pauseCurrent").invoke().arg(1).toint(); EnvironmentProcessor initiator = _environment.getServerController().getEnvironmentById(_environment.getEnvironmentId()); EnvironmentCallResultTask resultTask = new EnvironmentCallResultTask(initiator, pausedTaskId); // check if it's local call if (false == _environment.getServerController().isCrossEnvironmentInteractionDisabled() && serverGroup.equals(_environment.getServerController().getCurrentServerGroupCode()) && serverId == _environment.getServerController().getCurrentServerId() ) { // Make a remote call EnvironmentCallTask task = new EnvironmentCallTask(lua); task.setNextTask(resultTask, initiator); _environment.getServerController().getEnvironmentById(envId).addTask(task); } else { JUniformMutableObject object = JUniformMutableObject.newMap(); object.setProperty("action", "ExecuteCode"); JUniformMutableObject dataObject = JUniformMutableObject.newMap(); dataObject.setProperty("code", lua); dataObject.setProperty("environmentId", (Integer)envId); object.setProperty("data", dataObject); // Send a remote call task DistributedServerConnectorTask task = new DistributedServerConnectorTask(serverGroup, serverId, object); task.setNextTask(resultTask, initiator); _environment.getServerController().getConnector().addTask(task); } return _environment.getGlobals().get("Processor").get("yield").call(); } }; VarArgFunction lua_executeRemoteFunction = new VarArgFunction() { @Override public Varargs invoke(Varargs args) { String serverGroup = args.tojstring(1); int serverId = args.toint(2); int envId = args.toint(3); String function = args.tojstring(4); LuaTable functionArgs = null; if (args.istable(5)) { functionArgs = (LuaTable)args.arg(5); } // pause current thread int pausedTaskId = _environment.getGlobals().get("Processor").get("pauseCurrent").invoke().arg(1).toint(); // result task EnvironmentProcessor initiator = _environment.getServerController().getEnvironmentById(_environment.getEnvironmentId()); EnvironmentCallResultTask resultTask = new EnvironmentCallResultTask(initiator, pausedTaskId); // function call task EnvironmentFunctionCallTask task = new EnvironmentFunctionCallTask(function, functionArgs); task.setNextTask(resultTask, initiator); _environment.getServerController().getEnvironmentById(envId).addTask(task); return _environment.getGlobals().get("Processor").get("yield").call(); /* // check if it's local call if (false == _environment.getServerController().isCrossEnvironmentInteractionDisabled() && serverGroup.equals(_environment.getServerController().getCurrentServerGroupCode()) && serverId == _environment.getServerController().getCurrentServerId() ) { // Make a remote call EnvironmentCallTask task = new EnvironmentCallTask(lua); task.setNextTask(resultTask, initiator); _environment.getServerController().getEnvironmentById(envId).addTask(task); } else { JUniformMutableObject object = JUniformMutableObject.newMap(); object.setProperty("action", "ExecuteCode"); JUniformMutableObject dataObject = JUniformMutableObject.newMap(); dataObject.setProperty("code", lua); dataObject.setProperty("environmentId", (Integer)envId); object.setProperty("data", dataObject); // Send a remote call task DistributedServerConnectorTask task = new DistributedServerConnectorTask(serverGroup, serverId, object); task.setNextTask(resultTask, initiator); _environment.getServerController().getConnector().addTask(task); } return _environment.getGlobals().get("Processor").get("yield").call(); */ } }; }