From d989ec2a586585632cdce0b5119170fc0b00fcd1 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 14 Apr 2016 08:30:21 -0400 Subject: [PATCH] Added two callbacks to the Director; onTalked and onCommand. Split the command and event starts and keep track of them separately. --- .../FFXIVClassic Map Server.csproj | 2 + FFXIVClassic Map Server/PacketProcessor.cs | 26 ++++-- FFXIVClassic Map Server/Server.cs | 26 ++++-- FFXIVClassic Map Server/WorldManager.cs | 9 +- .../actors/chara/player/Player.cs | 83 +++++++++++++------ .../actors/director/Director.cs | 19 ++++- .../actors/director/OpeningDirector.cs | 3 +- .../actors/director/WeatherDirector.cs | 4 +- .../director/quest/QuestDirectorMan0L001..cs | 4 +- FFXIVClassic Map Server/actors/quest/Quest.cs | 10 +++ FFXIVClassic Map Server/lua/LuaEngine.cs | 63 +++++++++++++- .../packets/send/_0x10Packet.cs | 31 +++++++ 12 files changed, 227 insertions(+), 53 deletions(-) create mode 100644 FFXIVClassic Map Server/packets/send/_0x10Packet.cs diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 6a861225..b24f70a6 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -102,6 +102,7 @@ + @@ -244,6 +245,7 @@ + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 1c27dec5..83670ee2 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -249,19 +249,27 @@ namespace FFXIVClassic_Lobby_Server break; } */ - player.getActor().eventCurrentOwner = eventStart.scriptOwnerActorID; - player.getActor().eventCurrentStarter = eventStart.triggerName; - //Is it a static actor? If not look in the player's instance - Actor ownerActor = Server.getStaticActors(player.getActor().eventCurrentOwner); + Actor ownerActor = Server.getStaticActors(eventStart.scriptOwnerActorID); + if (ownerActor != null && ownerActor is Command) + { + player.getActor().currentCommand = eventStart.scriptOwnerActorID; + player.getActor().currentCommandName = eventStart.triggerName; + } + else + { + player.getActor().currentEventOwner = eventStart.scriptOwnerActorID; + player.getActor().currentEventName = eventStart.triggerName; + } + if (ownerActor == null) { //Is it a instance actor? - ownerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().eventCurrentOwner); + ownerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().currentEventOwner); if (ownerActor == null) { //Is it a Director? - if (player.getActor().currentDirector != null && player.getActor().eventCurrentOwner == player.getActor().currentDirector.actorId) + if (player.getActor().currentDirector != null && player.getActor().currentEventOwner == player.getActor().currentDirector.actorId) ownerActor = player.getActor().currentDirector; else { @@ -285,12 +293,12 @@ namespace FFXIVClassic_Lobby_Server Log.debug(String.Format("\n===Event UPDATE===\nSource Actor: 0x{0:X}\nCaller Actor: 0x{1:X}\nVal1: 0x{2:X}\nVal2: 0x{3:X}\nStep: 0x{4:X}\nParams: {5}", eventUpdate.actorID, eventUpdate.scriptOwnerActorID, eventUpdate.val1, eventUpdate.val2, eventUpdate.step, LuaUtils.dumpParams(eventUpdate.luaParams))); //Is it a static actor? If not look in the player's instance - Actor updateOwnerActor = Server.getStaticActors(player.getActor().eventCurrentOwner); + Actor updateOwnerActor = Server.getStaticActors(player.getActor().currentEventOwner); if (updateOwnerActor == null) { - updateOwnerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().eventCurrentOwner); + updateOwnerActor = Server.GetWorldManager().GetActorInWorld(player.getActor().currentEventOwner); - if (player.getActor().currentDirector != null && player.getActor().eventCurrentOwner == player.getActor().currentDirector.actorId) + if (player.getActor().currentDirector != null && player.getActor().currentEventOwner == player.getActor().currentDirector.actorId) updateOwnerActor = player.getActor().currentDirector; if (updateOwnerActor == null) diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs index c87f47a1..8f75ff7c 100644 --- a/FFXIVClassic Map Server/Server.cs +++ b/FFXIVClassic Map Server/Server.cs @@ -418,16 +418,22 @@ namespace FFXIVClassic_Lobby_Server } } - public void doWarp(ConnectedPlayer client, string zone, string privateArea, string sx, string sy, string sz) + public void doWarp(ConnectedPlayer client, string zone, string privateArea, string sx, string sy, string sz, string spawnType) { uint zoneId; float x,y,z; + byte sType; if (zone.ToLower().StartsWith("0x")) zoneId = Convert.ToUInt32(zone, 16); else zoneId = Convert.ToUInt32(zone); + if (spawnType.ToLower().StartsWith("0x")) + sType = Convert.ToByte(spawnType, 16); + else + sType = Convert.ToByte(spawnType); + if (mWorldManager.GetZone(zoneId) == null) { if (client != null) @@ -440,12 +446,20 @@ namespace FFXIVClassic_Lobby_Server z = Single.Parse(sz); if (client != null) - mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, 0x2, x, y, z, 0.0f); + { + if (zoneId == client.getActor().zoneId) + mWorldManager.DoPlayerMoveInZone(client.getActor(), x, y, z, 0.0f, sType); + else + mWorldManager.DoZoneChange(client.getActor(), zoneId, privateArea, sType, x, y, z, 0.0f); + } else { foreach (KeyValuePair entry in mConnectedPlayerList) { - mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, 0x2, x, y, z, 0.0f); + if (zoneId == entry.Value.getActor().zoneId) + mWorldManager.DoPlayerMoveInZone(entry.Value.getActor(), x, y, z, 0.0f, 0x0); + else + mWorldManager.DoZoneChange(entry.Value.getActor(), zoneId, privateArea, 0x2, x, y, z, 0.0f); } } } @@ -826,10 +840,10 @@ namespace FFXIVClassic_Lobby_Server { if (split.Length == 2) doWarp(client, split[1]); - else if (split.Length == 5) - doWarp(client, split[1], null, split[2], split[3], split[4]); else if (split.Length == 6) - doWarp(client, split[1], split[2], split[3], split[4], split[5]); + doWarp(client, split[1], null, split[2], split[3], split[4], split[5]); + else if (split.Length == 7) + doWarp(client, split[1], split[2], split[3], split[4], split[5], split[6]); return true; } else if (split[0].Equals("property")) diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index f43fef23..07119676 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -417,11 +417,11 @@ namespace FFXIVClassic_Map_Server if (ze.zoneId != player.zoneId) return; - DoPlayerMoveInZone(player, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation); + DoPlayerMoveInZone(player, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation, ze.spawnType); } //Moves actor within the zone - public void DoPlayerMoveInZone(Player player, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation) + public void DoPlayerMoveInZone(Player player, float spawnX, float spawnY, float spawnZ, float spawnRotation, byte spawnType = 0xF) { //Remove player from currentZone if transfer else it's login if (player.zone != null) @@ -437,7 +437,7 @@ namespace FFXIVClassic_Map_Server //Send packets player.playerSession.queuePacket(_0xE2Packet.buildPacket(player.actorId, 0x0), true, false); - player.playerSession.queuePacket(player.createSpawnTeleportPacket(player.actorId, 0x0f), true, false); + player.playerSession.queuePacket(player.createSpawnTeleportPacket(player.actorId, spawnType), true, false); player.sendInstanceUpdate(); } @@ -455,6 +455,9 @@ namespace FFXIVClassic_Map_Server //Set the current zone and add player player.zone = zone; + + LuaEngine.onBeginLogin(player); + zone.addActorToZone(player); //Send packets diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 7405ed9d..4403cb8a 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -84,6 +84,15 @@ namespace FFXIVClassic_Map_Server.Actors 45000, 47000, 50000, 53000, 56000, 59000, 62000, 65000, 68000, 71000, //Level <= 40 74000, 78000, 81000, 85000, 89000, 92000, 96000, 100000, 100000, 110000}; //Level <= 50 + //Event Related + public uint currentEventOwner = 0; + public string currentEventName = ""; + + public uint currentCommand = 0; + public string currentCommandName = ""; + + public uint eventMenuId = 0; + //Player Info public uint[] timers = new uint[20]; public ushort currentJob; @@ -108,12 +117,7 @@ namespace FFXIVClassic_Map_Server.Actors public bool hasGoobbue; public byte chocoboAppearance; public string chocoboName; - public byte mountState = 0; - - //Event Related - public uint eventCurrentOwner = 0; - public string eventCurrentStarter = ""; - public uint eventMenuId = 0; + public byte mountState = 0; public uint achievementPoints; @@ -125,7 +129,7 @@ namespace FFXIVClassic_Map_Server.Actors public Quest[] questScenario = new Quest[16]; public Quest[] questGuildleve = new Quest[8]; - public Director currentDirector;// = new OpeningDirector(0x46080012); + public Director currentDirector; public PlayerWork playerWork = new PlayerWork(); @@ -256,7 +260,7 @@ namespace FFXIVClassic_Map_Server.Actors if (isMyPlayer(playerActorId)) { if (currentDirector != null) - lParams = LuaUtils.createLuaParamList("/Chara/Player/Player_work", false, false, true, currentDirector, 0, false, timers, true); + lParams = LuaUtils.createLuaParamList("/Chara/Player/Player_work", false, false, true, currentDirector, true, 0, false, timers, true); else lParams = LuaUtils.createLuaParamList("/Chara/Player/Player_work", false, false, false, true, 0, false, timers, true); } @@ -472,12 +476,15 @@ namespace FFXIVClassic_Map_Server.Actors public void sendZoneInPackets(WorldManager world, ushort spawnType) { - queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId)); + queuePacket(SetActorIsZoningPacket.buildPacket(actorId, actorId, false)); + queuePacket(_0x10Packet.buildPacket(actorId, 0xFF)); queuePacket(SetMusicPacket.buildPacket(actorId, zone.bgmDay, 0x01)); queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR)); + + queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId)); queuePacket(getSpawnPackets(actorId, spawnType)); - //getSpawnPackets(actorId, spawnType).debugPrintPacket(); + getSpawnPackets(actorId, spawnType).debugPrintPacket(); #region grouptest //Retainers @@ -511,6 +518,7 @@ namespace FFXIVClassic_Map_Server.Actors playerSession.queuePacket(getInitPackets(actorId)); + BasePacket areaMasterSpawn = zone.getSpawnPackets(actorId); BasePacket debugSpawn = world.GetDebugActor().getSpawnPackets(actorId); BasePacket worldMasterSpawn = world.GetActor().getSpawnPackets(actorId); @@ -523,8 +531,8 @@ namespace FFXIVClassic_Map_Server.Actors playerSession.queuePacket(debugSpawn); if (directorSpawn != null) { - directorSpawn.debugPrintPacket(); - currentDirector.getInitPackets(actorId).debugPrintPacket(); + //directorSpawn.debugPrintPacket(); + // currentDirector.getInitPackets(actorId).debugPrintPacket(); queuePacket(directorSpawn); queuePacket(currentDirector.getInitPackets(actorId)); //queuePacket(currentDirector.getSetEventStatusPackets(actorId)); @@ -982,6 +990,17 @@ namespace FFXIVClassic_Map_Server.Actors return null; } + public bool hasQuest(string name) + { + for (int i = 0; i < questScenario.Length; i++) + { + if (questScenario[i] != null && questScenario[i].actorName.ToLower().Equals(name.ToLower())) + return true; + } + + return false; + } + public bool hasQuest(uint id) { for (int i = 0; i < questScenario.Length; i++) @@ -1004,23 +1023,27 @@ namespace FFXIVClassic_Map_Server.Actors return -1; } - public void setDirector(string directorType) + public void setDirector(string directorType, bool sendPackets) { if (directorType.Equals("openingDirector")) { - currentDirector = new OpeningDirector(0x46080012); + currentDirector = new OpeningDirector(this, 0x46080012); } else if (directorType.Equals("QuestDirectorMan0l001")) { - currentDirector = new QuestDirectorMan0l001(0x46080012); + currentDirector = new QuestDirectorMan0l001(this, 0x46080012); + } + + if (sendPackets) + { + queuePacket(RemoveActorPacket.buildPacket(actorId, 0x46080012)); + queuePacket(currentDirector.getSpawnPackets(actorId)); + queuePacket(currentDirector.getInitPackets(actorId)); + //queuePacket(currentDirector.getSetEventStatusPackets(actorId)); + //currentDirector.getSpawnPackets(actorId).debugPrintPacket(); + //currentDirector.getInitPackets(actorId).debugPrintPacket(); } - // queuePacket(RemoveActorPacket.buildPacket(actorId, 0x46080012)); - // queuePacket(currentDirector.getSpawnPackets(actorId)); - // queuePacket(currentDirector.getInitPackets(actorId)); - // queuePacket(currentDirector.getSetEventStatusPackets(actorId)); - // currentDirector.getSpawnPackets(actorId).debugPrintPacket(); - // currentDirector.getInitPackets(actorId).debugPrintPacket(); } public Director getDirector() @@ -1068,22 +1091,32 @@ namespace FFXIVClassic_Map_Server.Actors public void runEventFunction(string functionName, params object[] parameters) { List lParams = LuaUtils.createLuaParamList(parameters); - SubPacket spacket = RunEventFunctionPacket.buildPacket(actorId, eventCurrentOwner, eventCurrentStarter, functionName, lParams); + SubPacket spacket = RunEventFunctionPacket.buildPacket(actorId, currentEventOwner, currentEventName, functionName, lParams); spacket.debugPrintSubPacket(); queuePacket(spacket); } public void endEvent() { - SubPacket p = EndEventPacket.buildPacket(actorId, eventCurrentOwner, eventCurrentStarter); + SubPacket p = EndEventPacket.buildPacket(actorId, currentEventOwner, currentEventName); p.debugPrintSubPacket(); queuePacket(p); - eventCurrentOwner = 0; - eventCurrentStarter = ""; + currentEventOwner = 0; + currentEventName = ""; eventMenuId = 0; } + public void endCommand() + { + SubPacket p = EndEventPacket.buildPacket(actorId, currentCommand, currentCommandName); + p.debugPrintSubPacket(); + queuePacket(p); + + currentCommand = 0; + currentCommandName = ""; + } + public void setCurrentMenuId(uint id) { eventMenuId = id; diff --git a/FFXIVClassic Map Server/actors/director/Director.cs b/FFXIVClassic Map Server/actors/director/Director.cs index bc63ec27..4ae68542 100644 --- a/FFXIVClassic Map Server/actors/director/Director.cs +++ b/FFXIVClassic Map Server/actors/director/Director.cs @@ -1,5 +1,6 @@ using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Map_Server.Actors; +using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; using System; using System.Collections.Generic; @@ -10,10 +11,12 @@ using System.Threading.Tasks; namespace FFXIVClassic_Map_Server.actors.director { class Director : Actor - { - public Director(uint id) : base(id) - { + { + Player owner; + public Director(Player owner, uint id) : base(id) + { + this.owner = owner; } public virtual BasePacket getSpawnPackets(uint playerActorId, uint spawnType) @@ -37,5 +40,15 @@ namespace FFXIVClassic_Map_Server.actors.director return BasePacket.createPacket(initProperties.buildPacket(playerActorId, actorId), true, false); } + public void onTalked(Npc npc) + { + LuaEngine.doDirectorOnTalked(this, owner, npc); + } + + public void onCommand(Command command) + { + LuaEngine.doDirectorOnCommand(this, owner, command); + } + } } diff --git a/FFXIVClassic Map Server/actors/director/OpeningDirector.cs b/FFXIVClassic Map Server/actors/director/OpeningDirector.cs index 6c45066b..0d910ba4 100644 --- a/FFXIVClassic Map Server/actors/director/OpeningDirector.cs +++ b/FFXIVClassic Map Server/actors/director/OpeningDirector.cs @@ -1,4 +1,5 @@ using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; using System; @@ -11,7 +12,7 @@ namespace FFXIVClassic_Map_Server.actors.director { class OpeningDirector : Director { - public OpeningDirector(uint id) : base(id) + public OpeningDirector(Player player, uint id) : base(player, id) { this.displayNameId = 0; this.customDisplayName = "openingDire"; diff --git a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs index 658776de..f560a902 100644 --- a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs +++ b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs @@ -15,8 +15,8 @@ namespace FFXIVClassic_Map_Server.Actors { private uint weatherId; - public WeatherDirector(uint weatherId) - : base(0x5FF80003) + public WeatherDirector(Player player, uint weatherId) + : base(player, 0x5FF80003) { this.weatherId = weatherId; diff --git a/FFXIVClassic Map Server/actors/director/quest/QuestDirectorMan0L001..cs b/FFXIVClassic Map Server/actors/director/quest/QuestDirectorMan0L001..cs index d7f2bfd0..2d5d1aec 100644 --- a/FFXIVClassic Map Server/actors/director/quest/QuestDirectorMan0L001..cs +++ b/FFXIVClassic Map Server/actors/director/quest/QuestDirectorMan0L001..cs @@ -1,4 +1,5 @@ using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; using System; @@ -11,7 +12,8 @@ namespace FFXIVClassic_Map_Server.actors.director { class QuestDirectorMan0l001 : Director { - public QuestDirectorMan0l001(uint id) : base(id) + public QuestDirectorMan0l001(Player player, uint id) + : base(player, id) { this.displayNameId = 0; this.customDisplayName = "questDirect_ocn0Btl02_01"; diff --git a/FFXIVClassic Map Server/actors/quest/Quest.cs b/FFXIVClassic Map Server/actors/quest/Quest.cs index a8bd5c34..8fe77bce 100644 --- a/FFXIVClassic Map Server/actors/quest/Quest.cs +++ b/FFXIVClassic Map Server/actors/quest/Quest.cs @@ -45,11 +45,21 @@ namespace FFXIVClassic_Map_Server.Actors return null; } + public void ClearQuestData() + { + questData.Clear(); + } + public uint GetQuestId() { return actorId; } + public void ClearQuestFlags() + { + questFlags = 0; + } + public void SetQuestFlag(int bitIndex, bool value) { if (bitIndex >= 32) diff --git a/FFXIVClassic Map Server/lua/LuaEngine.cs b/FFXIVClassic Map Server/lua/LuaEngine.cs index 8d8d92eb..89d2c272 100644 --- a/FFXIVClassic Map Server/lua/LuaEngine.cs +++ b/FFXIVClassic Map Server/lua/LuaEngine.cs @@ -176,6 +176,21 @@ namespace FFXIVClassic_Map_Server.lua } } + public static void onBeginLogin(Player player) + { + if (File.Exists(FILEPATH_PLAYER)) + { + Script script = loadScript(FILEPATH_PLAYER); + + if (script == null) + return; + + //Run Script + if (!script.Globals.Get("onBeginLogin").IsNil()) + script.Call(script.Globals["onBeginLogin"], player); + } + } + public static void onLogin(Player player) { if (File.Exists(FILEPATH_PLAYER)) @@ -186,8 +201,8 @@ namespace FFXIVClassic_Map_Server.lua return; //Run Script - if (!script.Globals.Get("onZoneIn").IsNil()) - script.Call(script.Globals["onZoneIn"], player); + if (!script.Globals.Get("onLogin").IsNil()) + script.Call(script.Globals["onLogin"], player); } } @@ -215,10 +230,52 @@ namespace FFXIVClassic_Map_Server.lua private static void SendError(Player player, string message) { List sendError = new List(); - sendError.Add(EndEventPacket.buildPacket(player.actorId, player.eventCurrentOwner, player.eventCurrentStarter)); + sendError.Add(EndEventPacket.buildPacket(player.actorId, player.currentEventOwner, player.currentEventName)); player.sendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM_ERROR, "", message); player.playerSession.queuePacket(BasePacket.createPacket(sendError, true, false)); } + + internal static void doDirectorOnTalked(Director director, Player player, Npc npc) + { + string luaPath = String.Format(FILEPATH_DIRECTORS, director.getName()); + + if (File.Exists(luaPath)) + { + Script script = loadScript(luaPath); + + if (script == null) + return; + + //Run Script + if (!script.Globals.Get("onTalked").IsNil()) + script.Call(script.Globals["onTalked"], player, npc); + } + else + { + SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.getName())); + } + } + + internal static void doDirectorOnCommand(Director director, Player player, Command command) + { + string luaPath = String.Format(FILEPATH_DIRECTORS, director.getName()); + + if (File.Exists(luaPath)) + { + Script script = loadScript(luaPath); + + if (script == null) + return; + + //Run Script + if (!script.Globals.Get("onCommand").IsNil()) + script.Call(script.Globals["onCommand"], player, command); + } + else + { + SendError(player, String.Format("ERROR: Could not find script for director {0}.", director.getName())); + } + } } } diff --git a/FFXIVClassic Map Server/packets/send/_0x10Packet.cs b/FFXIVClassic Map Server/packets/send/_0x10Packet.cs new file mode 100644 index 00000000..5c036792 --- /dev/null +++ b/FFXIVClassic Map Server/packets/send/_0x10Packet.cs @@ -0,0 +1,31 @@ +using FFXIVClassic_Lobby_Server.packets; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.send +{ + class _0x10Packet + { + public const ushort OPCODE = 0x0010; + public const uint PACKET_SIZE = 0x28; + + public static SubPacket buildPacket(uint playerActorId, int val) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt32)val); + } + } + + return new SubPacket(OPCODE, playerActorId, playerActorId, data); + } + } +}