From 57b9d5ab9967cc4f4aef6a776135c5cf0503f369 Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Thu, 16 Jun 2016 01:50:13 +0100 Subject: [PATCH 01/10] 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 From 1ad2b5d7d0856aabe88bfb5e4cb7074bf08640a5 Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Fri, 17 Jun 2016 05:05:31 +0100 Subject: [PATCH 02/10] more work on commands - moved script object to wrapper class to catch and log exceptions - added loggers for basepacket/subpacket (todo: colour and use them in NLog.config) - finished up most commands (todo: !property and !property2) - todo: create and use mysql wrapper class to log exceptions --- .../FFXIVClassic Common Class Lib.csproj | 10 + FFXIVClassic Common Class Lib/Sql.cs | 80 ++ FFXIVClassic Common Class Lib/app.config | 9 + FFXIVClassic Common Class Lib/packages.config | 3 +- FFXIVClassic Lobby Server/Program.cs | 11 +- .../packets/BasePacket.cs | 13 +- .../packets/SubPacket.cs | 8 +- FFXIVClassic Map Server/CommandProcessor.cs | 789 ++---------------- .../FFXIVClassic Map Server.csproj | 1 + FFXIVClassic Map Server/NLog.config | 5 +- FFXIVClassic Map Server/actors/Actor.cs | 10 + FFXIVClassic Map Server/actors/area/Area.cs | 23 +- .../actors/chara/npc/Npc.cs | 2 +- .../actors/chara/player/Inventory.cs | 11 +- .../actors/chara/player/Player.cs | 20 + FFXIVClassic Map Server/lua/LuaEngine.cs | 201 +---- FFXIVClassic Map Server/lua/LuaScript.cs | 240 ++++++ ...le_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs | 0 ...le_5937a670-0e60-4077-877b-f7221da3dda1.cs | 0 ...le_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs | 0 FFXIVClassic Map Server/packets/BasePacket.cs | 7 +- FFXIVClassic Map Server/packets/SubPacket.cs | 8 +- data/scripts/commands/gm/delcurrency.lua | 37 + data/scripts/commands/gm/delitem.lua | 37 + data/scripts/commands/gm/delkeyitem.lua | 37 + data/scripts/commands/gm/givecurrency.lua | 37 + data/scripts/commands/gm/giveitem.lua | 26 +- data/scripts/commands/gm/givekeyitem.lua | 37 + data/scripts/commands/gm/graphic.lua | 3 +- .../{command - Copy (7).lua => property.lua} | 0 data/scripts/commands/gm/reloadzone.lua | 15 +- data/scripts/commands/gm/test.lua | 9 - data/scripts/commands/gm/warp.lua | 13 +- data/scripts/commands/gm/weather.lua | 30 + data/scripts/global.lua | 6 +- 35 files changed, 780 insertions(+), 958 deletions(-) create mode 100644 FFXIVClassic Common Class Lib/Sql.cs create mode 100644 FFXIVClassic Common Class Lib/app.config create mode 100644 FFXIVClassic Map Server/lua/LuaScript.cs delete mode 100644 FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs delete mode 100644 FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs delete mode 100644 FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs create mode 100644 data/scripts/commands/gm/delcurrency.lua create mode 100644 data/scripts/commands/gm/delitem.lua create mode 100644 data/scripts/commands/gm/delkeyitem.lua create mode 100644 data/scripts/commands/gm/givecurrency.lua create mode 100644 data/scripts/commands/gm/givekeyitem.lua rename data/scripts/commands/gm/{command - Copy (7).lua => property.lua} (100%) delete mode 100644 data/scripts/commands/gm/test.lua create mode 100644 data/scripts/commands/gm/weather.lua diff --git a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj index 1adbda3e..a3fe065d 100644 --- a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj +++ b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj @@ -35,6 +35,14 @@ false + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll + True + + + ..\packages\NLog.4.3.5\lib\net45\NLog.dll + True + @@ -49,10 +57,12 @@ + + diff --git a/FFXIVClassic Common Class Lib/Sql.cs b/FFXIVClassic Common Class Lib/Sql.cs new file mode 100644 index 00000000..fcad7791 --- /dev/null +++ b/FFXIVClassic Common Class Lib/Sql.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MySql.Data.MySqlClient; +using NLog; + +namespace FFXIVClassic.Common +{ + /* + class SqlCommand + { + public static Logger Log = LogManager.GetCurrentClassLogger(); + + public SqlCommand() + { + + } + + public SqlCommand(string cmdText) + { + try + { + MySqlCommand.MySqlCommand(""); + } + } + public SqlCommand(string cmdText, MySqlConnection connection); + public SqlCommand(string cmdText, MySqlConnection connection, MySqlTransaction transaction); + + ~SqlCommand() + { + + } + + public int CacheAge { get; set; } + + public string CommandText { get; set; } + public int CommandTimeout { get; set; } + + public CommandType CommandType { get; set; } + + public MySqlConnection Connection { get; set; } + + public bool DesignTimeVisible { get; set; } + public bool EnableCaching { get; set; } + + public bool IsPrepared { get; } + + public long LastInsertedId { get; } + + public MySqlParameterCollection Parameters { get; } + + public MySqlTransaction Transaction { get; set; } + public UpdateRowSource UpdatedRowSource { get; set; } + protected DbConnection DbConnection { get; set; } + protected DbParameterCollection DbParameterCollection { get; } + protected DbTransaction DbTransaction { get; set; } + + public IAsyncResult BeginExecuteNonQuery(); + public IAsyncResult BeginExecuteNonQuery(AsyncCallback callback, object stateObject); + public IAsyncResult BeginExecuteReader(); + public IAsyncResult BeginExecuteReader(CommandBehavior behavior); + public void Cancel(); + public SqlCommand Clone(); + public MySqlParameter CreateParameter(); + public void Dispose(); + public int EndExecuteNonQuery(IAsyncResult asyncResult); + public MySqlDataReader EndExecuteReader(IAsyncResult result); + public int ExecuteNonQuery(); + public MySqlDataReader ExecuteReader(); + public MySqlDataReader ExecuteReader(CommandBehavior behavior); + public object ExecuteScalar(); + public void Prepare(); + protected DbParameter CreateDbParameter(); + protected void Dispose(bool disposing); + protected DbDataReader ExecuteDbDataReader(CommandBehavior behavior); + } + */ +} diff --git a/FFXIVClassic Common Class Lib/app.config b/FFXIVClassic Common Class Lib/app.config new file mode 100644 index 00000000..143834c2 --- /dev/null +++ b/FFXIVClassic Common Class Lib/app.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Common Class Lib/packages.config b/FFXIVClassic Common Class Lib/packages.config index c171747f..d0ca21c2 100644 --- a/FFXIVClassic Common Class Lib/packages.config +++ b/FFXIVClassic Common Class Lib/packages.config @@ -1,4 +1,5 @@  - + + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/Program.cs b/FFXIVClassic Lobby Server/Program.cs index c5967a87..ee40fced 100644 --- a/FFXIVClassic Lobby Server/Program.cs +++ b/FFXIVClassic Lobby Server/Program.cs @@ -12,13 +12,13 @@ namespace FFXIVClassic_Lobby_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); - Debug.Listeners.Add(myWriter); + Debug.Listeners.Add(myWriter); #endif Program.Log.Info("--------FFXIV 1.0 Lobby Server--------"); @@ -55,6 +55,9 @@ namespace FFXIVClassic_Lobby_Server { Server server = new Server(); server.StartServer(); + + while (true) + Thread.Sleep(1000); } Program.Log.Info("Press any key to continue..."); diff --git a/FFXIVClassic Lobby Server/packets/BasePacket.cs b/FFXIVClassic Lobby Server/packets/BasePacket.cs index f37d6721..332e7d6f 100644 --- a/FFXIVClassic Lobby Server/packets/BasePacket.cs +++ b/FFXIVClassic Lobby Server/packets/BasePacket.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using System.Diagnostics; using FFXIVClassic.Common; using System.IO; +using NLog; namespace FFXIVClassic_Lobby_Server.packets { @@ -21,7 +22,7 @@ namespace FFXIVClassic_Lobby_Server.packets public class BasePacket { - + public static Logger Log = LogManager.GetCurrentClassLogger(); public const int TYPE_ZONE = 1; public const int TYPE_CHAT = 2; public const int BASEPACKET_SIZE = 0x10; @@ -332,12 +333,12 @@ namespace FFXIVClassic_Lobby_Server.packets #endregion public void DebugPrintPacket() - { + { #if DEBUG - // todo: create new target for colourful packet logging - //Console.BackgroundColor = ConsoleColor.DarkYellow; - - Program.Log.Debug("IsAuth: {0} Size: 0x{1:X}, NumSubpackets: {2}{3}{4}", header.isAuthenticated, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); + // todo: create new target for colourful packet logging + //Console.BackgroundColor = ConsoleColor.DarkYellow; + + Log.Debug("IsAuth: {0} Size: 0x{1:X}, NumSubpackets: {2}{3}{4}", header.isAuthenticated, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); foreach (SubPacket sub in GetSubpackets()) { diff --git a/FFXIVClassic Lobby Server/packets/SubPacket.cs b/FFXIVClassic Lobby Server/packets/SubPacket.cs index 1711dc65..0dcb526b 100644 --- a/FFXIVClassic Lobby Server/packets/SubPacket.cs +++ b/FFXIVClassic Lobby Server/packets/SubPacket.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.InteropServices; using FFXIVClassic.Common; +using NLog; namespace FFXIVClassic_Lobby_Server.packets { @@ -26,6 +27,7 @@ namespace FFXIVClassic_Lobby_Server.packets public class SubPacket { + public static Logger Log = LogManager.GetCurrentClassLogger(); public const int SUBPACKET_SIZE = 0x10; public const int GAMEMESSAGE_SIZE = 0x10; @@ -141,14 +143,14 @@ namespace FFXIVClassic_Lobby_Server.packets { #if DEBUG // todo: create new target for colourful packet logging - Program.Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); + Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); if (header.type == 0x03) { - Program.Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); + Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); } - Program.Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); + Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); #endif } diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/FFXIVClassic Map Server/CommandProcessor.cs index 849b682f..456f2b7a 100644 --- a/FFXIVClassic Map Server/CommandProcessor.cs +++ b/FFXIVClassic Map Server/CommandProcessor.cs @@ -73,418 +73,6 @@ namespace FFXIVClassic_Map_Server } } - public void DoMusic(ConnectedPlayer client, string music) - { - ushort musicId; - - if (music.ToLower().StartsWith("0x")) - musicId = Convert.ToUInt16(music, 16); - else - musicId = Convert.ToUInt16(music); - - if (client != null) - client.QueuePacket(BasePacket.CreatePacket(SetMusicPacket.BuildPacket(client.actorID, musicId, 1), true, false)); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - BasePacket musicPacket = BasePacket.CreatePacket(SetMusicPacket.BuildPacket(entry.Value.actorID, musicId, 1), true, false); - entry.Value.QueuePacket(musicPacket); - } - } - } - - /// - /// Teleports player to a location on a predefined list - /// - /// The current player - /// Predefined list: <ffxiv_database>\server_zones_spawnlocations - public void DoWarp(ConnectedPlayer client, uint id) - { - WorldManager worldManager = Server.GetWorldManager(); - FFXIVClassic_Map_Server.WorldManager.ZoneEntrance ze = worldManager.GetZoneEntrance(id); - - if (ze == null) - return; - - if (client != null) - worldManager.DoZoneChange(client.GetActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - worldManager.DoZoneChange(entry.Value.GetActor(), ze.zoneId, ze.privateAreaName, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); - } - } - } - - public void DoWarp(ConnectedPlayer client, uint zoneId, string privateArea, byte spawnType, float x, float y, float z, float r) - { - WorldManager worldManager = Server.GetWorldManager(); - if (worldManager.GetZone(zoneId) == null) - { - if (client != null) - client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Zone does not exist or setting isn't valid."), true, false)); - Program.Log.Error("Zone does not exist or setting isn't valid."); - } - - if (client != null) - worldManager.DoZoneChange(client.GetActor(), zoneId, privateArea, spawnType, x, y, z, r); - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - worldManager.DoZoneChange(entry.Value.GetActor(), zoneId, privateArea, spawnType, x, y, z, r); - } - } - } - - public void PrintPos(ConnectedPlayer client) - { - if (client != null) - { - Player p = client.GetActor(); - client.QueuePacket(BasePacket.CreatePacket(SendMessagePacket.BuildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)), true, false)); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - Program.Log.Info(String.Format("{0}\'s position: ZoneID: {1}, X: {2}, Y: {3}, Z: {4}, Rotation: {5}", p.customDisplayName, p.zoneId, p.positionX, p.positionY, p.positionZ, p.rotation)); - } - } - } - - private void SetGraphic(ConnectedPlayer client, uint slot, uint wId, uint eId, uint vId, uint cId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GraphicChange(slot, wId, eId, vId, cId); - p.SendAppearance(); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GraphicChange(slot, wId, eId, vId, cId); - p.SendAppearance(); - } - } - } - - private void GiveItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.NORMAL).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.NORMAL).AddItem(itemId, quantity); - } - } - } - - private void GiveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).AddItem(itemId, quantity); - } - } - } - - private void RemoveItem(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.NORMAL).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.NORMAL).RemoveItem(itemId, quantity); - } - } - } - - private void RemoveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type) - { - if (client != null) - { - Player p = client.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - - if (p.GetInventory(type) != null) - p.GetInventory(type).RemoveItem(itemId, quantity); - } - } - } - - private void GiveCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.CURRENCY).AddItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.CURRENCY).AddItem(itemId, quantity); - } - } - } - - // TODO: make RemoveCurrency() Remove all quantity of a currency if quantity_to_Remove > quantity_in_inventory instead of silently failing - private void RemoveCurrency(ConnectedPlayer client, uint itemId, int quantity) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.CURRENCY).RemoveItem(itemId, quantity); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.CURRENCY).RemoveItem(itemId, quantity); - } - } - } - - private void GiveKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.KEYITEMS).AddItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.KEYITEMS).AddItem(itemId, 1); - } - } - } - - private void RemoveKeyItem(ConnectedPlayer client, uint itemId) - { - if (client != null) - { - Player p = client.GetActor(); - p.GetInventory(Inventory.KEYITEMS).RemoveItem(itemId, 1); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - Player p = entry.Value.GetActor(); - p.GetInventory(Inventory.KEYITEMS).RemoveItem(itemId, 1); - } - } - } - - private void ParseWarp(ConnectedPlayer client, string[] split) - { - float x = 0, y = 0, z = 0, r = 0.0f; - uint zoneId = 0; - string privatearea = null; - - if (split.Length == 2) // Predefined list - { - // TODO: Handle !warp Playername - #region !warp (predefined list) - try - { - if (split[1].ToLower().StartsWith("0x")) - zoneId = Convert.ToUInt32(split[1], 16); - else - zoneId = Convert.ToUInt32(split[1]); - } - catch{return;} - #endregion - - DoWarp(client, zoneId); - } - else if (split.Length == 4) - { - #region !warp X Y Z - if (split[1].StartsWith("@")) - { - split[1] = split[1].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[1])) - split[1] = "0"; - - try { x = Single.Parse(split[1]) + client.GetActor().positionX; } - catch{return;} - - split[1] = x.ToString(); - } - if (split[2].StartsWith("@")) - { - split[2] = split[2].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[2])) - split[2] = "0"; - - try { y = Single.Parse(split[2]) + client.GetActor().positionY; } - catch{return;} - - split[2] = y.ToString(); - } - if (split[3].StartsWith("@")) - { - split[3] = split[3].Replace("@", string.Empty); - - if (String.IsNullOrEmpty(split[3])) - split[3] = "0"; - - try { z = Single.Parse(split[3]) + client.GetActor().positionZ; } - catch{return;} - - split[3] = z.ToString(); - } - - try - { - x = Single.Parse(split[1]); - y = Single.Parse(split[2]); - z = Single.Parse(split[3]); - } - catch{return;} - - zoneId = client.GetActor().zoneId; - r = client.GetActor().rotation; - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x00, x, y, z, r); - } - else if (split.Length == 5) - { - #region !warp Zone X Y Z - try - { - x = Single.Parse(split[2]); - y = Single.Parse(split[3]); - z = Single.Parse(split[4]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else if (split.Length == 6) - { - #region !warp Zone Instance X Y Z - try - { - x = Single.Parse(split[3]); - y = Single.Parse(split[4]); - z = Single.Parse(split[5]); - } - catch{return;} - - if (split[1].ToLower().StartsWith("0x")) - { - try { zoneId = Convert.ToUInt32(split[1], 16); } - catch{return;} - } - else - { - try { zoneId = Convert.ToUInt32(split[1]); } - catch{return;} - } - - privatearea = split[2]; - #endregion - - SendMessage(client, String.Format("Warping to: ZoneID: {0} X: {1}, Y: {2}, Z: {3}", zoneId, x, y, z)); - DoWarp(client, zoneId, privatearea, 0x2, x, y, z, r); - } - else - return; // catch any invalid warps here - } - - private void DoWeather(ConnectedPlayer client, string weatherID, string value) - { - ushort weather = Convert.ToUInt16(weatherID); - - if (client != null) - { - client.QueuePacket(BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(client.actorID, weather, Convert.ToUInt16(value)), true, false)); - } - - /* - * WIP: Change weather serverside, currently only clientside - * - uint currentZoneID; - if (client != null) - { - currentZoneID = client.GetActor().zoneId; - - foreach (KeyValuePair entry in mConnectedPlayerList) - { - // Change the weather for everyone in the same zone - if (currentZoneID == entry.Value.GetActor().zoneId) - { - BasePacket weatherPacket = BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(entry.Value.actorID, weather), true, false); - entry.Value.QueuePacket(weatherPacket); - } - } - } - */ - } - /// /// We only use the default options for SendMessagePacket. /// May as well make it less unwieldly to view @@ -512,8 +100,8 @@ namespace FFXIVClassic_Map_Server ) .SelectMany(str => str).ToArray(); - split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands - + split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands + var cmd = split?.ElementAt(0); if (cmd.Any()) @@ -543,334 +131,63 @@ namespace FFXIVClassic_Map_Server 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")) - { - if (split.Length == 1) - { - SendMessage(client, Resources.CPhelp); - } - if (split.Length == 2) - { - if (split[1].Equals("mypos")) - SendMessage(client, Resources.CPmypos); - else if (split[1].Equals("music")) - SendMessage(client, Resources.CPmusic); - else if (split[1].Equals("warp")) - SendMessage(client, Resources.CPwarp); - else if (split[1].Equals("givecurrency")) - SendMessage(client, Resources.CPgivecurrency); - else if (split[1].Equals("giveitem")) - SendMessage(client, Resources.CPgiveitem); - else if (split[1].Equals("givekeyitem")) - SendMessage(client, Resources.CPgivekeyitem); - else if (split[1].Equals("Removecurrency")) - SendMessage(client, Resources.CPRemovecurrency); - else if (split[1].Equals("Removeitem")) - SendMessage(client, Resources.CPRemoveitem); - else if (split[1].Equals("Removekeyitem")) - SendMessage(client, Resources.CPRemovekeyitem); - else if (split[1].Equals("reloaditems")) - SendMessage(client, Resources.CPreloaditems); - else if (split[1].Equals("reloadzones")) - SendMessage(client, Resources.CPreloadzones); - /* - else if (split[1].Equals("property")) - SendMessage(client, Resources.CPproperty); - else if (split[1].Equals("property2")) - SendMessage(client, Resources.CPproperty2); - else if (split[1].Equals("sendpacket")) - SendMessage(client, Resources.CPsendpacket); - else if (split[1].Equals("setgraphic")) - SendMessage(client, Resources.CPsetgraphic); - */ - } - if (split.Length == 3) - { - if(split[1].Equals("test")) - { - if (split[2].Equals("weather")) - SendMessage(client, Resources.CPtestweather); - } - } - - return true; - } + } + // Debug + //SendMessage(client, string.Join(",", split)); + + if (split.Length >= 1) + { + + #region !reloaditems + if (split[0].Equals("reloaditems")) + { + Program.Log.Info(String.Format("Got request to reload item gamedata")); + SendMessage(client, "Reloading Item Gamedata..."); + gamedataItems.Clear(); + gamedataItems = Database.GetItemGamedata(); + Program.Log.Info(String.Format("Loaded {0} items.", gamedataItems.Count)); + SendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count)); + return true; + } #endregion - - #region !test - else if (split[0].Equals("test")) - { - if (split.Length == 1) - { - // catch invalid commands - SendMessage(client, Resources.CPhelp); - } - else if (split.Length >= 2) - { - #region !test weather - if (split[1].Equals("weather")) - { - try - { - DoWeather(client, split[2], split[3]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not change weather: " + e); - } - } - #endregion - } - - } - #endregion - - #region !mypos - else if (split[0].Equals("mypos")) - { - try - { - PrintPos(client); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not load packet: " + e); - } - } - #endregion - - #region !reloadzones - else if (split[0].Equals("reloadzones")) - { - if (client != null) - { - Program.Log.Info(String.Format("Got request to reset zone: {0}", client.GetActor().zoneId)); - client.GetActor().zone.Clear(); - client.GetActor().zone.AddActorToZone(client.GetActor()); - 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); - return true; - } - #endregion - - #region !reloaditems - else if (split[0].Equals("reloaditems")) - { - Program.Log.Info(String.Format("Got request to reload item gamedata")); - SendMessage(client, "Reloading Item Gamedata..."); - gamedataItems.Clear(); - gamedataItems = Database.GetItemGamedata(); - Program.Log.Info(String.Format("Loaded {0} items.", gamedataItems.Count)); - SendMessage(client, String.Format("Loaded {0} items.", gamedataItems.Count)); - return true; - } - #endregion - + #region !sendpacket - else if (split[0].Equals("sendpacket")) - { - if (split.Length < 2) - return false; - - try - { - SendPacket(client, "./packets/" + split[1]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not load packet: " + e); - } - } + else if (split[0].Equals("sendpacket")) + { + if (split.Length < 2) + return false; + + try + { + SendPacket(client, "./packets/" + split[1]); + return true; + } + catch (Exception e) + { + Program.Log.Error("Could not load packet: " + e); + } + } #endregion - - #region !graphic - else if (split[0].Equals("graphic")) - { - try - { - if (split.Length == 6) - SetGraphic(client, UInt32.Parse(split[1]), UInt32.Parse(split[2]), UInt32.Parse(split[3]), UInt32.Parse(split[4]), UInt32.Parse(split[5])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not give item."); - } - } - #endregion - - #region !giveitem - else if (split[0].Equals("giveitem")) - { - try - { - if (split.Length == 2) - GiveItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - GiveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - GiveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not give item."); - } - } - #endregion - - #region !Removeitem - else if (split[0].Equals("Removeitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveItem(client, UInt32.Parse(split[1]), 1); - else if (split.Length == 3) - RemoveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - else if (split.Length == 4) - RemoveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove item."); - } - } - #endregion - - #region !givekeyitem - else if (split[0].Equals("givekeyitem")) - { - try - { - if (split.Length == 2) - GiveKeyItem(client, UInt32.Parse(split[1])); - } - catch (Exception e) - { - Program.Log.Error("Could not give keyitem."); - } - } - #endregion - - #region !Removekeyitem - else if (split[0].Equals("Removekeyitem")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveKeyItem(client, UInt32.Parse(split[1])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove keyitem."); - } - } - #endregion - - #region !givecurrency - else if (split[0].Equals("givecurrency")) - { - try - { - if (split.Length == 2) - GiveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - GiveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - } - catch (Exception e) - { - Program.Log.Error("Could not give currency."); - } - } - #endregion - - #region !Removecurrency - else if (split[0].Equals("Removecurrency")) - { - if (split.Length < 2) - return false; - - try - { - if (split.Length == 2) - RemoveCurrency(client, ITEM_GIL, Int32.Parse(split[1])); - else if (split.Length == 3) - RemoveCurrency(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not Remove currency."); - } - } - #endregion - - #region !music - else if (split[0].Equals("music")) - { - if (split.Length < 2) - return false; - - try - { - DoMusic(client, split[1]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not change music: " + e); - } - } - #endregion - - #region !warp - else if (split[0].Equals("warp")) - { - ParseWarp(client, split); - return true; - } - #endregion - + #region !property - else if (split[0].Equals("property")) - { - if (split.Length == 4) - { - ChangeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]); - } - return true; - } + else if (split[0].Equals("property")) + { + if (split.Length == 4) + { + ChangeProperty(Utils.MurmurHash2(split[1], 0), Convert.ToUInt32(split[2], 16), split[3]); + } + return true; + } #endregion - + #region !property2 - else if (split[0].Equals("property2")) - { - if (split.Length == 4) - { - ChangeProperty(Convert.ToUInt32(split[1], 16), Convert.ToUInt32(split[2], 16), split[3]); - } - return true; + else if (split[0].Equals("property2")) + { + if (split.Length == 4) + { + ChangeProperty(Convert.ToUInt32(split[1], 16), Convert.ToUInt32(split[2], 16), split[3]); + } + return true; } #endregion } diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index f01958b6..f178f04e 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -119,6 +119,7 @@ + diff --git a/FFXIVClassic Map Server/NLog.config b/FFXIVClassic Map Server/NLog.config index 1d8fb2f4..839421a0 100644 --- a/FFXIVClassic Map Server/NLog.config +++ b/FFXIVClassic Map Server/NLog.config @@ -29,8 +29,11 @@ --> - + + + + diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 30397547..b94246be 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -377,6 +377,16 @@ namespace FFXIVClassic_Map_Server.Actors // todo: handle zone? zone.BroadcastPacketAroundActor(this, MoveActorToPositionPacket.BuildPacket(this.actorId, this.actorId, x, y, z, rot, moveState)); } + + public Area GetZone() + { + return zone; + } + + public uint GetZoneID() + { + return zoneId; + } } } diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs index c9767c1d..73a2b5ac 100644 --- a/FFXIVClassic Map Server/actors/area/Area.cs +++ b/FFXIVClassic Map Server/actors/area/Area.cs @@ -13,7 +13,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; - +using FFXIVClassic_Map_Server.packets.send; + namespace FFXIVClassic_Map_Server.Actors { class Area : Actor @@ -352,5 +353,25 @@ namespace FFXIVClassic_Map_Server.Actors AddActorToZone(npc); } + public void ChangeWeather(ushort weather, ushort transitionTime, Player player, bool zoneWide = false) + { + weatherNormal = weather; + + if (player != null && !zoneWide) + { + player.QueuePacket(BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime), true, false)); + } + if (zoneWide) + { + foreach (var actor in mActorList) + { + if (actor.Value is Player) + { + player = ((Player)actor.Value); + player.QueuePacket(BasePacket.CreatePacket(SetWeatherPacket.BuildPacket(player.actorId, weather, transitionTime), true, false)); + } + } + } + } } } diff --git a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs index eb4aea77..35ba4583 100644 --- a/FFXIVClassic Map Server/actors/chara/npc/Npc.cs +++ b/FFXIVClassic Map Server/actors/chara/npc/Npc.cs @@ -3,7 +3,7 @@ using FFXIVClassic_Map_Server.actors; using FFXIVClassic_Map_Server.Actors.Chara; using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.lua; -using FFXIVClassic_Map_Server.packets; +using FFXIVClassic_Map_Server.packets; using FFXIVClassic_Map_Server.packets.receive.events; using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.utils; diff --git a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs index 38ec5ffe..19538ae4 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Inventory.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Inventory.cs @@ -87,15 +87,21 @@ namespace FFXIVClassic_Map_Server.actors.chara.player AddItem(itemId, quantity, 1); } - public void AddItem(uint itemId, int quantity, byte quality) + public bool AddItem(uint itemId, int quantity, byte quality) { if (!IsSpaceForAdd(itemId, quantity)) - return; + return false; Item gItem = Server.GetItemGamedata(itemId); List slotsToUpdate = new List(); List addItemPackets = new List(); + if (gItem == null) + { + Program.Log.Error("Inventory.AddItem: unable to find item %u", itemId); + return false; + } + //Check if item id exists int quantityCount = quantity; for (int i = 0; i < list.Count; i++) @@ -152,6 +158,7 @@ namespace FFXIVClassic_Map_Server.actors.chara.player owner.QueuePacket(InventorySetEndPacket.BuildPacket(owner.actorId)); owner.QueuePacket(InventoryEndChangePacket.BuildPacket(owner.actorId)); + return true; } public void AddItem(uint[] itemId) diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 82f801de..42ecf917 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -749,6 +749,26 @@ namespace FFXIVClassic_Map_Server.Actors //zone.BroadcastPacketAroundActor(this, worldMasterMessage); } + public void ChangeProperty(uint id, uint value, string target) + { + SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target); + + ChangeProperty.SetTarget(target); + ChangeProperty.AddInt(id, value); + ChangeProperty.AddTarget(); + + /*foreach (KeyValuePair entry in mConnectedPlayerList) + { + SubPacket ChangePropertyPacket = ChangeProperty.BuildPacket((entry.Value.actorID), (entry.Value.actorID)); + + BasePacket packet = BasePacket.CreatePacket(ChangePropertyPacket, true, false); + packet.DebugPrintPacket(); + + entry.Value.QueuePacket(packet); + } + */ + } + public void GraphicChange(uint slot, uint graphicId) { appearanceIds[slot] = graphicId; diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index 67249ba1..01683358 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Diagnostics; +using FFXIVClassic_Map_Server.lua; namespace FFXIVClassic_Map_Server.lua { @@ -37,12 +38,12 @@ namespace FFXIVClassic_Map_Server.lua luaPath = String.Format(FILEPATH_NPCS, target.zoneId, target.GetName()); if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return null; - DynValue result = RunScript(script, script.Globals["init"], target); + DynValue result = script.Call(script.Globals["init"], target); List lparams = LuaUtils.CreateLuaParamList(result); return lparams; } @@ -79,7 +80,7 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; @@ -95,7 +96,7 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onEventStarted").IsNil()) - RunScript(script, script.Globals["onEventStarted"], objects.ToArray()); + script.Call(script.Globals["onEventStarted"], objects.ToArray()); } else { @@ -110,14 +111,14 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; //Run Script if (!script.Globals.Get("onSpawn").IsNil()) - RunScript(script, script.Globals["onSpawn"], player, target); + script.Call(script.Globals["onSpawn"], player, target); } else { @@ -145,7 +146,7 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; @@ -159,7 +160,7 @@ namespace FFXIVClassic_Map_Server.lua //Run Script if (!script.Globals.Get("onEventUpdate").IsNil()) - RunScript(script, script.Globals["onEventUpdate"], objects.ToArray()); + script.Call(script.Globals["onEventUpdate"], objects.ToArray()); } else { @@ -173,14 +174,14 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; //Run Script if (!script.Globals.Get("onZoneIn").IsNil()) - RunScript(script, script.Globals["onZoneIn"], player); + script.Call(script.Globals["onZoneIn"], player); } } @@ -188,14 +189,14 @@ namespace FFXIVClassic_Map_Server.lua { if (File.Exists(FILEPATH_PLAYER)) { - Script script = LoadScript(FILEPATH_PLAYER); + LuaScript script = LoadScript(FILEPATH_PLAYER); if (script == null) return; //Run Script if (!script.Globals.Get("onBeginLogin").IsNil()) - RunScript(script, script.Globals["onBeginLogin"], player); + script.Call(script.Globals["onBeginLogin"], player); } } @@ -203,14 +204,14 @@ namespace FFXIVClassic_Map_Server.lua { if (File.Exists(FILEPATH_PLAYER)) { - Script script = LoadScript(FILEPATH_PLAYER); + LuaScript script = LoadScript(FILEPATH_PLAYER); if (script == null) return; //Run Script if (!script.Globals.Get("onLogin").IsNil()) - RunScript(script, script.Globals["onLogin"], player); + script.Call(script.Globals["onLogin"], player); } } @@ -224,7 +225,7 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(path)) { // load global functions - Script script = LoadGlobals(); + LuaScript script = LoadGlobals(); // see if this script has any syntax errors try @@ -275,7 +276,7 @@ namespace FFXIVClassic_Map_Server.lua } } } - catch (Exception e) { Program.Log.Error("LuaEngine.RunGMCommand: " + e.Message); return; } + catch (Exception e) { LuaScript.Log.Error("LuaEngine.RunGMCommand: " + e.Message); return; } } // if this isnt a console command, make sure player exists @@ -295,7 +296,7 @@ namespace FFXIVClassic_Map_Server.lua } else if (help) { - Program.Log.Info("[Commands] [{0}]: {1}", cmd, description); + LuaScript.Log.Info("[Commands] [{0}]: {1}", cmd, description); return; } @@ -323,7 +324,7 @@ namespace FFXIVClassic_Map_Server.lua LuaParam.Add(param[i + 1]); continue; default: - Program.Log.Info("LuaEngine.RunGMCommand: {0} unknown parameter {1}.", path, parameters[i]); + LuaScript.Log.Info("LuaEngine.RunGMCommand: {0} unknown parameter {1}.", path, parameters[i]); LuaParam.Add(param[i + 1]); continue; } @@ -341,18 +342,18 @@ namespace FFXIVClassic_Map_Server.lua LuaParam.Insert(1, i); // run the script - RunScript(script, script.Globals["onTrigger"], LuaParam.ToArray()); + script.Call(script.Globals["onTrigger"], LuaParam.ToArray()); return; } } - Program.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path); + LuaScript.Log.Error("LuaEngine.RunGMCommand: Unable to find script {0}", path); return; } #endregion - public static Script LoadScript(string filename) + public static LuaScript LoadScript(string filename) { - Script script = LoadGlobals(); + LuaScript script = LoadGlobals(); try { @@ -366,9 +367,9 @@ namespace FFXIVClassic_Map_Server.lua return script; } - public static Script LoadGlobals(Script script = null) + public static LuaScript LoadGlobals(LuaScript script = null) { - script = script ?? new Script(); + script = script ?? new LuaScript(); // register and load all global functions here ((FileSystemScriptLoader)script.Options.ScriptLoader).ModulePaths = FileSystemScriptLoader.UnpackStringPaths("./scripts/?;./scripts/?.lua"); @@ -396,14 +397,14 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; //Run Script if (!script.Globals.Get("onTalked").IsNil()) - RunScript(script, script.Globals["onTalked"], player, npc); + script.Call(script.Globals["onTalked"], player, npc); } else { @@ -417,161 +418,19 @@ namespace FFXIVClassic_Map_Server.lua if (File.Exists(luaPath)) { - Script script = LoadScript(luaPath); + LuaScript script = LoadScript(luaPath); if (script == null) return; //Run Script if (!script.Globals.Get("onCommand").IsNil()) - RunScript(script, script.Globals["onCommand"], player, command); + script.Call(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/FFXIVClassic Map Server/lua/LuaScript.cs b/FFXIVClassic Map Server/lua/LuaScript.cs new file mode 100644 index 00000000..6442ceca --- /dev/null +++ b/FFXIVClassic Map Server/lua/LuaScript.cs @@ -0,0 +1,240 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MoonSharp; +using MoonSharp.Interpreter; +using NLog; +using MoonSharp.Interpreter.Debugging; +using System.IO; + +namespace FFXIVClassic_Map_Server.lua +{ + class LuaScript : Script + { + public static Logger Log = LogManager.GetCurrentClassLogger(); + + public LuaScript() + { + this.Options.DebugPrint = s => { Log.Debug(s); }; + } + public new static DynValue RunFile(string filename) + { + try + { + return Script.RunFile(filename); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new void AttachDebugger(IDebugger debugger) + { + try + { + ((Script)this).AttachDebugger(debugger); + } + catch (Exception e) + { + Log.Debug(e.Message); + } + } + + public new DynValue Call(DynValue function) + { + try + { + return ((Script)this).Call(function); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue Call(object function) + { + try + { + return ((Script)this).Call(function); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue Call(object function, params object[] args) + { + try + { + return ((Script)this).Call(function, args); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue Call(DynValue function, params DynValue[] args) + { + try + { + return ((Script)this).Call(function, args); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue Call(DynValue function, params object[] args) + { + try + { + return ((Script)this).Call(function, args); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue CreateCoroutine(DynValue function) + { + try + { + return ((Script)this).CreateCoroutine(function); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue CreateCoroutine(object function) + { + try + { + return ((Script)this).CreateCoroutine(function); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue DoString(string code, Table globalContext = null) + { + try + { + return ((Script)this).DoString(code, globalContext); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new DynValue DoFile(string filename, Table globalContext = null) + { + try + { + return ((Script)this).DoFile(filename, globalContext); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new void Dump(DynValue function, Stream stream) + { + try + { + ((Script)this).Dump(function, stream); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + } + } + + public new DynValue RequireModule(string modname, Table globalContext = null) + { + try + { + return ((Script)this).RequireModule(modname, globalContext); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + return null; + } + } + + public new void SetTypeMetatable(DataType type, Table metatable) + { + try + { + ((Script)this).SetTypeMetatable(type, metatable); + } + catch (Exception e) + { + if (e is InterpreterException) + Log.Debug(((InterpreterException)e).DecoratedMessage); + else + Log.Debug(e.Message); + } + } + } +} diff --git a/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs b/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs b/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs b/FFXIVClassic Map Server/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs deleted file mode 100644 index e69de29b..00000000 diff --git a/FFXIVClassic Map Server/packets/BasePacket.cs b/FFXIVClassic Map Server/packets/BasePacket.cs index ae9b5700..ef2597e0 100644 --- a/FFXIVClassic Map Server/packets/BasePacket.cs +++ b/FFXIVClassic Map Server/packets/BasePacket.cs @@ -4,6 +4,7 @@ using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using FFXIVClassic.Common; +using NLog; namespace FFXIVClassic_Map_Server.packets { @@ -19,7 +20,9 @@ namespace FFXIVClassic_Map_Server.packets public ulong timestamp; //Miliseconds } - public class BasePacket{ + public class BasePacket + { + public static Logger Log = LogManager.GetCurrentClassLogger(); public const int TYPE_ZONE = 1; public const int TYPE_CHAT = 2; @@ -335,7 +338,7 @@ namespace FFXIVClassic_Map_Server.packets // todo: create new target for colourful packet logging //Console.BackgroundColor = ConsoleColor.DarkYellow; - Program.Log.Debug("IsAuth: {0} IsEncrypted: {1}, Size: 0x{2:X}, NumSubpackets: {3}{4}{5}", header.isAuthenticated, header.isCompressed, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); + Log.Debug("IsAuth: {0} IsEncrypted: {1}, Size: 0x{2:X}, NumSubpackets: {3}{4}{5}", header.isAuthenticated, header.isCompressed, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); foreach (SubPacket sub in GetSubpackets()) { diff --git a/FFXIVClassic Map Server/packets/SubPacket.cs b/FFXIVClassic Map Server/packets/SubPacket.cs index e4b28170..bd432915 100644 --- a/FFXIVClassic Map Server/packets/SubPacket.cs +++ b/FFXIVClassic Map Server/packets/SubPacket.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.InteropServices; using FFXIVClassic.Common; +using NLog; namespace FFXIVClassic_Map_Server.packets { @@ -26,6 +27,7 @@ namespace FFXIVClassic_Map_Server.packets public class SubPacket { + public static Logger Log = LogManager.GetCurrentClassLogger(); public const int SUBPACKET_SIZE = 0x10; public const int GAMEMESSAGE_SIZE = 0x10; @@ -143,15 +145,15 @@ namespace FFXIVClassic_Map_Server.packets // todo: create new target for colourful packet logging //Console.BackgroundColor = ConsoleColor.DarkRed; - Program.Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); + Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); if (header.type == 0x03) { - Program.Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); + Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); //Console.BackgroundColor = ConsoleColor.DarkMagenta; - Program.Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); + Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); } //Console.BackgroundColor = ConsoleColor.Black; diff --git a/data/scripts/commands/gm/delcurrency.lua b/data/scripts/commands/gm/delcurrency.lua new file mode 100644 index 00000000..4eaaf4fe --- /dev/null +++ b/data/scripts/commands/gm/delcurrency.lua @@ -0,0 +1,37 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "sssss", + description = "removes from , currency is removed from user if is nil", +} + +function onTrigger(player, argc, currency, qty, location, name, lastName) + local sender = "[delcurrency] "; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + if player then + currency = tonumber(currency) or nil; + qty = 1; + location = INVENTORY_CURRENCY; + + local removed = player:GetInventory(location):removecurrency(currency, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to remove currency"; + + if currency and removed then + message = string.format("removed currency %u from %s", currency, player:GetName()); + end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to remove currency, ensure player name is valid."); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/delitem.lua b/data/scripts/commands/gm/delitem.lua new file mode 100644 index 00000000..90c89082 --- /dev/null +++ b/data/scripts/commands/gm/delitem.lua @@ -0,0 +1,37 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "sssss", + description = "removes from for . and are optional, item is removed from user if is nil", +} + +function onTrigger(player, argc, item, qty, location, name, lastName) + local sender = "[delitem] "; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + if player then + item = tonumber(item) or nil; + qty = tonumber(qty) or 1; + location = tonumber(itemtype) or INVENTORY_NORMAL; + + local removed = player:GetInventory(location):removeItem(item, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to remove item"; + + if item and removed then + message = string.format("removed item %u from %s", item, player:GetName()); + end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to remove item, ensure player name is valid."); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/delkeyitem.lua b/data/scripts/commands/gm/delkeyitem.lua new file mode 100644 index 00000000..66ad8549 --- /dev/null +++ b/data/scripts/commands/gm/delkeyitem.lua @@ -0,0 +1,37 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "ssss", + description = "removes from , keyitem is removed from user if is nil", +} + +function onTrigger(player, argc, keyitem, qty, name, lastName) + local sender = "[delkeyitem] "; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + if player then + keyitem = tonumber(keyitem) or nil; + qty = 1; + location = INVENTORY_KEYITEMS; + + local removed = player:GetInventory(location):removeItem(item, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to remove keyitem"; + + if keyitem and removed then + message = string.format("removed keyitem %u from %s", keyitem, player:GetName()); + end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to remove keyitem, ensure player name is valid."); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/givecurrency.lua b/data/scripts/commands/gm/givecurrency.lua new file mode 100644 index 00000000..fea8f5fd --- /dev/null +++ b/data/scripts/commands/gm/givecurrency.lua @@ -0,0 +1,37 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "sss", + description = "adds to self or .", +} + +function onTrigger(player, argc, currency, name, lastName) + local sender = "[givecurrency] "; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + if player then + currency = tonumber(currency) or nil; + qty = 1; + location = INVENTORY_CURRENCY; + + local added = player:GetInventory(location):AddItem(currency, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to add currency"; + + if currency and added then + message = string.format("added currency %u to %s", currency, player:GetName()); + end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to add currency, ensure player name is valid."); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/giveitem.lua b/data/scripts/commands/gm/giveitem.lua index 84ae4f8f..47c94a57 100644 --- a/data/scripts/commands/gm/giveitem.lua +++ b/data/scripts/commands/gm/giveitem.lua @@ -2,21 +2,35 @@ require("global"); properties = { permissions = 0, - parameters = "ssss", + parameters = "sssss", description = "adds to for . and are optional, item is added to user if is nil", } -function onTrigger(player, argc, item, qty, location, target) +function onTrigger(player, argc, item, qty, location, name, lastName) local sender = "[giveitem] "; - player = GetWorldManager():GetPCInWorld(target) or player; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + if player then item = tonumber(item) or nil; qty = tonumber(qty) or 1; location = tonumber(itemtype) or INVENTORY_NORMAL; + local added = player:GetInventory(location):AddItem(item, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to add item"; - 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()); + if item and added then + message = string.format("added item %u to %s", item, player:GetName()); end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to add item, ensure player name is valid."); end; end; \ No newline at end of file diff --git a/data/scripts/commands/gm/givekeyitem.lua b/data/scripts/commands/gm/givekeyitem.lua new file mode 100644 index 00000000..af8aca70 --- /dev/null +++ b/data/scripts/commands/gm/givekeyitem.lua @@ -0,0 +1,37 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "sss", + description = "adds to self or .", +} + +function onTrigger(player, argc, keyitem, name, lastName) + local sender = "[givekeyitem] "; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + if player then + keyitem = tonumber(keyitem) or nil; + qty = 1; + location = INVENTORY_KEYITEMS; + + local added = player:GetInventory(location):AddItem(keyitem, qty); + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local message = "unable to add keyitem"; + + if keyitem and added then + message = string.format("added keyitem %u to %s", keyitem, player:GetName()); + end + player:SendMessage(messageID, sender, message); + print(message); + else + print(sender.."unable to add keyitem, ensure player name is valid."); + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/graphic.lua b/data/scripts/commands/gm/graphic.lua index 19a28c5d..c577f305 100644 --- a/data/scripts/commands/gm/graphic.lua +++ b/data/scripts/commands/gm/graphic.lua @@ -1,8 +1,7 @@ properties = { permissions = 0, parameters = "sssss", - description = [[changes appearance for equipment in . Parameters: , - idk what any of those mean either]], + description = "changes appearance for equipment in . Parameters: , (idk what any of those mean either)", } function onTrigger(player, argc, slot, wId, eId, vId, cId) diff --git a/data/scripts/commands/gm/command - Copy (7).lua b/data/scripts/commands/gm/property.lua similarity index 100% rename from data/scripts/commands/gm/command - Copy (7).lua rename to data/scripts/commands/gm/property.lua diff --git a/data/scripts/commands/gm/reloadzone.lua b/data/scripts/commands/gm/reloadzone.lua index 35db5d1e..1db18069 100644 --- a/data/scripts/commands/gm/reloadzone.lua +++ b/data/scripts/commands/gm/reloadzone.lua @@ -7,17 +7,26 @@ properties = { } function onTrigger(player, argc, zone) - if not zone or tonumber(zone) == 0 then - printf("%s is not a valid zone!", zone); + if not player and not zone or tonumber(zone) == 0 then + printf("No valid zone specified!"); return; end; + local sender = "[reloadzones] "; + zone = tonumber(zone); if player then - local messageID = MSG_TYPE_SYSTEM_ERROR; + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + zone = zone or player:GetZoneID(); player:SendMessage(messageID, "[reloadzones] ", string.format("Reloading zone: %u", zone)); + --[[ todo: get this working legit + player:GetZone():Clear(); + player:GetZone():AddActorToZone(player); + player:SendInstanceUpdate(); + ]] end; GetWorldManager():ReloadZone(zone); + printf("%s reloaded zone %u", sender, zone); end; \ No newline at end of file diff --git a/data/scripts/commands/gm/test.lua b/data/scripts/commands/gm/test.lua deleted file mode 100644 index 6b0221b7..00000000 --- a/data/scripts/commands/gm/test.lua +++ /dev/null @@ -1,9 +0,0 @@ -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 index 01b689fb..4fa2c2b9 100644 --- a/data/scripts/commands/gm/warp.lua +++ b/data/scripts/commands/gm/warp.lua @@ -3,20 +3,21 @@ require("global"); properties = { permissions = 0, parameters = "sssssss", - description = [[ + description = +[[ | | . ]], } -function onTrigger(player, argc, p1, p2, p3, p4, privateArea, firstName, lastName) +function onTrigger(player, argc, p1, p2, p3, p4, privateArea, name, lastName) - if firstName then + if name then if lastName then - player = GetWorldManager():GetPCInWorld(firstName.." "..lastName) or nil; + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; else - player = GetWorldManager():GetPCInWorld(firstName) or nil; + player = GetWorldManager():GetPCInWorld(name) or nil; end; end; @@ -60,7 +61,7 @@ function onTrigger(player, argc, p1, p2, p3, p4, privateArea, firstName, lastNam 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); + worldManager:DoZoneChange(player, zone, privateArea, 0x02, x, y, z, 0.00); end else diff --git a/data/scripts/commands/gm/weather.lua b/data/scripts/commands/gm/weather.lua new file mode 100644 index 00000000..e1fd6703 --- /dev/null +++ b/data/scripts/commands/gm/weather.lua @@ -0,0 +1,30 @@ +require("global"); + +properties = { + permissions = 0, + parameters = "ssss", + description = "usage: .", +} + +function onTrigger(player, argc, weather, updateTime, zonewide) + -- todo: change weather + local messageID = MESSAGE_TYPE_SYSTEM_ERROR; + local sender = "[weather] "; + local message = "unable to change weather"; + + if player then + weather = tonumber(weather) or 0; + updateTime = tonumber(updateTime) or 0; + zonewide = tonumber(zonewide) or 0; + message = "changed weather to %u "; + if zonewide ~= 0 then + message = string.format(message.."for zone %u", player:GetZoneID()); + else + message = string.format(message.."%s", player:GetName()); + end; + -- weatherid, updateTime + player:GetZone():ChangeWeather(weather, updateTime, player, zonewide ~= 0); + player:SendMessage(messageID, sender, message); + end; + print(sender..message); +end; \ No newline at end of file diff --git a/data/scripts/global.lua b/data/scripts/global.lua index d79ae0d8..15de27dd 100644 --- a/data/scripts/global.lua +++ b/data/scripts/global.lua @@ -57,5 +57,9 @@ INVENTORY_EQUIPMENT_OTHERPLAYER = 0x00F9; --Max 0x23 function printf(s, ...) - print(s:format(...)); + if ... then + print(s:format(...)); + else + print(s); + end; end; \ No newline at end of file From 0aac675b30e6a61e7f82385aae7923721cd30afe Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Mon, 20 Jun 2016 19:21:19 +0100 Subject: [PATCH 03/10] cleaned up previous commit --- FFXIVClassic Common Class Lib/Sql.cs | 72 ++----------------- FFXIVClassic Common Class Lib/packages.config | 2 +- .../FFXIVClassic Lobby Server.csproj | 6 +- FFXIVClassic Lobby Server/NLog.config | 5 +- FFXIVClassic Lobby Server/app.config | 16 ++--- FFXIVClassic Lobby Server/packages.config | 2 +- FFXIVClassic Map Server/App.config | 20 +++--- .../FFXIVClassic Map Server.csproj | 4 +- FFXIVClassic Map Server/NLog.config | 3 +- FFXIVClassic Map Server/packages.config | 2 +- data/lobby_config.ini | 2 +- data/map_config.ini | 2 +- 12 files changed, 41 insertions(+), 95 deletions(-) diff --git a/FFXIVClassic Common Class Lib/Sql.cs b/FFXIVClassic Common Class Lib/Sql.cs index fcad7791..2de92bc0 100644 --- a/FFXIVClassic Common Class Lib/Sql.cs +++ b/FFXIVClassic Common Class Lib/Sql.cs @@ -5,76 +5,16 @@ using System.Text; using System.Threading.Tasks; using MySql.Data.MySqlClient; using NLog; +using System.Data; +using System.Data.Common; namespace FFXIVClassic.Common { - /* - class SqlCommand + // todo: + // havent decided whether it's worth wrapping every sql class + // so i'll just leave it with logger for now + public class Sql { public static Logger Log = LogManager.GetCurrentClassLogger(); - - public SqlCommand() - { - - } - - public SqlCommand(string cmdText) - { - try - { - MySqlCommand.MySqlCommand(""); - } - } - public SqlCommand(string cmdText, MySqlConnection connection); - public SqlCommand(string cmdText, MySqlConnection connection, MySqlTransaction transaction); - - ~SqlCommand() - { - - } - - public int CacheAge { get; set; } - - public string CommandText { get; set; } - public int CommandTimeout { get; set; } - - public CommandType CommandType { get; set; } - - public MySqlConnection Connection { get; set; } - - public bool DesignTimeVisible { get; set; } - public bool EnableCaching { get; set; } - - public bool IsPrepared { get; } - - public long LastInsertedId { get; } - - public MySqlParameterCollection Parameters { get; } - - public MySqlTransaction Transaction { get; set; } - public UpdateRowSource UpdatedRowSource { get; set; } - protected DbConnection DbConnection { get; set; } - protected DbParameterCollection DbParameterCollection { get; } - protected DbTransaction DbTransaction { get; set; } - - public IAsyncResult BeginExecuteNonQuery(); - public IAsyncResult BeginExecuteNonQuery(AsyncCallback callback, object stateObject); - public IAsyncResult BeginExecuteReader(); - public IAsyncResult BeginExecuteReader(CommandBehavior behavior); - public void Cancel(); - public SqlCommand Clone(); - public MySqlParameter CreateParameter(); - public void Dispose(); - public int EndExecuteNonQuery(IAsyncResult asyncResult); - public MySqlDataReader EndExecuteReader(IAsyncResult result); - public int ExecuteNonQuery(); - public MySqlDataReader ExecuteReader(); - public MySqlDataReader ExecuteReader(CommandBehavior behavior); - public object ExecuteScalar(); - public void Prepare(); - protected DbParameter CreateDbParameter(); - protected void Dispose(bool disposing); - protected DbDataReader ExecuteDbDataReader(CommandBehavior behavior); } - */ } diff --git a/FFXIVClassic Common Class Lib/packages.config b/FFXIVClassic Common Class Lib/packages.config index b2de2ed0..8b2d1420 100644 --- a/FFXIVClassic Common Class Lib/packages.config +++ b/FFXIVClassic Common Class Lib/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj index 550b75a0..8f83df96 100644 --- a/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj +++ b/FFXIVClassic Lobby Server/FFXIVClassic Lobby Server.csproj @@ -58,8 +58,9 @@ ..\FFXIVClassic Common Class Lib\bin\Debug\FFXIVClassic.Common.dll - - ..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll + True ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll @@ -112,6 +113,7 @@ Always + Designer diff --git a/FFXIVClassic Lobby Server/NLog.config b/FFXIVClassic Lobby Server/NLog.config index c152c074..8495609d 100644 --- a/FFXIVClassic Lobby Server/NLog.config +++ b/FFXIVClassic Lobby Server/NLog.config @@ -29,7 +29,10 @@ --> - + + + + diff --git a/FFXIVClassic Lobby Server/app.config b/FFXIVClassic Lobby Server/app.config index d0ac62a0..143834c2 100644 --- a/FFXIVClassic Lobby Server/app.config +++ b/FFXIVClassic Lobby Server/app.config @@ -1,9 +1,9 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/packages.config b/FFXIVClassic Lobby Server/packages.config index 5a3427bf..dd879142 100644 --- a/FFXIVClassic Lobby Server/packages.config +++ b/FFXIVClassic Lobby Server/packages.config @@ -2,7 +2,7 @@ - + diff --git a/FFXIVClassic Map Server/App.config b/FFXIVClassic Map Server/App.config index c45a8c71..63198b4c 100644 --- a/FFXIVClassic Map Server/App.config +++ b/FFXIVClassic Map Server/App.config @@ -1,11 +1,11 @@ - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index f178f04e..c5c79140 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -49,8 +49,8 @@ ..\packages\MoonSharp.1.2.1.0\lib\net40-client\MoonSharp.Interpreter.dll - - ..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll + + ..\packages\MySql.Data.6.9.8\lib\net45\MySql.Data.dll True diff --git a/FFXIVClassic Map Server/NLog.config b/FFXIVClassic Map Server/NLog.config index 839421a0..a12d0fdc 100644 --- a/FFXIVClassic Map Server/NLog.config +++ b/FFXIVClassic Map Server/NLog.config @@ -32,7 +32,8 @@ - + + diff --git a/FFXIVClassic Map Server/packages.config b/FFXIVClassic Map Server/packages.config index 6d8ab227..fa384c55 100644 --- a/FFXIVClassic Map Server/packages.config +++ b/FFXIVClassic Map Server/packages.config @@ -3,7 +3,7 @@ - + diff --git a/data/lobby_config.ini b/data/lobby_config.ini index 2251736f..f8aa676b 100644 --- a/data/lobby_config.ini +++ b/data/lobby_config.ini @@ -8,4 +8,4 @@ host=127.0.0.1 port=3306 database=ffxiv_server username=root -password= +password=root diff --git a/data/map_config.ini b/data/map_config.ini index 2251736f..f8aa676b 100644 --- a/data/map_config.ini +++ b/data/map_config.ini @@ -8,4 +8,4 @@ host=127.0.0.1 port=3306 database=ffxiv_server username=root -password= +password=root From 590ad3e002e1c6c18aad163c6643c29574503d90 Mon Sep 17 00:00:00 2001 From: deviltti Date: Tue, 21 Jun 2016 18:52:20 -0400 Subject: [PATCH 04/10] Reimplemented ConsoleColor for packets in NLog. --- FFXIVClassic Map Server/NLog.config | 34 ++- FFXIVClassic Map Server/packets/BasePacket.cs | 222 +++++++++--------- FFXIVClassic Map Server/packets/SubPacket.cs | 90 +++---- 3 files changed, 184 insertions(+), 162 deletions(-) diff --git a/FFXIVClassic Map Server/NLog.config b/FFXIVClassic Map Server/NLog.config index a12d0fdc..d989ae88 100644 --- a/FFXIVClassic Map Server/NLog.config +++ b/FFXIVClassic Map Server/NLog.config @@ -1,16 +1,17 @@ - + + + internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log"> - + - + - - - - - - + + + + + + + - - + + - + - - + - - - - - - - - + + + + + + + + + - - - - - + + + + - + \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/packets/BasePacket.cs b/FFXIVClassic Lobby Server/packets/BasePacket.cs index 332e7d6f..075ec2b6 100644 --- a/FFXIVClassic Lobby Server/packets/BasePacket.cs +++ b/FFXIVClassic Lobby Server/packets/BasePacket.cs @@ -1,14 +1,14 @@ using System; using System.Collections.Generic; -using System.Runtime.InteropServices; using System.Diagnostics; -using FFXIVClassic.Common; using System.IO; +using System.Runtime.InteropServices; +using FFXIVClassic.Common; using NLog; +using NLog.Targets; namespace FFXIVClassic_Lobby_Server.packets { - [StructLayout(LayoutKind.Sequential)] public struct BasePacketHeader { @@ -22,25 +22,25 @@ namespace FFXIVClassic_Lobby_Server.packets public class BasePacket { - public static Logger Log = LogManager.GetCurrentClassLogger(); public const int TYPE_ZONE = 1; public const int TYPE_CHAT = 2; public const int BASEPACKET_SIZE = 0x10; - - public BasePacketHeader header; + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); public byte[] data; + public BasePacketHeader header; + //Loads a sniffed packet from a file - public unsafe BasePacket(String path) + public unsafe BasePacket(string path) { - byte[] bytes = File.ReadAllBytes(path); + var bytes = File.ReadAllBytes(path); if (bytes.Length < BASEPACKET_SIZE) throw new OverflowException("Packet Error: Packet was too small"); fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } if (bytes.Length < header.packetSize) @@ -65,7 +65,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } if (bytes.Length < header.packetSize) @@ -84,7 +84,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[offset]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } int packetSize = header.packetSize; @@ -106,9 +106,9 @@ namespace FFXIVClassic_Lobby_Server.packets public List GetSubpackets() { - List subpackets = new List(header.numSubpackets); + var subpackets = new List(header.numSubpackets); - int offset = 0; + var offset = 0; while (offset < data.Length) subpackets.Add(new SubPacket(data, ref offset)); @@ -116,7 +116,7 @@ namespace FFXIVClassic_Lobby_Server.packets return subpackets; } - public unsafe static BasePacketHeader GetHeader(byte[] bytes) + public static unsafe BasePacketHeader GetHeader(byte[] bytes) { BasePacketHeader header; if (bytes.Length < BASEPACKET_SIZE) @@ -124,7 +124,7 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[0]) { - header = (BasePacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); + header = (BasePacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(BasePacketHeader)); } return header; @@ -132,10 +132,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetHeaderBytes() { - int size = Marshal.SizeOf(header); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(header); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(header, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -144,7 +144,7 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetPacketBytes() { - byte[] outBytes = new byte[header.packetSize]; + var outBytes = new byte[header.packetSize]; Array.Copy(GetHeaderBytes(), 0, outBytes, 0, BASEPACKET_SIZE); Array.Copy(data, 0, outBytes, BASEPACKET_SIZE, data.Length); return outBytes; @@ -153,16 +153,17 @@ namespace FFXIVClassic_Lobby_Server.packets //Replaces all instances of the sniffed actorID with the given one public void ReplaceActorID(uint actorID) { - using (MemoryStream mem = new MemoryStream(data)) + using (var mem = new MemoryStream(data)) { - using (BinaryWriter binWriter = new BinaryWriter(mem)) + using (var binWriter = new BinaryWriter(mem)) { - using (BinaryReader binreader = new BinaryReader(mem)) + using (var binreader = new BinaryReader(mem)) { while (binreader.BaseStream.Position + 4 < data.Length) { - uint read = binreader.ReadUInt32(); - if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID + var read = binreader.ReadUInt32(); + if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || + read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID { binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); binWriter.Write(actorID); @@ -176,15 +177,15 @@ namespace FFXIVClassic_Lobby_Server.packets //Replaces all instances of the sniffed actorID with the given one public void ReplaceActorID(uint fromActorID, uint actorID) { - using (MemoryStream mem = new MemoryStream(data)) + using (var mem = new MemoryStream(data)) { - using (BinaryWriter binWriter = new BinaryWriter(mem)) + using (var binWriter = new BinaryWriter(mem)) { - using (BinaryReader binreader = new BinaryReader(mem)) + using (var binreader = new BinaryReader(mem)) { while (binreader.BaseStream.Position + 4 < data.Length) { - uint read = binreader.ReadUInt32(); + var read = binreader.ReadUInt32(); if (read == fromActorID) //Original ID { binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); @@ -196,49 +197,65 @@ namespace FFXIVClassic_Lobby_Server.packets } } + public void DebugPrintPacket() + { +#if DEBUG + logger.ColorDebug( + string.Format("IsAuth:{0} Size:0x{1:X}, NumSubpackets:{2}{3}{4}", + header.isAuthenticated, header.packetSize, header.numSubpackets, + Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkYellow); + + foreach (var sub in GetSubpackets()) + { + sub.DebugPrintSubPacket(); + } +#endif + } + #region Utility Functions + public static BasePacket CreatePacket(List subpackets, bool isAuthed, bool isEncrypted) { //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); byte[] data = null; - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)subpackets.Count; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = (ushort) subpackets.Count; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size - foreach (SubPacket subpacket in subpackets) + foreach (var subpacket in subpackets) header.packetSize += subpacket.header.subpacketSize; data = new byte[header.packetSize - 0x10]; //Add Subpackets - int offset = 0; - foreach (SubPacket subpacket in subpackets) + var offset = 0; + foreach (var subpacket in subpackets) { - byte[] subpacketData = subpacket.GetBytes(); + var subpacketData = subpacket.GetBytes(); Array.Copy(subpacketData, 0, data, offset, subpacketData.Length); - offset += (ushort)subpacketData.Length; + offset += (ushort) subpacketData.Length; } Debug.Assert(data != null && offset == data.Length && header.packetSize == 0x10 + offset); - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static BasePacket CreatePacket(SubPacket subpacket, bool isAuthed, bool isEncrypted) { //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); byte[] data = null; - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)1; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); @@ -248,42 +265,41 @@ namespace FFXIVClassic_Lobby_Server.packets data = new byte[header.packetSize - 0x10]; //Add Subpackets - byte[] subpacketData = subpacket.GetBytes(); + var subpacketData = subpacket.GetBytes(); Array.Copy(subpacketData, 0, data, 0, subpacketData.Length); Debug.Assert(data != null); - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static BasePacket CreatePacket(byte[] data, bool isAuthed, bool isEncrypted) { - Debug.Assert(data != null); //Create Header - BasePacketHeader header = new BasePacketHeader(); + var header = new BasePacketHeader(); - header.isAuthenticated = isAuthed ? (byte)1 : (byte)0; - header.isEncrypted = isEncrypted ? (byte)1 : (byte)0; - header.numSubpackets = (ushort)1; + header.isAuthenticated = isAuthed ? (byte) 1 : (byte) 0; + header.isEncrypted = isEncrypted ? (byte) 1 : (byte) 0; + header.numSubpackets = 1; header.packetSize = BASEPACKET_SIZE; header.timestamp = Utils.MilisUnixTimeStampUTC(); //Get packet size - header.packetSize += (ushort)data.Length; + header.packetSize += (ushort) data.Length; - BasePacket packet = new BasePacket(header, data); + var packet = new BasePacket(header, data); return packet; } public static unsafe void EncryptPacket(Blowfish blowfish, BasePacket packet) { - byte[] data = packet.data; + var data = packet.data; int size = packet.header.packetSize; - int offset = 0; + var offset = 0; while (offset < data.Length) { if (data.Length < offset + SubPacket.SUBPACKET_SIZE) @@ -292,7 +308,7 @@ namespace FFXIVClassic_Lobby_Server.packets SubPacketHeader header; fixed (byte* pdata = &data[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (data.Length < offset + header.subpacketSize) @@ -302,15 +318,14 @@ namespace FFXIVClassic_Lobby_Server.packets offset += header.subpacketSize; } - } public static unsafe void DecryptPacket(Blowfish blowfish, ref BasePacket packet) { - byte[] data = packet.data; + var data = packet.data; int size = packet.header.packetSize; - int offset = 0; + var offset = 0; while (offset < data.Length) { if (data.Length < offset + SubPacket.SUBPACKET_SIZE) @@ -319,7 +334,7 @@ namespace FFXIVClassic_Lobby_Server.packets SubPacketHeader header; fixed (byte* pdata = &data[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (data.Length < offset + header.subpacketSize) @@ -330,24 +345,17 @@ namespace FFXIVClassic_Lobby_Server.packets offset += header.subpacketSize; } } + #endregion - - public void DebugPrintPacket() - { -#if DEBUG - // todo: create new target for colourful packet logging - //Console.BackgroundColor = ConsoleColor.DarkYellow; - - Log.Debug("IsAuth: {0} Size: 0x{1:X}, NumSubpackets: {2}{3}{4}", header.isAuthenticated, header.packetSize, header.numSubpackets, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); - - foreach (SubPacket sub in GetSubpackets()) - { - sub.DebugPrintSubPacket(); - } - - //Console.BackgroundColor = ConsoleColor.Black; -#endif - } - } -} + + public static class LoggerExtensions + { + public static void ColorDebug(this Logger logger, string message, ConsoleOutputColor color) + { + var logEvent = new LogEventInfo(LogLevel.Debug, logger.Name, message); + logEvent.Properties["color"] = (int) color; + logger.Log(logEvent); + } + } +} \ No newline at end of file diff --git a/FFXIVClassic Lobby Server/packets/SubPacket.cs b/FFXIVClassic Lobby Server/packets/SubPacket.cs index 0dcb526b..19f0a705 100644 --- a/FFXIVClassic Lobby Server/packets/SubPacket.cs +++ b/FFXIVClassic Lobby Server/packets/SubPacket.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using FFXIVClassic.Common; using NLog; +using NLog.Targets; namespace FFXIVClassic_Lobby_Server.packets { @@ -27,13 +28,13 @@ namespace FFXIVClassic_Lobby_Server.packets public class SubPacket { - public static Logger Log = LogManager.GetCurrentClassLogger(); public const int SUBPACKET_SIZE = 0x10; public const int GAMEMESSAGE_SIZE = 0x10; + private static readonly Logger logger = LogManager.GetCurrentClassLogger(); + public byte[] data; + public GameMessageHeader gameMessage; public SubPacketHeader header; - public GameMessageHeader gameMessage; - public byte[] data; public unsafe SubPacket(byte[] bytes, ref int offset) { @@ -42,14 +43,15 @@ namespace FFXIVClassic_Lobby_Server.packets fixed (byte* pdata = &bytes[offset]) { - header = (SubPacketHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); + header = (SubPacketHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(SubPacketHeader)); } if (header.type == 0x3) { fixed (byte* pdata = &bytes[offset + SUBPACKET_SIZE]) { - gameMessage = (GameMessageHeader)Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader)); + gameMessage = + (GameMessageHeader) Marshal.PtrToStructure(new IntPtr(pdata), typeof(GameMessageHeader)); } } @@ -72,8 +74,8 @@ namespace FFXIVClassic_Lobby_Server.packets public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data) { - this.header = new SubPacketHeader(); - this.gameMessage = new GameMessageHeader(); + header = new SubPacketHeader(); + gameMessage = new GameMessageHeader(); gameMessage.opcode = opcode; header.sourceId = sourceId; @@ -89,13 +91,13 @@ namespace FFXIVClassic_Lobby_Server.packets this.data = data; - header.subpacketSize = (ushort)(SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length); + header.subpacketSize = (ushort) (SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length); } public SubPacket(SubPacket original, uint newTargetId) { - this.header = new SubPacketHeader(); - this.gameMessage = original.gameMessage; + header = new SubPacketHeader(); + gameMessage = original.gameMessage; header.subpacketSize = original.header.subpacketSize; header.type = original.header.type; header.sourceId = original.header.sourceId; @@ -105,10 +107,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetHeaderBytes() { - int size = Marshal.SizeOf(header); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(header); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(header, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -117,10 +119,10 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetGameMessageBytes() { - int size = Marshal.SizeOf(gameMessage); - byte[] arr = new byte[size]; + var size = Marshal.SizeOf(gameMessage); + var arr = new byte[size]; - IntPtr ptr = Marshal.AllocHGlobal(size); + var ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(gameMessage, ptr, true); Marshal.Copy(ptr, arr, 0, size); Marshal.FreeHGlobal(ptr); @@ -129,7 +131,7 @@ namespace FFXIVClassic_Lobby_Server.packets public byte[] GetBytes() { - byte[] outBytes = new byte[header.subpacketSize]; + var outBytes = new byte[header.subpacketSize]; Array.Copy(GetHeaderBytes(), 0, outBytes, 0, SUBPACKET_SIZE); if (header.type == 0x3) @@ -142,17 +144,20 @@ namespace FFXIVClassic_Lobby_Server.packets public void DebugPrintSubPacket() { #if DEBUG - // todo: create new target for colourful packet logging - Log.Debug("Size: 0x{0:X}{1}{2}", header.subpacketSize, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())); - + logger.ColorDebug( + string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, header.type, + Environment.NewLine, + Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkRed); + if (header.type == 0x03) { - Log.Debug("Opcode: 0x{0:X}{1}{2}", gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE)); - } + logger.ColorDebug(Utils.ByteArrayToHex(GetGameMessageBytes(), SUBPACKET_SIZE), + ConsoleOutputColor.DarkRed); - Log.Debug("Data: {0}{1}", Environment.NewLine, Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE)); + logger.ColorDebug(Utils.ByteArrayToHex(data, SUBPACKET_SIZE + GAMEMESSAGE_SIZE), + ConsoleOutputColor.DarkMagenta); + } #endif } - } -} +} \ No newline at end of file diff --git a/FFXIVClassic Map Server/NLog.config b/FFXIVClassic Map Server/NLog.config index d989ae88..1260ebf7 100644 --- a/FFXIVClassic Map Server/NLog.config +++ b/FFXIVClassic Map Server/NLog.config @@ -34,7 +34,9 @@ + layout="[${date:format=MM/dd/yyyy HH\:mm\:ss}][${uppercase:${level}}]${message}" /> + @@ -50,7 +52,8 @@ - + + + layout="[${date:format=dd MMM yyyy HH\:mm\:ss.fff}] [${uppercase:${level}}] ${message}" /> + layout="[${date:format=dd MMM yyyy HH\:mm\:ss.fff}] [${uppercase:${level}}] ${message}" /> + layout="[${date:format=dd MMM yyyy HH\:mm\:ss.fff}] [${uppercase:${level}}] ${message}" /> + layout="[${date:format=dd MMM yyyy HH\:mm\:ss.fff}] [${uppercase:${level}}] ${message}" /> Date: Tue, 21 Jun 2016 21:52:40 -0400 Subject: [PATCH 08/10] demo...srs? --- FFXIVClassic Lobby Server/packets/SubPacket.cs | 2 +- FFXIVClassic Map Server/packets/SubPacket.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FFXIVClassic Lobby Server/packets/SubPacket.cs b/FFXIVClassic Lobby Server/packets/SubPacket.cs index 19f0a705..d684a087 100644 --- a/FFXIVClassic Lobby Server/packets/SubPacket.cs +++ b/FFXIVClassic Lobby Server/packets/SubPacket.cs @@ -145,7 +145,7 @@ namespace FFXIVClassic_Lobby_Server.packets { #if DEBUG logger.ColorDebug( - string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, header.type, + string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkRed); diff --git a/FFXIVClassic Map Server/packets/SubPacket.cs b/FFXIVClassic Map Server/packets/SubPacket.cs index 67ee943e..954e80b1 100644 --- a/FFXIVClassic Map Server/packets/SubPacket.cs +++ b/FFXIVClassic Map Server/packets/SubPacket.cs @@ -145,7 +145,7 @@ namespace FFXIVClassic_Map_Server.packets { #if DEBUG logger.ColorDebug( - string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, header.type, + string.Format("Size:0x{0:X} Opcode:0x{1:X}{2}{3}", header.subpacketSize, gameMessage.opcode, Environment.NewLine, Utils.ByteArrayToHex(GetHeaderBytes())), ConsoleOutputColor.DarkRed); From 30b0d4a97d74bd8c3ca353096baca43cf7b69470 Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Fri, 24 Jun 2016 20:52:30 +0100 Subject: [PATCH 09/10] implemented sendpacket and speed commands - fixed data race on logging in - todo: implement reloadzones, reloaditems, property, property2 --- .../FFXIVClassic Common Class Lib.csproj | 1 + FFXIVClassic Map Server/CommandProcessor.cs | 43 ++----------------- FFXIVClassic Map Server/Database.cs | 2 + FFXIVClassic Map Server/PacketProcessor.cs | 16 ++++--- FFXIVClassic Map Server/Program.cs | 2 +- .../actors/chara/player/Player.cs | 35 +++++++-------- .../dataobjects/ConnectedPlayer.cs | 6 +-- .../packets/send/login/0x7ResponsePacket.cs | 4 +- data/scripts/commands/gm/property.lua | 9 ---- data/scripts/commands/gm/sendpacket.lua | 24 +++++++++++ data/scripts/commands/gm/speed.lua | 13 ++++++ 11 files changed, 74 insertions(+), 81 deletions(-) delete mode 100644 data/scripts/commands/gm/property.lua create mode 100644 data/scripts/commands/gm/sendpacket.lua create mode 100644 data/scripts/commands/gm/speed.lua diff --git a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj index a3fe065d..8c708e5f 100644 --- a/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj +++ b/FFXIVClassic Common Class Lib/FFXIVClassic Common Class Lib.csproj @@ -24,6 +24,7 @@ 4 false false + true pdbonly diff --git a/FFXIVClassic Map Server/CommandProcessor.cs b/FFXIVClassic Map Server/CommandProcessor.cs index 7b0b1359..50985884 100644 --- a/FFXIVClassic Map Server/CommandProcessor.cs +++ b/FFXIVClassic Map Server/CommandProcessor.cs @@ -35,25 +35,6 @@ namespace FFXIVClassic_Map_Server mConnectedPlayerList = playerList; } - public void SendPacket(ConnectedPlayer client, string path) - { - BasePacket packet = new BasePacket(path); - - if (client != null) - { - packet.ReplaceActorID(client.actorID); - client.QueuePacket(packet); - } - else - { - foreach (KeyValuePair entry in mConnectedPlayerList) - { - packet.ReplaceActorID(entry.Value.actorID); - entry.Value.QueuePacket(packet); - } - } - } - public void ChangeProperty(uint id, uint value, string target) { SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target); @@ -87,7 +68,7 @@ namespace FFXIVClassic_Map_Server internal bool DoCommand(string input, ConnectedPlayer client) { - if (!input.Any()) + if (!input.Any() || input.Equals("")) return false; input.Trim(); @@ -102,7 +83,7 @@ namespace FFXIVClassic_Map_Server split = split.Select(temp => temp.ToLower()).ToArray(); // Ignore case on commands - var cmd = split?.ElementAt(0); + var cmd = split[0]; if (cmd.Any()) { @@ -138,6 +119,8 @@ namespace FFXIVClassic_Map_Server if (split.Length >= 1) { + // TODO: reloadzones + #region !reloaditems if (split[0].Equals("reloaditems")) { @@ -151,24 +134,6 @@ namespace FFXIVClassic_Map_Server } #endregion - #region !sendpacket - else if (split[0].Equals("sendpacket")) - { - if (split.Length < 2) - return false; - - try - { - SendPacket(client, "./packets/" + split[1]); - return true; - } - catch (Exception e) - { - Program.Log.Error("Could not load packet: " + e); - } - } - #endregion - #region !property else if (split[0].Equals("property")) { diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 55e1b9fd..823e8b13 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -419,6 +419,8 @@ namespace FFXIVClassic_Map_Server player.oldRotation = player.rotation = reader.GetFloat(4); player.currentMainState = reader.GetUInt16(5); player.zoneId = reader.GetUInt32(6); + player.isZoning = true; + player.zone = Server.GetWorldManager().GetZone(player.zoneId); player.gcCurrent = reader.GetByte(7); player.gcRankLimsa = reader.GetByte(8); player.gcRankGridania = reader.GetByte(9); diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 09b203aa..e1a7719c 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -112,7 +112,7 @@ namespace FFXIVClassic_Map_Server if (packet.header.connectionType == BasePacket.TYPE_ZONE) { - while (!mPlayers.ContainsKey(client.owner)) + while (mPlayers != null && !mPlayers.ContainsKey(client.owner)) { } player = mPlayers[client.owner]; } @@ -127,9 +127,9 @@ namespace FFXIVClassic_Map_Server player.SetConnection(packet.header.connectionType, client); if (packet.header.connectionType == BasePacket.TYPE_ZONE) - Program.Log.Debug("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.GetAddress()); + Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.GetAddress()); else if (packet.header.connectionType == BasePacket.TYPE_CHAT) - Program.Log.Debug("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.GetAddress()); + Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.GetAddress()); //Create player actor reply1.DebugPrintPacket(); @@ -139,12 +139,14 @@ namespace FFXIVClassic_Map_Server } else if (subpacket.header.type == 0x07) { - BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC()); + BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC(), 0x08); //client.QueuePacket(init); } else if (subpacket.header.type == 0x08) - { - //Response, client's current [actorID][time] + { + //Response, client's current [actorID][time] + //BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC(), 0x07); + //client.QueuePacket(init); packet.DebugPrintPacket(); } else if (subpacket.header.type == 0x03) @@ -154,7 +156,7 @@ namespace FFXIVClassic_Map_Server if(mPlayers.ContainsKey(client.owner)) player = mPlayers[client.owner]; - if (player == null) + if (player == null || !player.IsClientConnectionsReady()) return; //Normal Game Opcode diff --git a/FFXIVClassic Map Server/Program.cs b/FFXIVClassic Map Server/Program.cs index bb0020b6..a8bba8eb 100644 --- a/FFXIVClassic Map Server/Program.cs +++ b/FFXIVClassic Map Server/Program.cs @@ -70,7 +70,7 @@ namespace FFXIVClassic_Map_Server { String input = Console.ReadLine(); Log.Info("[Console Input] " + input); - cp.DoCommand(input, null); + cp.DoCommand(input, null); } } diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 190b5156..fe3213e3 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -601,6 +601,21 @@ namespace FFXIVClassic_Map_Server.Actors playerSession.QueuePacket(subpacket, true, false); } + public void SendPacket(string path) + { + try + { + BasePacket packet = new BasePacket(path); + + packet.ReplaceActorID(actorId); + QueuePacket(packet); + } + catch (Exception e) + { + this.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "[SendPacket]", "Unable to send packet."); + } + } + public void BroadcastPacket(SubPacket packet, bool sendToSelf) { if (sendToSelf) @@ -749,26 +764,6 @@ namespace FFXIVClassic_Map_Server.Actors //zone.BroadcastPacketAroundActor(this, worldMasterMessage); } - public void ChangeProperty(uint id, uint value, string target) - { - SetActorPropetyPacket ChangeProperty = new SetActorPropetyPacket(target); - - ChangeProperty.SetTarget(target); - ChangeProperty.AddInt(id, value); - ChangeProperty.AddTarget(); - - /*foreach (KeyValuePair entry in mConnectedPlayerList) - { - SubPacket ChangePropertyPacket = ChangeProperty.BuildPacket((entry.Value.actorID), (entry.Value.actorID)); - - BasePacket packet = BasePacket.CreatePacket(ChangePropertyPacket, true, false); - packet.DebugPrintPacket(); - - entry.Value.QueuePacket(packet); - } - */ - } - public void GraphicChange(uint slot, uint graphicId) { appearanceIds[slot] = graphicId; diff --git a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs index f5eef9a4..19caa56e 100644 --- a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs +++ b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs @@ -70,8 +70,8 @@ namespace FFXIVClassic_Map_Server.dataobjects } public void QueuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted) - { - zoneConnection.QueuePacket(subPacket, isAuthed, isEncrypted); + { + zoneConnection.QueuePacket(subPacket, isAuthed, isEncrypted); } public Player GetActor() @@ -97,7 +97,7 @@ namespace FFXIVClassic_Map_Server.dataobjects } public void UpdatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState) - { + { playerActor.oldPositionX = playerActor.positionX; playerActor.oldPositionY = playerActor.positionY; playerActor.oldPositionZ = playerActor.positionZ; diff --git a/FFXIVClassic Map Server/packets/send/login/0x7ResponsePacket.cs b/FFXIVClassic Map Server/packets/send/login/0x7ResponsePacket.cs index 133fffb5..63d207f9 100644 --- a/FFXIVClassic Map Server/packets/send/login/0x7ResponsePacket.cs +++ b/FFXIVClassic Map Server/packets/send/login/0x7ResponsePacket.cs @@ -5,7 +5,7 @@ namespace FFXIVClassic_Map_Server.packets.send.login { class Login0x7ResponsePacket { - public static BasePacket BuildPacket(uint actorID, uint time) + public static BasePacket BuildPacket(uint actorID, uint time, uint type) { byte[] data = new byte[0x18]; @@ -16,7 +16,7 @@ namespace FFXIVClassic_Map_Server.packets.send.login try { binWriter.Write((short)0x18); - binWriter.Write((short)0x8); + binWriter.Write((short)type); binWriter.Write((uint)0); binWriter.Write((uint)0); binWriter.Write((uint)0xFFFFFD7F); diff --git a/data/scripts/commands/gm/property.lua b/data/scripts/commands/gm/property.lua deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/property.lua +++ /dev/null @@ -1,9 +0,0 @@ -properties = { - permissions = 0, - parameters = "", - description = "", -} - -function onTrigger(player) - -end; \ No newline at end of file diff --git a/data/scripts/commands/gm/sendpacket.lua b/data/scripts/commands/gm/sendpacket.lua new file mode 100644 index 00000000..d506c3b4 --- /dev/null +++ b/data/scripts/commands/gm/sendpacket.lua @@ -0,0 +1,24 @@ +properties = { + permissions = 0, + parameters = "ssss", + description = " ", +} + +function onTrigger(player, argc, path, name, lastName) + local sender = "[sendpacket ]"; + lastName = lastName or ""; + path = "./packets/"..path; + + if name then + if lastName then + player = GetWorldManager():GetPCInWorld(name.." "..lastName) or nil; + else + player = GetWorldManager():GetPCInWorld(name) or nil; + end; + end; + + value = tonumber(value) or 0; + if player and argc > 0 then + player:SendPacket(path) + end; +end; \ No newline at end of file diff --git a/data/scripts/commands/gm/speed.lua b/data/scripts/commands/gm/speed.lua new file mode 100644 index 00000000..90cf537a --- /dev/null +++ b/data/scripts/commands/gm/speed.lua @@ -0,0 +1,13 @@ +properties = { + permissions = 0, + parameters = "sss", + description = " speed", +} + +function onTrigger(player, argc, stop, walk, run) + stop = tonumber(stop) or 0; + walk = tonumber(walk) or 2; + run = tonumber(run) or 5; + + player:ChangeSpeed(stop, walk, run); +end; \ No newline at end of file From 8839e7555734111030970ceb3b8b807b7f1b1618 Mon Sep 17 00:00:00 2001 From: Tahir Akhlaq Date: Fri, 24 Jun 2016 22:14:17 +0100 Subject: [PATCH 10/10] missed some left over files --- data/scripts/commands/gm/command - Copy (2).lua | 9 --------- data/scripts/commands/gm/command - Copy (3).lua | 9 --------- data/scripts/commands/gm/command - Copy (4).lua | 9 --------- data/scripts/commands/gm/command - Copy (5).lua | 9 --------- data/scripts/commands/gm/command - Copy (6).lua | 9 --------- 5 files changed, 45 deletions(-) delete mode 100644 data/scripts/commands/gm/command - Copy (2).lua delete mode 100644 data/scripts/commands/gm/command - Copy (3).lua delete mode 100644 data/scripts/commands/gm/command - Copy (4).lua delete mode 100644 data/scripts/commands/gm/command - Copy (5).lua delete mode 100644 data/scripts/commands/gm/command - Copy (6).lua diff --git a/data/scripts/commands/gm/command - Copy (2).lua b/data/scripts/commands/gm/command - Copy (2).lua deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/command - Copy (2).lua +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/command - Copy (3).lua +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/command - Copy (4).lua +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/command - Copy (5).lua +++ /dev/null @@ -1,9 +0,0 @@ -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 deleted file mode 100644 index 576478bb..00000000 --- a/data/scripts/commands/gm/command - Copy (6).lua +++ /dev/null @@ -1,9 +0,0 @@ -properties = { - permissions = 0, - parameters = "", - description = "", -} - -function onTrigger(player) - -end; \ No newline at end of file