From 57b9d5ab9967cc4f4aef6a776135c5cf0503f369 Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Thu, 16 Jun 2016 01:50:13 +0100 Subject: [PATCH] start of work moving commands to lua --- FFXIVClassic Map Server/CommandProcessor.cs | 59 ++- FFXIVClassic Map Server/Program.cs | 6 +- FFXIVClassic Map Server/WorldManager.cs | 2 +- FFXIVClassic Map Server/actors/Actor.cs | 60 ++- FFXIVClassic Map Server/actors/area/Area.cs | 2 +- FFXIVClassic Map Server/lua/LuaEngine.cs | 354 ++++++++++++++++-- .../commands/gm/command - Copy (2).lua | 9 + .../commands/gm/command - Copy (3).lua | 9 + .../commands/gm/command - Copy (4).lua | 9 + .../commands/gm/command - Copy (5).lua | 9 + .../commands/gm/command - Copy (6).lua | 9 + .../commands/gm/command - Copy (7).lua | 9 + data/scripts/commands/gm/giveitem.lua | 22 ++ data/scripts/commands/gm/graphic.lua | 19 + data/scripts/commands/gm/music.lua | 10 + data/scripts/commands/gm/mypos.lua | 22 ++ data/scripts/commands/gm/reloadzone.lua | 23 ++ data/scripts/commands/gm/test.lua | 9 + data/scripts/commands/gm/warp.lua | 78 ++++ data/scripts/global.lua | 50 ++- 20 files changed, 703 insertions(+), 67 deletions(-) create mode 100644 data/scripts/commands/gm/command - Copy (2).lua create mode 100644 data/scripts/commands/gm/command - Copy (3).lua create mode 100644 data/scripts/commands/gm/command - Copy (4).lua create mode 100644 data/scripts/commands/gm/command - Copy (5).lua create mode 100644 data/scripts/commands/gm/command - Copy (6).lua create mode 100644 data/scripts/commands/gm/command - Copy (7).lua create mode 100644 data/scripts/commands/gm/giveitem.lua create mode 100644 data/scripts/commands/gm/graphic.lua create mode 100644 data/scripts/commands/gm/music.lua create mode 100644 data/scripts/commands/gm/mypos.lua create mode 100644 data/scripts/commands/gm/reloadzone.lua create mode 100644 data/scripts/commands/gm/test.lua create mode 100644 data/scripts/commands/gm/warp.lua diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/FFXIVClassic Map Server/CommandProcessor.cs index 23ea3d7c..849b682f 100644 --- a/FFXIVClassic Map Server/CommandProcessor.cs +++ b/FFXIVClassic Map Server/CommandProcessor.cs @@ -455,7 +455,7 @@ namespace FFXIVClassic_Map_Server return; // catch any invalid warps here } - private void doWeather(ConnectedPlayer client, string weatherID, string value) + private void DoWeather(ConnectedPlayer client, string weatherID, string value) { ushort weather = Convert.ToUInt16(weatherID); @@ -499,18 +499,55 @@ namespace FFXIVClassic_Map_Server internal bool DoCommand(string input, ConnectedPlayer client) { + if (!input.Any()) + return false; + input.Trim(); - if (input.StartsWith("!")) - input = input.Substring(1); + input = input.StartsWith("!") ? input.Substring(1) : input; + + var split = input.Split('"') + .Select((str, index) => index % 2 == 0 + ? str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) + : new String[] { str } + ) + .SelectMany(str => str).ToArray(); - String[] split = input.Split(' '); split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands - split = split.Where(temp => temp != "").ToArray(); // strips extra whitespace from commands - - // Debug - //SendMessage(client, string.Join(",", split)); - if (split.Length >= 1) + var cmd = split?.ElementAt(0); + + if (cmd.Any()) + { + // if client isnt null, take player to be the player actor + var player = client?.GetActor(); + + if (cmd.Equals("help")) + { + // if there's another string after this, take it as the command we want the description for + if (split.Length > 1) + { + LuaEngine.RunGMCommand(player, split[1], null, true); + return true; + } + + // print out all commands + foreach (var str in Directory.GetFiles("./scripts/commands/gm/")) + { + var c = str.Replace(".lua", ""); + c = c.Replace("./scripts/commands/gm/", ""); + + LuaEngine.RunGMCommand(player, c, null, true); + } + return true; + } + + LuaEngine.RunGMCommand(player, cmd.ToString(), split.ToArray()); + return true; + } + // Debug + //SendMessage(client, string.Join(",", split)); + + if (split.Length >= 1) { #region !help if (split[0].Equals("help")) @@ -582,7 +619,7 @@ namespace FFXIVClassic_Map_Server { try { - doWeather(client, split[2], split[3]); + DoWeather(client, split[2], split[3]); return true; } catch (Exception e) @@ -622,7 +659,7 @@ namespace FFXIVClassic_Map_Server client.GetActor().SendInstanceUpdate(); client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Reseting zone {0}...", client.GetActor().zoneId)), true, false)); } - Server.GetWorldManager().reloadZone(client.GetActor().zoneId); + Server.GetWorldManager().ReloadZone(client.GetActor().zoneId); return true; } #endregion diff --git a/FFXIVClassic Map Server/Program.cs b/FFXIVClassic Map Server/Program.cs index eaaa6981..e08d871a 100644 --- a/FFXIVClassic Map Server/Program.cs +++ b/FFXIVClassic Map Server/Program.cs @@ -18,9 +18,9 @@ namespace FFXIVClassic_Map_Server public static Logger Log; static void Main(string[] args) - { - - // set up logging + { + + // set up logging Log = LogManager.GetCurrentClassLogger(); #if DEBUG TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out); diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 9f551555..f0c87fde 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -464,7 +464,7 @@ namespace FFXIVClassic_Map_Server LuaEngine.OnZoneIn(player); } - public void reloadZone(uint zoneId) + public void ReloadZone(uint zoneId) { if (!zoneList.ContainsKey(zoneId)) return; diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 5db8a9dd..30397547 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -11,7 +11,7 @@ using FFXIVClassic_Map_Server.actors.area; namespace FFXIVClassic_Map_Server.Actors { class Actor - { + { public uint actorId; public string actorName; @@ -58,12 +58,12 @@ namespace FFXIVClassic_Map_Server.Actors public SubPacket CreateAddActorPacket(uint playerActorId, byte val) { return AddActorPacket.BuildPacket(actorId, playerActorId, val); - } + } public SubPacket CreateNamePacket(uint playerActorId) { return SetActorNamePacket.BuildPacket(actorId, playerActorId, displayNameId, displayNameId == 0xFFFFFFFF | displayNameId == 0x0 ? customDisplayName : ""); - } + } public SubPacket CreateSpeedPacket(uint playerActorId) { @@ -95,10 +95,10 @@ namespace FFXIVClassic_Map_Server.Actors { SubPacket spawnPacket; - spawnPacket = SetActorPositionPacket.BuildPacket(actorId, playerActorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, false); - + spawnPacket = SetActorPositionPacket.BuildPacket(actorId, playerActorId, 0xFFFFFFFF, positionX, positionY, positionZ, rotation, spawnType, false); + //return SetActorPositionPacket.BuildPacket(actorId, playerActorId, -211.895477f, 190.000000f, 29.651011f, 2.674819f, SetActorPositionPacket.SPAWNTYPE_PLAYERWAKE); - + spawnPacket.DebugPrintSubPacket(); return spawnPacket; @@ -124,8 +124,8 @@ namespace FFXIVClassic_Map_Server.Actors if (eventConditions.talkEventConditions != null) { - foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) - subpackets.Add(SetTalkEventCondition.BuildPacket(playerActorId, actorId, condition)); + foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) + subpackets.Add(SetTalkEventCondition.BuildPacket(playerActorId, actorId, condition)); } if (eventConditions.noticeEventConditions != null) @@ -171,8 +171,8 @@ namespace FFXIVClassic_Map_Server.Actors if (eventConditions.talkEventConditions != null) { - foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) - subpackets.Add(SetEventStatus.BuildPacket(playerActorId, actorId, true, 1, condition.conditionName)); + foreach (EventList.TalkEventCondition condition in eventConditions.talkEventConditions) + subpackets.Add(SetEventStatus.BuildPacket(playerActorId, actorId, true, 1, condition.conditionName)); } if (eventConditions.noticeEventConditions != null) @@ -219,7 +219,7 @@ namespace FFXIVClassic_Map_Server.Actors } public virtual BasePacket GetSpawnPackets(uint playerActorId) - { + { return GetSpawnPackets(playerActorId, 0x1); } @@ -229,13 +229,13 @@ namespace FFXIVClassic_Map_Server.Actors subpackets.Add(CreateAddActorPacket(playerActorId, 8)); subpackets.AddRange(GetEventConditionPackets(playerActorId)); subpackets.Add(CreateSpeedPacket(playerActorId)); - subpackets.Add(CreateSpawnPositonPacket(playerActorId, spawnType)); + subpackets.Add(CreateSpawnPositonPacket(playerActorId, spawnType)); subpackets.Add(CreateNamePacket(playerActorId)); subpackets.Add(CreateStatePacket(playerActorId)); subpackets.Add(CreateIsZoneingPacket(playerActorId)); subpackets.Add(CreateScriptBindPacket(playerActorId)); return BasePacket.CreatePacket(subpackets, true, false); - } + } public virtual BasePacket GetInitPackets(uint playerActorId) { @@ -301,7 +301,7 @@ namespace FFXIVClassic_Map_Server.Actors SubPacket ChangeSpeedPacket = SetActorSpeedPacket.BuildPacket(actorId, actorId, moveSpeeds[0], moveSpeeds[1], moveSpeeds[2]); zone.BroadcastPacketAroundActor(this, ChangeSpeedPacket); } - + public void generateActorName(int actorNumber) { //Format Class Name @@ -311,7 +311,7 @@ namespace FFXIVClassic_Map_Server.Actors .Replace("MapObj", "Map") .Replace("Object", "Obj") .Replace("Retainer", "Rtn") - .Replace("Standard", "Std"); + .Replace("Standard", "Std"); className = Char.ToLowerInvariant(className[0]) + className.Substring(1); //Format Zone Name @@ -335,7 +335,7 @@ namespace FFXIVClassic_Map_Server.Actors className = className.Substring(0, 20 - zoneName.Length); } catch (ArgumentOutOfRangeException e) - {} + { } //Convert actor number to base 63 string classNumber = Utils.ToStringBase63(actorNumber); @@ -349,6 +349,34 @@ namespace FFXIVClassic_Map_Server.Actors actorName = String.Format("{0}_{1}_{2}@{3:X3}{4:X2}", className, zoneName, classNumber, zoneId, privLevel); } + public List GetPos() + { + List pos = new List(); + + pos.Add(positionX); + pos.Add(positionY); + pos.Add(positionZ); + pos.Add(rotation); + pos.Add(zoneId); + + return pos; + } + + public void SetPos(float x, float y, float z, float rot = 0, uint zoneId = 0) + { + oldPositionX = positionX; + oldPositionY = positionY; + oldPositionZ = positionZ; + oldRotation = rotation; + + positionX = x; + positionY = y; + positionZ = z; + rotation = rot; + + // todo: handle zone? + zone.BroadcastPacketAroundActor(this, MoveActorToPositionPacket.BuildPacket(this.actorId, this.actorId, x, y, z, rot, moveState)); + } } } diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs index 5b510fce..c9767c1d 100644 --- a/FFXIVClassic Map Server/actors/area/Area.cs +++ b/FFXIVClassic Map Server/actors/area/Area.cs @@ -292,7 +292,7 @@ namespace FFXIVClassic_Map_Server.Actors { if (a is Player) { - if (((Player)a).customDisplayName.Equals(name)) + if (((Player)a).customDisplayName.ToLower().Equals(name.ToLower())) return (Player)a; } } diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index fef4e299..67249ba1 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -1,5 +1,4 @@ -using FFXIVClassic.Common; -using FFXIVClassic_Map_Server.packets; +using FFXIVClassic_Map_Server.packets; using FFXIVClassic_Map_Server.actors.director; using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.dataobjects; @@ -12,6 +11,7 @@ using MoonSharp.Interpreter.Loaders; using System; using System.Collections.Generic; using System.IO; +using System.Diagnostics; namespace FFXIVClassic_Map_Server.lua { @@ -36,13 +36,13 @@ namespace FFXIVClassic_Map_Server.lua { luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName()); if (File.Exists(luaPath)) - { + { Script script = LoadScript(luaPath); if (script == null) return null; - DynValue result = script.Call(script.Globals["init"], target); + DynValue result = RunScript(script, script.Globals["init"], target); List lparams = LuaUtils.CreateLuaParamList(result); return lparams; } @@ -54,8 +54,8 @@ namespace FFXIVClassic_Map_Server.lua } return null; - } - + } + public static void DoActorOnEventStarted(Player player, Actor target, EventStartPacket eventStart) { if (target is Npc) @@ -74,7 +74,7 @@ namespace FFXIVClassic_Map_Server.lua { luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName()); } - else + else luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName()); if (File.Exists(luaPath)) @@ -95,13 +95,13 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onEventStarted").IsNil()) - script.Call(script.Globals["onEventStarted"], objects.ToArray()); + RunScript(script, script.Globals["onEventStarted"], objects.ToArray()); } else { SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName())); - } - + } + } public static void DoActorOnSpawn(Player player, Npc target) @@ -117,7 +117,7 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onSpawn").IsNil()) - script.Call(script.Globals["onSpawn"], player, target); + RunScript(script, script.Globals["onSpawn"], player, target); } else { @@ -134,12 +134,12 @@ namespace FFXIVClassic_Map_Server.lua return; } - string luaPath; - - if (target is Command) + string luaPath; + + if (target is Command) luaPath = String.Format(FILEPATH_COMMANDS, target.GetName()); else if (target is Director) - luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName()); + luaPath = String.Format(FILEPATH_DIRECTORS, target.GetName()); else luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName()); @@ -159,18 +159,18 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onEventUpdate").IsNil()) - script.Call(script.Globals["onEventUpdate"], objects.ToArray()); + RunScript(script, script.Globals["onEventUpdate"], objects.ToArray()); } else { SendError(player, String.Format("ERROR: Could not find script for actor {0}.", target.GetName())); - } + } } public static void OnZoneIn(Player player) { - string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().actorId); - + string luaPath = String.Format(FILEPATH_ZONE, player.GetZone().actorId); + if (File.Exists(luaPath)) { Script script = LoadScript(luaPath); @@ -180,8 +180,8 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onZoneIn").IsNil()) - script.Call(script.Globals["onZoneIn"], player); - } + RunScript(script, script.Globals["onZoneIn"], player); + } } public static void OnBeginLogin(Player player) @@ -195,7 +195,7 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onBeginLogin").IsNil()) - script.Call(script.Globals["onBeginLogin"], player); + RunScript(script, script.Globals["onBeginLogin"], player); } } @@ -210,29 +210,175 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onLogin").IsNil()) - script.Call(script.Globals["onLogin"], player); + RunScript(script, script.Globals["onLogin"], player); } } + #region RunGMCommand + public static void RunGMCommand(Player player, String cmd, string[] param, bool help = false) + { + // load from scripts/commands/gm/ directory + var path = String.Format("./scripts/commands/gm/{0}.lua", cmd.ToString().ToLower()); + + // check if the file exists + if (File.Exists(path)) + { + // load global functions + Script 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) { Program.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) + { + Program.Log.Info("[Commands] [{0}]: {1}", cmd, description); + return; + } + + // we'll push our lua params here + List LuaParam = new List(); + + var i = 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: + Program.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); + + // run the script + RunScript(script, script.Globals["onTrigger"], LuaParam.ToArray()); + return; + } + } + Program.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path); + return; + } + #endregion + public static Script LoadScript(string filename) { - Script script = new Script(); - ((FileSystemScriptLoader)script.Options.ScriptLoader).ModulePaths = FileSystemScriptLoader.UnpackStringPaths("./scripts/?;./scripts/?.lua"); - script.Globals["GetWorldManager"] = (Func)Server.GetWorldManager; - script.Globals["GetStaticActor"] = (Func)Server.GetStaticActors; - script.Globals["GetWorldMaster"] = (Func)Server.GetWorldManager().GetActor; - script.Globals["GetItemGamedata"] = (Func)Server.GetItemGamedata; + Script script = LoadGlobals(); try { script.DoFile(filename); } - catch(SyntaxErrorException e) + catch (SyntaxErrorException e) { Program.Log.Error("LUAERROR: {0}.", e.DecoratedMessage); return null; } return script; + } + + public static Script LoadGlobals(Script script = null) + { + script = script ?? new Script(); + + // register and load all global functions here + ((FileSystemScriptLoader)script.Options.ScriptLoader).ModulePaths = FileSystemScriptLoader.UnpackStringPaths("./scripts/?;./scripts/?.lua"); + script.Globals["GetWorldManager"] = (Func)Server.GetWorldManager; + script.Globals["GetStaticActor"] = (Func)Server.GetStaticActors; + script.Globals["GetWorldMaster"] = (Func)Server.GetWorldManager().GetActor; + script.Globals["GetItemGamedata"] = (Func)Server.GetItemGamedata; + + script.Options.DebugPrint = s => { Program.Log.Debug(s); }; + return script; } public static void SendError(Player player, string message) @@ -257,7 +403,7 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onTalked").IsNil()) - script.Call(script.Globals["onTalked"], player, npc); + RunScript(script, script.Globals["onTalked"], player, npc); } else { @@ -278,12 +424,154 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onCommand").IsNil()) - script.Call(script.Globals["onCommand"], player, command); + RunScript(script, script.Globals["onCommand"], player, command); } else { SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.GetName())); } - } + } + + + #region RunScript + // + // Summary: + // Calls the specified function. + // + // Parameters: + // function: + // The Lua/MoonSharp function to be called + // + // Returns: + // The return value(s) of the function call. + // + // Exceptions: + // T:System.ArgumentException: + // Thrown if function is not of DataType.Function + public static DynValue RunScript(Script script, DynValue function) + { + DynValue res = null; + try + { + res = script.Call(function); + } + catch (InterpreterException e) + { + Program.Log.Error(e.DecoratedMessage); + } + return res; + } + // + // Summary: + // Calls the specified function. + // + // Parameters: + // function: + // The Lua/MoonSharp function to be called + // + // Exceptions: + // T:System.ArgumentException: + // Thrown if function is not of DataType.Function + public static DynValue RunScript(Script script, object function) + { + DynValue res = null; + try + { + res = script.Call(function); + } + catch (InterpreterException e) + { + Program.Log.Error(e.DecoratedMessage); + } + return res; + } + // + // Summary: + // Calls the specified function. + // + // Parameters: + // function: + // The Lua/MoonSharp function to be called + // + // args: + // The arguments to pass to the function. + // + // Exceptions: + // T:System.ArgumentException: + // Thrown if function is not of DataType.Function + public static DynValue RunScript(Script script, object function, params object[] args) + { + DynValue res = null; + try + { + res = script.Call(function, args); + } + catch (InterpreterException e) + { + Program.Log.Error(e.DecoratedMessage); + } + return res; + } + // + // Summary: + // Calls the specified function. + // + // Parameters: + // function: + // The Lua/MoonSharp function to be called + // + // args: + // The arguments to pass to the function. + // + // Returns: + // The return value(s) of the function call. + // + // Exceptions: + // T:System.ArgumentException: + // Thrown if function is not of DataType.Function + public static DynValue RunScript(Script script, DynValue function, params DynValue[] args) + { + DynValue res = null; + try + { + res = script.Call(function, args); + } + catch (InterpreterException e) + { + Program.Log.Error(e.DecoratedMessage); + } + return res; + } + // + // Summary: + // Calls the specified function. + // + // Parameters: + // function: + // The Lua/MoonSharp function to be called + // + // args: + // The arguments to pass to the function. + // + // Returns: + // The return value(s) of the function call. + // + // Exceptions: + // T:System.ArgumentException: + // Thrown if function is not of DataType.Function + public static DynValue RunScript(Script script, DynValue function, params object[] args) + { + DynValue res = null; + try + { + res = script.Call(function, args); + } + catch (InterpreterException e) + { + Program.Log.Error(e.DecoratedMessage); + } + return res; + } + #endregion } } diff --git a/data/scripts/commands/gm/command - Copy (2).lua b/data/scripts/commands/gm/command - Copy (2).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (2).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/command - Copy (3).lua b/data/scripts/commands/gm/command - Copy (3).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (3).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/command - Copy (4).lua b/data/scripts/commands/gm/command - Copy (4).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (4).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/command - Copy (5).lua b/data/scripts/commands/gm/command - Copy (5).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (5).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/command - Copy (6).lua b/data/scripts/commands/gm/command - Copy (6).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (6).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/command - Copy (7).lua b/data/scripts/commands/gm/command - Copy (7).lua new file mode 100644 index 00000000..576478bb --- /dev/null +++ b/data/scripts/commands/gm/command - Copy (7).lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "", + description = "", +} + +function onTrigger(player) + +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/giveitem.lua b/data/scripts/commands/gm/giveitem.lua new file mode 100644 index 00000000..84ae4f8f --- /dev/null +++ b/data/scripts/commands/gm/giveitem.lua @@ -0,0 +1,22 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "ssss", + description = "adds to for . and are optional, item is added to user if is nil", +} + +function onTrigger(player, argc, item, qty, location, target) + local sender = "[giveitem] "; + player = GetWorldManager():GetPCInWorld(target) or player; + if player then + item = tonumber(item) or nil; + qty = tonumber(qty) or 1; + location = tonumber(itemtype) or INVENTORY_NORMAL; + + if item then + player:GetInventory(location):AddItem(item, qty); + player:SendMessage(MSG_TYPE_SYSTEM_ERROR, "[giveitem] ", string.format("Added item %u to %s", item, player:GetName()); + end + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/graphic.lua b/data/scripts/commands/gm/graphic.lua new file mode 100644 index 00000000..19a28c5d --- /dev/null +++ b/data/scripts/commands/gm/graphic.lua @@ -0,0 +1,19 @@ +properties = { + permissions = 0, + parameters = "sssss", + description = [[changes appearance for equipment in . Parameters: , + idk what any of those mean either]], +} + +function onTrigger(player, argc, slot, wId, eId, vId, cId) + slot = tonumber(slot) or 0; + wId = tonumber(wId) or 0; + eId = tonumber(eId) or 0; + vId = tonumber(vId) or 0; + cId = tonumber(cId) or 0; + + if player then + player:GraphicChange(slot, wId, eId, vId, cId); + player:SendAppearance(); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/music.lua b/data/scripts/commands/gm/music.lua new file mode 100644 index 00000000..a55f697c --- /dev/null +++ b/data/scripts/commands/gm/music.lua @@ -0,0 +1,10 @@ +properties = { + permissions = 0, + parameters = "s", + description = "plays music to player", +} + +function onTrigger(player, argc, music) + music = tonumber(music) or 0; + player:ChangeMusic(music); +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/mypos.lua b/data/scripts/commands/gm/mypos.lua new file mode 100644 index 00000000..74f70cb7 --- /dev/null +++ b/data/scripts/commands/gm/mypos.lua @@ -0,0 +1,22 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "", + description = "prints your current in-game position (different to map coords)", +} + +function onTrigger(player) + local pos = player:GetPos(); + local x = pos[0]; + local y = pos[1]; + local z = pos[2]; + local rot = pos[3]; + local zone = pos[4]; + + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local sender = "[mypos] "; + local message = string.format("current position X:%d Y:%d Z:%d (Rotation: %d) Zone:%d", x, y, z, rot, zone); + + player:SendMessage(messageID, sender, message); +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/reloadzone.lua b/data/scripts/commands/gm/reloadzone.lua new file mode 100644 index 00000000..35db5d1e --- /dev/null +++ b/data/scripts/commands/gm/reloadzone.lua @@ -0,0 +1,23 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "s", + description = "reloads ", +} + +function onTrigger(player, argc, zone) + if not zone or tonumber(zone) == 0 then + printf("%s is not a valid zone!", zone); + return; + end; + + zone = tonumber(zone); + + if player then + local messageID = MSG_TYPE_SYSTEM_ERROR; + player:SendMessage(messageID, "[reloadzones] ", string.format("Reloading zone: %u", zone)); + end; + + GetWorldManager():ReloadZone(zone); +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/test.lua b/data/scripts/commands/gm/test.lua new file mode 100644 index 00000000..6b0221b7 --- /dev/null +++ b/data/scripts/commands/gm/test.lua @@ -0,0 +1,9 @@ +properties = { + permissions = 0, + parameters = "sss", + description = "", +} + +function onTrigger(player, argc) + -- todo: change weather +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/warp.lua b/data/scripts/commands/gm/warp.lua new file mode 100644 index 00000000..01b689fb --- /dev/null +++ b/data/scripts/commands/gm/warp.lua @@ -0,0 +1,78 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "sssssss", + description = [[ + | + | + . +]], +} + +function onTrigger(player, argc, p1, p2, p3, p4, privateArea, firstName, lastName) + + if firstName then + if lastName then + player = GetWorldManager():GetPCInWorld(firstName.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(firstName) or nil; + end; + end; + + if not player then + printf("[Command] [warp] error! No target or player specified!"); + return; + end; + + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local sender = "[warp] "; + + -- we're getting a list/array from c# so 0 index + local pos = player:GetPos(); + local player_x = pos[0]; + local player_y = pos[1]; + local player_z = pos[2]; + local player_rot = pos[3]; + local player_zone = pos[4]; + + local worldManager = GetWorldManager(); + + -- treat this as a predefined warp list + if argc == 1 then + zone = tonumber(p1) or player_zone; + player:SendMessage(messageID, sender, string.format("warping to zone:%u", zone)); + worldManager:DoZoneChange(player, zone); + + elseif argc >= 3 then + + if argc == 3 then + local x = tonumber(applyPositionOffset(p1, player_x)) or player_x; + local y = tonumber(applyPositionOffset(p2, player_y)) or player_y; + local z = tonumber(applyPositionOffset(p3, player_z)) or player_z; + + player:SendMessage(messageID, sender, string.format("setting coordinates X:%d Y:%d Z:%d within current zone (%d)", x, y, z, player_zone)); + worldManager:DoPlayerMoveInZone(player, x, y, z, 0x0F); + else + local zone = tonumber(applyPositionOffset(p1, player_zone)) or player_zone; + local x = tonumber(applyPositionOffset(p2, player_x)) or player_x; + local y = tonumber(applyPositionOffset(p3, player_y)) or player_y; + local z = tonumber(applyPositionOffset(p4, player_z)) or player_z; + if privateArea == "" then privateArea = nil end; + player:SendMessage(messageID, sender, string.format("setting coordinates X:%d Y:%d Z:%d to new zone (%d) private area:%s", x, y, z, zone, privateArea or "unspecified")); + worldManager:DoZoneChange(player, zone, privateArea, 0x0F, x, y, z, 0.00); + end + + else + player:SendMessage(messageID, sender, "Unknown parameters! Usage: "..properties.description); + end; +end; + +function applyPositionOffset(str, offset) + local s = str; + print(s); + if s:find("@") then + s = tonumber(s:sub(s:find("@") + 1, s:len())) + offset; + end + return s; +end; \ No newline at end of file diff --git a/data/scripts/global.lua b/data/scripts/global.lua index 5b7d0984..d79ae0d8 100644 --- a/data/scripts/global.lua +++ b/data/scripts/global.lua @@ -4,7 +4,7 @@ Globals referenced in all of the lua scripts --]] ---ACTOR STATES +-- ACTOR STATES ACTORSTATE_PASSIVE = 0; ACTORSTATE_DEAD1 = 1; @@ -12,4 +12,50 @@ ACTORSTATE_ACTIVE = 2; ACTORSTATE_DEAD2 = 3; ACTORSTATE_SITTING_ONOBJ = 11; ACTORSTATE_SITTING_ONFLOOR = 13; -ACTORSTATE_MOUNTED = 15; \ No newline at end of file +ACTORSTATE_MOUNTED = 15; + + +-- MESSAGE +MESSAGE_TYPE_NONE = 0; +MESSAGE_TYPE_SAY = 1; +MESSAGE_TYPE_SHOUT = 2; +MESSAGE_TYPE_TELL = 3; +MESSAGE_TYPE_PARTY = 4; +MESSAGE_TYPE_LINKSHELL1 = 5; +MESSAGE_TYPE_LINKSHELL2 = 6; +MESSAGE_TYPE_LINKSHELL3 = 7; +MESSAGE_TYPE_LINKSHELL4 = 8; +MESSAGE_TYPE_LINKSHELL5 = 9; +MESSAGE_TYPE_LINKSHELL6 = 10; +MESSAGE_TYPE_LINKSHELL7 = 11; +MESSAGE_TYPE_LINKSHELL8 = 12; + +MESSAGE_TYPE_SAY_SPAM = 22; +MESSAGE_TYPE_SHOUT_SPAM = 23; +MESSAGE_TYPE_TELL_SPAM = 24; +MESSAGE_TYPE_CUSTOM_EMOTE = 25; +MESSAGE_TYPE_EMOTE_SPAM = 26; +MESSAGE_TYPE_STANDARD_EMOTE = 27; +MESSAGE_TYPE_URGENT_MESSAGE = 28; +MESSAGE_TYPE_GENERAL_INFO = 29; +MESSAGE_TYPE_SYSTEM = 32; +MESSAGE_TYPE_SYSTEM_ERROR = 33; + +-- INVENTORY +INVENTORY_NORMAL = 0x0000; --Max 0xC8 +INVENTORY_LOOT = 0x0004; --Max 0xA +INVENTORY_MELDREQUEST = 0x0005; --Max 0x04 +INVENTORY_BAZAAR = 0x0007; --Max 0x0A +INVENTORY_CURRENCY = 0x0063; --Max 0x140 +INVENTORY_KEYITEMS = 0x0064; --Max 0x500 +INVENTORY_EQUIPMENT = 0x00FE; --Max 0x23 +INVENTORY_EQUIPMENT_OTHERPLAYER = 0x00F9; --Max 0x23 + + + + + + +function printf(s, ...) + print(s:format(...)); +end; \ No newline at end of file