public void CallLuaFunction(Player player, Actor target, string funcName, bool optional, params object[] args) { //Need a seperate case for NPCs cause that child/parent thing. if (target is Npc) { CallLuaFunctionNpc(player, (Npc)target, funcName, optional, args); return; } object[] args2 = new object[args.Length + 2]; Array.Copy(args, 0, args2, 2, args.Length); args2[0] = player; args2[1] = target; string luaPath = GetScriptPath(target); LuaScript script = LoadScript(luaPath); if (script != null) { if (!script.Globals.Get(funcName).IsNil()) { try { Coroutine coroutine = script.CreateCoroutine(script.Globals[funcName]).Coroutine; DynValue value = coroutine.Resume(args2); ResolveResume(player, coroutine, value); } catch (Exception e) { player.SendMessage(0x20, "", e.Message); player.EndEvent(); } } else { if (!optional) { SendError(player, String.Format("Could not find function '{0}' for actor {1}.", funcName, target.GetName())); } } } else { if (!(target is Area) && !optional) { SendError(player, String.Format("Could not find script for actor {0}.", target.GetName())); } } }
public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false) { bool playerNull = player == null; if (playerNull) { if (param.Length >= 2 && param[1].Contains("\"")) { player = Server.GetWorldManager().GetPCInWorld(param[1]); } else if (param.Length > 2) { player = Server.GetWorldManager().GetPCInWorld(param[1] + param[2]); } } // load from scripts/commands/gm/ directory var path = String.Format("./scripts/commands/gm/{0}.lua", cmd.ToLower()); // check if the file exists if (File.Exists(path)) { // load global functions LuaScript script = LoadGlobals(); // see if this script has any syntax errors try { script.DoFile(path); } catch (Exception e) { Program.Log.Error("LuaEngine.RunGMCommand: {0}.", e.Message); return; } // can we run this script if (!script.Globals.Get("onTrigger").IsNil()) { // can i run this command var permissions = 0; // parameter types (string, integer, double, float) var parameters = ""; var description = "!" + cmd + ": "; // get the properties table var res = script.Globals.Get("properties"); // make sure properties table exists if (!res.IsNil()) { try { // returns table if one is found var table = res.Table; // find each key/value pair foreach (var pair in table.Pairs) { if (pair.Key.String == "permissions") { permissions = (int)pair.Value.Number; } else if (pair.Key.String == "parameters") { parameters = pair.Value.String; } else if (pair.Key.String == "description") { description = pair.Value.String; } } } catch (Exception e) { LuaScript.Log.Error("LuaEngine.RunGMCommand: " + e.Message); return; } } // if this isnt a console command, make sure player exists if (player != null) { if (permissions > 0 && !player.isGM) { Program.Log.Info("LuaEngine.RunGMCommand: {0}'s GM level is too low to use command {1}.", player.actorName, cmd); return; } // i hate to do this, but cant think of a better way to keep !help else if (help) { player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, String.Format("[Commands] [{0}]", cmd), description); return; } } else if (help) { LuaScript.Log.Info("[Commands] [{0}]: {1}", cmd, description); return; } // we'll push our lua params here List <object> LuaParam = new List <object>(); var i = playerNull ? 2 : 0; for (; i < parameters.Length; ++i) { try { // convert chat parameters to command parameters switch (parameters[i]) { case 'i': LuaParam.Add(Convert.ChangeType(param[i + 1], typeof(int))); continue; case 'd': LuaParam.Add(Convert.ChangeType(param[i + 1], typeof(double))); continue; case 'f': LuaParam.Add(Convert.ChangeType(param[i + 1], typeof(float))); continue; case 's': LuaParam.Add(param[i + 1]); continue; default: LuaScript.Log.Info("LuaEngine.RunGMCommand: {0} unknown parameter {1}.", path, parameters[i]); LuaParam.Add(param[i + 1]); continue; } } catch (Exception e) { if (e is IndexOutOfRangeException) { break; } LuaParam.Add(param[i + 1]); } } // the script can double check the player exists, we'll push them anyways LuaParam.Insert(0, player); // push the arg count too LuaParam.Insert(1, i - (playerNull ? 2 : 0)); // run the script //script.Call(script.Globals["onTrigger"], LuaParam.ToArray()); // gm commands dont need to be coroutines? try { Coroutine coroutine = script.CreateCoroutine(script.Globals["onTrigger"]).Coroutine; DynValue value = coroutine.Resume(LuaParam.ToArray()); GetInstance().ResolveResume(player, coroutine, value); } catch (Exception e) { Program.Log.Error("LuaEngine.RunGMCommand: {0} - {1}", path, e.Message); } return; } } LuaScript.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path); return; }
private void CallLuaFunctionNpc(Player player, Npc target, string funcName, bool optional, params object[] args) { object[] args2 = new object[args.Length + (player == null ? 1 : 2)]; Array.Copy(args, 0, args2, (player == null ? 1 : 2), args.Length); if (player != null) { args2[0] = player; args2[1] = target; } else { args2[0] = target; } LuaScript parent = null, child = null; if (File.Exists("./scripts/base/" + target.classPath + ".lua")) { parent = LuaEngine.LoadScript("./scripts/base/" + target.classPath + ".lua"); } Area area = target.zone; if (area is PrivateArea) { if (File.Exists(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId()))) { child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/privatearea/{1}_{2}/{3}/{4}.lua", area.zoneName, ((PrivateArea)area).GetPrivateAreaName(), ((PrivateArea)area).GetPrivateAreaType(), target.className, target.GetUniqueId())); } } else { if (File.Exists(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId()))) { child = LuaEngine.LoadScript(String.Format("./scripts/unique/{0}/{1}/{2}.lua", area.zoneName, target.className, target.GetUniqueId())); } } if (parent == null && child == null) { LuaEngine.SendError(player, String.Format("Could not find script for actor {0}.", target.GetName())); return; } //Run Script Coroutine coroutine = null; if (child != null && !child.Globals.Get(funcName).IsNil()) { coroutine = child.CreateCoroutine(child.Globals[funcName]).Coroutine; } else if (parent != null && parent.Globals.Get(funcName) != null && !parent.Globals.Get(funcName).IsNil()) { coroutine = parent.CreateCoroutine(parent.Globals[funcName]).Coroutine; } if (coroutine != null) { try { DynValue value = coroutine.Resume(args2); ResolveResume(player, coroutine, value); } catch (ScriptRuntimeException e) { SendError(player, e.DecoratedMessage); } } }