From 4ce4647a75d28fcf4c39bbc7b5d2f0073f13377c Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sat, 3 Dec 2016 14:00:24 -0500 Subject: [PATCH] If a player tries to zone to a offline server they will see a standard error message. Also a reconnection attempt will be made on a disconnected server. --- .../FFXIVClassic Map Server.csproj | 1 + FFXIVClassic Map Server/PacketProcessor.cs | 10 +++++ FFXIVClassic Map Server/WorldManager.cs | 21 ++++------- .../actors/chara/player/Player.cs | 16 ++++---- .../WorldPackets/Receive/ErrorPacket.cs | 35 ++++++++++++++++++ .../DataObjects/ZoneServer.cs | 6 ++- .../FFXIVClassic World Server.csproj | 1 + .../Packets/WorldPackets/Send/ErrorPacket.cs | 37 +++++++++++++++++++ FFXIVClassic World Server/WorldMaster.cs | 9 ++++- 9 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 FFXIVClassic Map Server/packets/WorldPackets/Receive/ErrorPacket.cs create mode 100644 FFXIVClassic World Server/Packets/WorldPackets/Send/ErrorPacket.cs diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index fd7c1e34..c6543cc2 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -256,6 +256,7 @@ + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 12b31425..e11b85cc 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -42,6 +42,16 @@ namespace FFXIVClassic_Map_Server //Normal Game Opcode switch (subpacket.gameMessage.opcode) { + //World Server - Error + case 0x100A: + ErrorPacket worldError = new ErrorPacket(subpacket.data); + switch (worldError.errorCode) + { + case 0x01: + session.GetActor().SendGameMessage(Server.GetWorldManager().GetActor(), 60005, 0x20); + break; + } + break; //World Server - Session Begin case 0x1000: subpacket.DebugPrintSubPacket(); diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 5e728a01..84a4a72e 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -360,14 +360,7 @@ namespace FFXIVClassic_Map_Server //Moves actor to new zone, and sends packets to spawn at the given coords. public void DoZoneChange(Player player, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation) - { - Area oldZone = player.zone; - //Remove player from currentZone if transfer else it's login - if (player.zone != null) - { - oldZone.RemoveActorFromZone(player); - } - + { //Add player to new zone and update Area newArea; @@ -379,16 +372,18 @@ namespace FFXIVClassic_Map_Server //This server does not contain that zoneId if (newArea == null) { - if (oldZone != null) - { - oldZone.AddActorToZone(player); - } - Program.Log.Debug("Request to change to zone not on this server by: {0}.", player.customDisplayName); RequestWorldServerZoneChange(player, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation); return; } + Area oldZone = player.zone; + //Remove player from currentZone if transfer else it's login + if (player.zone != null) + { + oldZone.RemoveActorFromZone(player); + } + newArea.AddActorToZone(player); //Update player actor's properties diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 9df7fe81..df603f6f 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -748,8 +748,8 @@ namespace FFXIVClassic_Map_Server.Actors } public void SendGameMessage(Actor sourceActor, Actor textIdOwner, ushort textId, byte log, params object[] msgParams) - { - if (msgParams.Length == 0) + { + if (msgParams == null || msgParams.Length == 0) { QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, sourceActor.actorId, textIdOwner.actorId, textId, log)); } @@ -758,24 +758,24 @@ namespace FFXIVClassic_Map_Server.Actors } public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, params object[] msgParams) - { - if (msgParams.Length == 0) + { + if (msgParams == null || msgParams.Length == 0) QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log)); else QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, log, LuaUtils.CreateLuaParamList(msgParams))); } public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, string customSender, params object[] msgParams) - { - if (msgParams.Length == 0) + { + if (msgParams == null || msgParams.Length == 0) QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log)); else QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams))); } public void SendGameMessage(Actor textIdOwner, ushort textId, byte log, uint displayId, params object[] msgParams) - { - if (msgParams.Length == 0) + { + if (msgParams == null || msgParams.Length == 0) QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log)); else QueuePacket(GameMessagePacket.BuildPacket(Server.GetWorldManager().GetActor().actorId, actorId, textIdOwner.actorId, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams))); diff --git a/FFXIVClassic Map Server/packets/WorldPackets/Receive/ErrorPacket.cs b/FFXIVClassic Map Server/packets/WorldPackets/Receive/ErrorPacket.cs new file mode 100644 index 00000000..ae31462d --- /dev/null +++ b/FFXIVClassic Map Server/packets/WorldPackets/Receive/ErrorPacket.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive +{ + class ErrorPacket + { + public uint errorCode; + + public bool invalidPacket = false; + + public ErrorPacket(byte[] data) + { + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryReader binReader = new BinaryReader(mem)) + { + try + { + errorCode = binReader.ReadUInt32(); + } + catch (Exception) + { + invalidPacket = true; + } + } + } + + } + } +} diff --git a/FFXIVClassic World Server/DataObjects/ZoneServer.cs b/FFXIVClassic World Server/DataObjects/ZoneServer.cs index f066ba7b..f4a2ac00 100644 --- a/FFXIVClassic World Server/DataObjects/ZoneServer.cs +++ b/FFXIVClassic World Server/DataObjects/ZoneServer.cs @@ -35,7 +35,7 @@ namespace FFXIVClassic_World_Server.DataObjects ownedZoneIds.Add(id); } - public void Connect() + public bool Connect() { Program.Log.Info("Connecting to zone server @ {0}:{1}", zoneServerIp, zoneServerPort); IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(zoneServerIp), zoneServerPort); @@ -60,7 +60,9 @@ namespace FFXIVClassic_World_Server.DataObjects } } catch (Exception e) - { Program.Log.Error("Failed to connect"); return; } + { Program.Log.Error("Failed to connect"); return false; } + + return true; } public void SendPacket(SubPacket subpacket) diff --git a/FFXIVClassic World Server/FFXIVClassic World Server.csproj b/FFXIVClassic World Server/FFXIVClassic World Server.csproj index bb0381e4..75e58178 100644 --- a/FFXIVClassic World Server/FFXIVClassic World Server.csproj +++ b/FFXIVClassic World Server/FFXIVClassic World Server.csproj @@ -77,6 +77,7 @@ + diff --git a/FFXIVClassic World Server/Packets/WorldPackets/Send/ErrorPacket.cs b/FFXIVClassic World Server/Packets/WorldPackets/Send/ErrorPacket.cs new file mode 100644 index 00000000..2a7d4c4f --- /dev/null +++ b/FFXIVClassic World Server/Packets/WorldPackets/Send/ErrorPacket.cs @@ -0,0 +1,37 @@ +using FFXIVClassic.Common; +using FFXIVClassic_World_Server.DataObjects; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send +{ + class ErrorPacket + { + public const ushort OPCODE = 0x100A; + public const uint PACKET_SIZE = 0x24; + + public static SubPacket BuildPacket(Session session, uint errorCode) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + try + { + binWriter.Write((UInt32)errorCode); + } + catch (Exception) + { } + } + } + + return new SubPacket(true, OPCODE, 0, session.sessionId, data); + } + } +} diff --git a/FFXIVClassic World Server/WorldMaster.cs b/FFXIVClassic World Server/WorldMaster.cs index 0f490c25..22ebd24a 100644 --- a/FFXIVClassic World Server/WorldMaster.cs +++ b/FFXIVClassic World Server/WorldMaster.cs @@ -1,5 +1,6 @@ using FFXIVClassic.Common; using FFXIVClassic_World_Server.DataObjects; +using FFXIVClassic_World_Server.Packets.WorldPackets.Send; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -167,7 +168,13 @@ namespace FFXIVClassic_World_Server //Moves actor to new zone, and sends packets to spawn at the given coords. public void DoZoneServerChange(Session session, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation) { - session.routing1.SendSessionEnd(session, destinationZoneId, destinationPrivateArea, spawnType, spawnX, spawnY, spawnZ, spawnRotation); + ZoneServer zs = GetZoneServer(destinationZoneId); + if (zs.isConnected) + session.routing1.SendSessionEnd(session, destinationZoneId, destinationPrivateArea, spawnType, spawnX, spawnY, spawnZ, spawnRotation); + else if (zs.Connect()) + session.routing1.SendSessionEnd(session, destinationZoneId, destinationPrivateArea, spawnType, spawnX, spawnY, spawnZ, spawnRotation); + else + session.routing1.SendPacket(ErrorPacket.BuildPacket(session, 1)); } //Login Zone In