/*
* 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();
*/
}
};
}