private bool EnsureScriptEnvironment() { if (m_scriptEnvironment == null) { m_scriptEnvironment = new ScriptEnvironment(this); if (!m_scriptEnvironment.Create()) { this.Log().Error("Resource {0} caused an error during loading. Please see the above lines for details.", Name); State = ResourceState.Stopped; return false; } } return true; }
public void TriggerEvent(string eventName, string argsSerialized, int source) { List <Delegate> eventHandlers; if (!m_eventHandlers.TryGetValue(eventName, out eventHandlers)) { return; } m_luaEnvironment["source"] = source; var lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; var oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; //var unpacker = (Func<object, LuaResult>)((LuaTable)m_luaEnvironment["msgpack"])["unpack"]; //var table = unpacker(argsSerialized); dynamic luaEnvironment = m_luaEnvironment; LuaTable table = luaEnvironment.msgpack.unpack(argsSerialized); var args = new object[0]; if (table != null) { args = new object[table.Length]; var i = 0; foreach (var value in table) { args[i] = value.Value; i++; } } foreach (var handler in eventHandlers) { try { var methodParameters = handler.Method.GetParameters(); var localArgs = args; int ignoreAppend = 0; if (methodParameters.Length >= 1 && (methodParameters.Last().ParameterType == typeof(LuaTable) || methodParameters.First().ParameterType == typeof(Closure))) { ignoreAppend = 1; } localArgs = localArgs.Take(methodParameters.Length - ignoreAppend).ToArray(); handler.DynamicInvoke(localArgs); } catch (Exception e) { Game.RconPrint.Print("Error in resource {0}: {1}\n", m_resource.Name, e.Message); this.Log().Error(() => "Error executing event handler for event " + eventName + " in resource " + m_resource.Name + ": " + e.Message, e); PrintLuaStackTrace(e); while (e != null) { if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); PrintLuaStackTrace(e.InnerException); } e = e.InnerException; } //eventHandlers.Clear(); ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; return; } } ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; }
public bool Create() { ScriptEnvironment lastEnvironment = null, oldLastEnvironment = null; try { if (ms_luaState == null) { ms_luaState = new Lua(); //ms_luaDebug = new LuaStackTraceDebugger(); ms_luaDebug = null; if (Resource.Manager.Configuration.ScriptDebug) { ms_luaDebug = new LuaStackTraceDebugger(); } ms_luaCompileOptions = new LuaCompileOptions(); ms_luaCompileOptions.DebugEngine = ms_luaDebug; ms_initChunks = new [] { ms_luaState.CompileChunk("system/MessagePack.lua", ms_luaCompileOptions), ms_luaState.CompileChunk("system/dkjson.lua", ms_luaCompileOptions), ms_luaState.CompileChunk("system/resource_init.lua", ms_luaCompileOptions) }; } m_luaEnvironment = ms_luaState.CreateEnvironment <LuaGlobal>(); foreach (var func in ms_luaFunctions) { //m_luaEnvironment[func.Key] = Delegate.CreateDelegate var parameters = func.Value.GetParameters() .Select(p => p.ParameterType) .Concat(new Type[] { func.Value.ReturnType }) .ToArray(); var delegType = Expression.GetDelegateType ( parameters ); var deleg = Delegate.CreateDelegate ( delegType, null, func.Value ); var expParameters = parameters.Take(parameters.Count() - 1).Select(a => Expression.Parameter(a)).ToArray(); var pushedEnvironment = Expression.Variable(typeof(PushedEnvironment)); Expression <Func <PushedEnvironment> > preFunc = () => PushEnvironment(this); Expression <Action <PushedEnvironment> > postFunc = env => env.PopEnvironment(); Expression body; if (func.Value.ReturnType.Name != "Void") { var retval = Expression.Variable(func.Value.ReturnType); body = Expression.Block ( func.Value.ReturnType, new[] { retval, pushedEnvironment }, Expression.Assign ( pushedEnvironment, Expression.Invoke(preFunc) ), Expression.Assign ( retval, Expression.Call(func.Value, expParameters) ), Expression.Invoke(postFunc, pushedEnvironment), retval ); } else { body = Expression.Block ( func.Value.ReturnType, new[] { pushedEnvironment }, Expression.Assign ( pushedEnvironment, Expression.Invoke(preFunc) ), Expression.Call(func.Value, expParameters), Expression.Invoke(postFunc, pushedEnvironment) ); } var lambda = Expression.Lambda(delegType, body, expParameters); m_luaEnvironment[func.Key] = lambda.Compile(); } InitHandler = null; /*m_luaNative = LuaL.LuaLNewState(); * LuaL.LuaLOpenLibs(m_luaNative); * * LuaLib.LuaNewTable(m_luaNative); * LuaLib.LuaSetGlobal(m_luaNative, "luanet"); * * InitHandler = null; * * m_luaState = new NLua.Lua(m_luaNative);*/ lock (m_luaEnvironment) { lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; // load global data files foreach (var chunk in ms_initChunks) { m_luaEnvironment.DoChunk(chunk); } } return(true); } catch (Exception e) { this.Log().Error(() => "Error creating script environment for resource " + m_resource.Name + ": " + e.Message, e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); } PrintLuaStackTrace(e); } finally { ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; } return(false); }
internal static PushedEnvironment PushEnvironment(ScriptEnvironment env) { var penv = new PushedEnvironment(); penv.LastEnvironment = ms_currentEnvironment; ms_currentEnvironment = env; penv.OldLastEnvironment = LastEnvironment; LastEnvironment = penv.LastEnvironment; return penv; }
public bool Stop() { if (State != ResourceState.Running && State != ResourceState.Starting) { throw new InvalidOperationException(string.Format("Tried to stop a resource ({0}) that wasn't running.", Name)); } this.Log().Info("Stopping resource {0} (last state: {1}).", Name, State); if (State == ResourceState.Running) { if (!Manager.TriggerEvent("onResourceStop", -1, Name)) { return false; } } var dependants = Dependants.GetRange(0, Dependants.Count); foreach (var dependant in dependants) { var dependantResource = Manager.GetResource(dependant); dependantResource.Stop(); } Dependants.Clear(); foreach (var dependency in Dependencies) { var dependencyResource = Manager.GetResource(dependency); dependencyResource.RemoveDependant(Name); } // remove the watcher m_watcher.Dispose(); m_watcher = null; // dispose of the script environment m_scriptEnvironment.Dispose(); m_scriptEnvironment = null; if (State == ResourceState.Running) { // broadcast a stop message to all clients var clients = ClientInstances.Clients.Where(c => c.Value.NetChannel != null).Select(c => c.Value); foreach (var client in clients) { client.SendReliableCommand(0x45E855D7, Encoding.UTF8.GetBytes(Name)); // msgResStop } } // done! State = ResourceState.Stopped; return true; }
public void Tick() { var timers = m_timers.GetRange(0, m_timers.Count); var now = Time.CurrentTime; foreach (var timer in timers) { if (now >= timer.TickFrom) { lock (m_luaEnvironment) { var lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; var oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; try { timer.Function.DynamicInvoke(); } catch (Exception e) { this.Log().Error(() => "Error invoking timer in resource " + m_resource.Name + ": " + e.Message, e); PrintLuaStackTrace(e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); PrintLuaStackTrace(e.InnerException); } } ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; m_timers.Remove(timer); } } } }
public void TriggerEvent(string eventName, string argsSerialized, int source) { List<Delegate> eventHandlers; if (!m_eventHandlers.TryGetValue(eventName, out eventHandlers)) { return; } m_luaEnvironment["source"] = source; var lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; var oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; //var unpacker = (Func<object, LuaResult>)((LuaTable)m_luaEnvironment["msgpack"])["unpack"]; //var table = unpacker(argsSerialized); dynamic luaEnvironment = m_luaEnvironment; LuaTable table = luaEnvironment.msgpack.unpack(argsSerialized); var args = new object[0]; if (table != null) { args = new object[table.Length]; var i = 0; foreach (var value in table) { args[i] = value.Value; i++; } } foreach (var handler in eventHandlers) { try { var methodParameters = handler.Method.GetParameters(); var localArgs = args; int ignoreAppend = 0; if (methodParameters.Length >= 1 && (methodParameters.Last().ParameterType == typeof(LuaTable) || methodParameters.First().ParameterType == typeof(Closure))) { ignoreAppend = 1; } localArgs = localArgs.Take(methodParameters.Length - ignoreAppend).ToArray(); handler.DynamicInvoke(localArgs); } catch (Exception e) { Game.RconPrint.Print("Error in resource {0}: {1}\n", m_resource.Name, e.Message); this.Log().Error(() => "Error executing event handler for event " + eventName + " in resource " + m_resource.Name + ": " + e.Message, e); PrintLuaStackTrace(e); while (e != null) { if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); PrintLuaStackTrace(e.InnerException); } e = e.InnerException; } eventHandlers.Clear(); ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; return; } } ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; }
public bool LoadScripts() { ScriptEnvironment lastEnvironment = null, oldLastEnvironment = null; try { lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; // load scripts defined in this resource foreach (var script in m_resource.ServerScripts) { lock (m_luaEnvironment) { var chunk = ms_luaState.CompileChunk(Path.Combine(m_resource.Path, script), ms_luaCompileOptions); m_luaEnvironment.DoChunk(chunk); m_curChunks.Add(chunk); } } return true; } catch (Exception e) { this.Log().Error(() => "Error creating script environment for resource " + m_resource.Name + ": " + e.Message, e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); } PrintLuaStackTrace(e); } finally { ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; } return false; }
public bool DoInitFile(bool preParse) { ScriptEnvironment lastEnvironment = null, oldLastEnvironment = null; try { lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; lock (m_luaEnvironment) { var initFunction = ms_luaState.CompileChunk(Path.Combine(m_resource.Path, "__resource.lua"), ms_luaCompileOptions); var initDelegate = new Func<LuaResult>(() => m_luaEnvironment.DoChunk(initFunction)); InitHandler.DynamicInvoke(initDelegate, preParse); } if (!preParse) { foreach (var script in m_serverScripts) { var chunk = ms_luaState.CompileChunk(Path.Combine(m_resource.Path, script), ms_luaCompileOptions); m_luaEnvironment.DoChunk(chunk); m_curChunks.Add(chunk); } } return true; } catch (Exception e) { this.Log().Error(() => "Error creating script environment for resource " + m_resource.Name + ": " + e.Message, e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); } PrintLuaStackTrace(e); } finally { ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; } return false; }
public bool Create() { ScriptEnvironment lastEnvironment = null, oldLastEnvironment = null; try { if (ms_luaState == null) { ms_luaState = new Lua(); //ms_luaDebug = new LuaStackTraceDebugger(); ms_luaDebug = null; if (Resource.Manager.Configuration.ScriptDebug) { ms_luaDebug = new LuaStackTraceDebugger(); } ms_luaCompileOptions = new LuaCompileOptions(); ms_luaCompileOptions.DebugEngine = ms_luaDebug; ms_initChunks = new [] { ms_luaState.CompileChunk("system/MessagePack.lua", ms_luaCompileOptions), ms_luaState.CompileChunk("system/dkjson.lua", ms_luaCompileOptions), ms_luaState.CompileChunk("system/resource_init.lua", ms_luaCompileOptions) }; } m_luaEnvironment = ms_luaState.CreateEnvironment(); foreach (var func in ms_luaFunctions) { //m_luaEnvironment[func.Key] = Delegate.CreateDelegate var parameters = func.Value.GetParameters() .Select(p => p.ParameterType) .Concat(new Type[] { func.Value.ReturnType }) .ToArray(); var delegType = Expression.GetDelegateType ( parameters ); var deleg = Delegate.CreateDelegate ( delegType, null, func.Value ); var expParameters = parameters.Take(parameters.Count() - 1).Select(a => Expression.Parameter(a)).ToArray(); var pushedEnvironment = Expression.Variable(typeof(PushedEnvironment)); Expression<Func<PushedEnvironment>> preFunc = () => PushEnvironment(this); Expression<Action<PushedEnvironment>> postFunc = env => env.PopEnvironment(); Expression body; if (func.Value.ReturnType.Name != "Void") { var retval = Expression.Variable(func.Value.ReturnType); body = Expression.Block ( func.Value.ReturnType, new[] { retval, pushedEnvironment }, Expression.Assign ( pushedEnvironment, Expression.Invoke(preFunc) ), Expression.Assign ( retval, Expression.Call(func.Value, expParameters) ), Expression.Invoke(postFunc, pushedEnvironment), retval ); } else { body = Expression.Block ( func.Value.ReturnType, new[] { pushedEnvironment }, Expression.Assign ( pushedEnvironment, Expression.Invoke(preFunc) ), Expression.Call(func.Value, expParameters), Expression.Invoke(postFunc, pushedEnvironment) ); } var lambda = Expression.Lambda(delegType, body, expParameters); m_luaEnvironment[func.Key] = lambda.Compile(); } InitHandler = null; /*m_luaNative = LuaL.LuaLNewState(); LuaL.LuaLOpenLibs(m_luaNative); LuaLib.LuaNewTable(m_luaNative); LuaLib.LuaSetGlobal(m_luaNative, "luanet"); InitHandler = null; m_luaState = new NLua.Lua(m_luaNative);*/ lock (m_luaEnvironment) { lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; // load global data files foreach (var chunk in ms_initChunks) { m_luaEnvironment.DoChunk(chunk); } } return true; } catch (Exception e) { this.Log().Error(() => "Error creating script environment for resource " + m_resource.Name + ": " + e.Message, e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); } PrintLuaStackTrace(e); } finally { ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; } return false; }
public string CallExport(Delegate func, string argsSerialized) { lock (m_luaEnvironment) { var lastEnvironment = ms_currentEnvironment; ms_currentEnvironment = this; var oldLastEnvironment = LastEnvironment; LastEnvironment = lastEnvironment; string retstr = ""; try { // unpack var unpacker = (Func<string, LuaTable>)((LuaTable)m_luaEnvironment["msgpack"])["unpack"]; var table = unpacker(argsSerialized); var args = new object[table.Length]; var i = 0; foreach (var value in table) { args[i] = value.Value; i++; } // invoke var objects = (LuaResult)func.DynamicInvoke(args.Take(func.Method.GetParameters().Length - 1).ToArray()); // pack return values retstr = EventScriptFunctions.SerializeArguments(objects); } catch (Exception e) { this.Log().Error(() => "Error invoking reference for resource " + m_resource.Name + ": " + e.Message, e); if (e.InnerException != null) { this.Log().Error(() => "Inner exception: " + e.InnerException.Message, e.InnerException); } PrintLuaStackTrace(e); } ms_currentEnvironment = lastEnvironment; LastEnvironment = oldLastEnvironment; return retstr; } }
static async Task PerformHttpRequest(string url, Func <object, object, object, LuaResult> cb, string method = "GET", string data = "", LuaTable headers = null) { var webRequest = HttpWebRequest.CreateHttp(url); webRequest.Method = method; var senv = ScriptEnvironment.CurrentEnvironment; if (headers != null) { foreach (var header in headers) { var key = header.Key.ToString(); var value = header.Value.ToString(); if (key.Equals("content-type", StringComparison.InvariantCultureIgnoreCase)) { webRequest.ContentType = value; } else { webRequest.Headers.Add(key, value); } } } try { if (data != string.Empty) { var reqStream = await webRequest.GetRequestStreamAsync(); var dataBytes = Encoding.UTF8.GetBytes(data); await reqStream.WriteAsync(dataBytes, 0, dataBytes.Length); } var response = await webRequest.GetResponseAsync() as HttpWebResponse; // store headers var respHeaders = new LuaTable(); for (int i = 0; i < response.Headers.Count; i++) { respHeaders[response.Headers.Keys[i]] = response.Headers[i]; } // get the response var respStream = response.GetResponseStream(); var streamReader = new StreamReader(respStream); var responseText = await streamReader.ReadToEndAsync(); try { var penv = ScriptEnvironment.PushEnvironment(senv); cb(0, responseText, respHeaders); penv.PopEnvironment(); } catch (Exception e) { webRequest.Log().Error("Error in callback for web request: {0}", e.Message); ScriptEnvironment.PrintLuaStackTrace(e); } } catch (WebException e) { webRequest.Log().Warn("Web request to {0} failed: {1}", url, e.Message); try { var penv = ScriptEnvironment.PushEnvironment(senv); cb((int)((HttpWebResponse)e.Response).StatusCode, null, null); penv.PopEnvironment(); } catch (Exception e2) { webRequest.Log().Error("Error in callback for web request: {0}", e2.Message); ScriptEnvironment.PrintLuaStackTrace(e2); } } }