From 5d494255ad33070a60f0c9fa9ec3b0faa05f0222 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Mon, 2 Jan 2017 14:35:11 -0500 Subject: [PATCH] Party invite done, as well as chat. Fixed double output of say packets. Note: Still need to implement name version of invite!!! --- .../FFXIVClassic Map Server.csproj | 2 +- FFXIVClassic Map Server/PacketProcessor.cs | 3 +- FFXIVClassic Map Server/WorldManager.cs | 17 +++++++ .../actors/chara/player/Player.cs | 9 ++-- ...ltPacket.cs => GroupInviteResultPacket.cs} | 5 +- .../DataObjects/Group/Group.cs | 38 ++++++++++++++ .../DataObjects/Group/Party.cs | 14 +++++- .../FFXIVClassic World Server.csproj | 4 +- FFXIVClassic World Server/PacketProcessor.cs | 15 ++++++ .../Receive/Subpackets/ChatMessagePacket.cs | 42 ++++++++++++++++ .../Subpackets/PartyChatMessagePacket.cs | 31 ++++++++++++ .../Subpackets/Groups/GroupHeaderPacket.cs | 1 + ...ltPacket.cs => GroupInviteResultPacket.cs} | 6 ++- .../Receive/Group/PartyInvitePacket.cs | 2 +- FFXIVClassic World Server/Server.cs | 15 ++++-- FFXIVClassic World Server/WorldMaster.cs | 50 ++++++++++++++++--- 16 files changed, 231 insertions(+), 23 deletions(-) rename FFXIVClassic Map Server/packets/WorldPackets/Send/Group/{PartyInviteResultPacket.cs => GroupInviteResultPacket.cs} (87%) create mode 100644 FFXIVClassic World Server/Packets/Receive/Subpackets/ChatMessagePacket.cs create mode 100644 FFXIVClassic World Server/Packets/Receive/Subpackets/PartyChatMessagePacket.cs rename FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/{PartyInviteResultPacket.cs => GroupInviteResultPacket.cs} (80%) diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 9df052dc..dac17214 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -286,7 +286,7 @@ - + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 6f6bc7fe..653c7fab 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -111,7 +111,8 @@ namespace FFXIVClassic_Map_Server return; ; } - session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false); + if (chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SAY || chatMessage.logType == SendMessagePacket.MESSAGE_TYPE_SHOUT) + session.GetActor().BroadcastPacket(SendMessagePacket.BuildPacket(session.id, session.id, chatMessage.logType, session.GetActor().customDisplayName, chatMessage.message), false); break; //Langauge Code (Client safe to send packets to now) diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index edc2042b..39912ab0 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -748,6 +748,23 @@ namespace FFXIVClassic_Map_Server currentPlayerParties.Remove(party.groupIndex); } + public void CreateInvitePartyGroup(Player player, string name) + { + SubPacket invitePacket = PartyInvitePacket.BuildPacket(player.playerSession, name); + player.QueuePacket(invitePacket); + } + public void CreateInvitePartyGroup(Player player, uint actorId) + { + SubPacket invitePacket = PartyInvitePacket.BuildPacket(player.playerSession, actorId); + player.QueuePacket(invitePacket); + } + + public void GroupInviteResult(Player player, uint groupType, uint result) + { + SubPacket groupInviteResultPacket = GroupInviteResultPacket.BuildPacket(player.playerSession, groupType, result); + player.QueuePacket(groupInviteResultPacket); + } + public Player GetPCInWorld(string name) { foreach (Zone zone in zoneList.Values) diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index f39b87b5..069c0904 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -608,14 +608,15 @@ namespace FFXIVClassic_Map_Server.Actors public void BroadcastPacket(SubPacket packet, bool sendToSelf) { - if (sendToSelf) - QueuePacket(packet); - foreach (Actor a in playerSession.actorInstanceList) { if (a is Player) { - Player p = (Player)a; + Player p = (Player)a; + + if (p.Equals(this) && !sendToSelf) + continue; + SubPacket clonedPacket = new SubPacket(packet, a.actorId); p.QueuePacket(clonedPacket); } diff --git a/FFXIVClassic Map Server/packets/WorldPackets/Send/Group/PartyInviteResultPacket.cs b/FFXIVClassic Map Server/packets/WorldPackets/Send/Group/GroupInviteResultPacket.cs similarity index 87% rename from FFXIVClassic Map Server/packets/WorldPackets/Send/Group/PartyInviteResultPacket.cs rename to FFXIVClassic Map Server/packets/WorldPackets/Send/Group/GroupInviteResultPacket.cs index 6fc17074..a753bc9c 100644 --- a/FFXIVClassic Map Server/packets/WorldPackets/Send/Group/PartyInviteResultPacket.cs +++ b/FFXIVClassic Map Server/packets/WorldPackets/Send/Group/GroupInviteResultPacket.cs @@ -9,18 +9,19 @@ using System.Threading.Tasks; namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group { - class PartyInviteResultPacket + class GroupInviteResultPacket { public const ushort OPCODE = 0x1023; public const uint PACKET_SIZE = 0x28; - public static SubPacket BuildPacket(Session session, uint result) + public static SubPacket BuildPacket(Session session, uint groupType, uint result) { byte[] data = new byte[PACKET_SIZE - 0x20]; using (MemoryStream mem = new MemoryStream(data)) { using (BinaryWriter binWriter = new BinaryWriter(mem)) { + binWriter.Write((UInt32)groupType); binWriter.Write((UInt32)result); } } diff --git a/FFXIVClassic World Server/DataObjects/Group/Group.cs b/FFXIVClassic World Server/DataObjects/Group/Group.cs index a20b37d7..02a97553 100644 --- a/FFXIVClassic World Server/DataObjects/Group/Group.cs +++ b/FFXIVClassic World Server/DataObjects/Group/Group.cs @@ -48,6 +48,17 @@ namespace FFXIVClassic_World_Server.DataObjects.Group return new List(); } + public void SendGroupPacketsAll(params uint[] sessionIds) + { + for (int i = 0; i < sessionIds.Length; i++) + { + Session session = Server.GetServer().GetSession(sessionIds[i]); + + if (session != null) + SendGroupPackets(session); + } + } + public void SendGroupPacketsAll(List sessionIds) { for (int i = 0; i < sessionIds.Count; i++) @@ -59,6 +70,28 @@ namespace FFXIVClassic_World_Server.DataObjects.Group } } + public void SendDeletePackets(params uint[] sessionIds) + { + for (int i = 0; i < sessionIds.Length; i++) + { + Session session = Server.GetServer().GetSession(sessionIds[i]); + + if (session != null) + SendDeletePacket(session); + } + } + + public void SendDeletePackets(List sessionIds) + { + for (int i = 0; i < sessionIds.Count; i++) + { + Session session = Server.GetServer().GetSession(sessionIds[i]); + + if (session != null) + SendDeletePacket(session); + } + } + public void SendGroupPackets(Session session) { ulong time = Utils.MilisUnixTimeStampUTC(); @@ -87,6 +120,11 @@ namespace FFXIVClassic_World_Server.DataObjects.Group } + public void SendDeletePacket(Session session) + { + session.clientConnection.QueuePacket(DeleteGroupPacket.buildPacket(session.sessionId, this), true, false); + } + public virtual void SendInitWorkValues(Session session) { diff --git a/FFXIVClassic World Server/DataObjects/Group/Party.cs b/FFXIVClassic World Server/DataObjects/Group/Party.cs index 1286d693..7fc1a9eb 100644 --- a/FFXIVClassic World Server/DataObjects/Group/Party.cs +++ b/FFXIVClassic World Server/DataObjects/Group/Party.cs @@ -252,6 +252,18 @@ namespace FFXIVClassic_World_Server.DataObjects.Group } return groupMembers; } - + + public void OnPlayerJoin(Session inviteeSession) + { + for (int i = 0; i < members.Count; i++) + { + Session session = Server.GetServer().GetSession(members[i]); + if (session == null) + continue; + + session.SendGameMessage(30427, 0x20, (Object)Server.GetServer().GetNameForId(inviteeSession.sessionId)); + } + } + } } diff --git a/FFXIVClassic World Server/FFXIVClassic World Server.csproj b/FFXIVClassic World Server/FFXIVClassic World Server.csproj index 5e6868d3..f491b4b8 100644 --- a/FFXIVClassic World Server/FFXIVClassic World Server.csproj +++ b/FFXIVClassic World Server/FFXIVClassic World Server.csproj @@ -90,6 +90,8 @@ + + @@ -108,7 +110,7 @@ - + diff --git a/FFXIVClassic World Server/PacketProcessor.cs b/FFXIVClassic World Server/PacketProcessor.cs index bf11afa1..95e27eea 100644 --- a/FFXIVClassic World Server/PacketProcessor.cs +++ b/FFXIVClassic World Server/PacketProcessor.cs @@ -1,9 +1,11 @@ using FFXIVClassic.Common; using FFXIVClassic_World_Server.DataObjects; +using FFXIVClassic_World_Server.DataObjects.Group; using FFXIVClassic_World_Server.Packets.Receive; using FFXIVClassic_World_Server.Packets.Receive.Subpackets; using FFXIVClassic_World_Server.Packets.Send; using FFXIVClassic_World_Server.Packets.Send.Login; +using FFXIVClassic_World_Server.Packets.Send.Subpackets; using FFXIVClassic_World_Server.Packets.WorldPackets.Receive; using FFXIVClassic_World_Server.Packets.WorldPackets.Send; using System; @@ -151,6 +153,19 @@ namespace FFXIVClassic_World_Server { switch (subpacket.gameMessage.opcode) { + case 0x00C9: + subpacket.DebugPrintSubPacket(); + PartyChatMessagePacket partyChatMessagePacket = new PartyChatMessagePacket(subpacket.data); + Party playerParty = mServer.GetWorldManager().GetPartyManager().GetParty(session.sessionId); + for (int i = 0; i < playerParty.members.Count; i++) + { + Session thatSession = mServer.GetSession(playerParty.members[i]); + if (thatSession != null && !session.Equals(thatSession)) + { + thatSession.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, thatSession.sessionId, SendMessagePacket.MESSAGE_TYPE_PARTY, mServer.GetNameForId(session.sessionId), partyChatMessagePacket.message), true, false); + } + } + break; case 0x6: mServer.GetWorldManager().DoLogin(session); break; diff --git a/FFXIVClassic World Server/Packets/Receive/Subpackets/ChatMessagePacket.cs b/FFXIVClassic World Server/Packets/Receive/Subpackets/ChatMessagePacket.cs new file mode 100644 index 00000000..ad94cc71 --- /dev/null +++ b/FFXIVClassic World Server/Packets/Receive/Subpackets/ChatMessagePacket.cs @@ -0,0 +1,42 @@ +using System; +using System.IO; +using System.Text; + +namespace FFXIVClassic_World_Server.Packets.Receive.Subpackets +{ + class ChatMessagePacket + { + public float posX; + public float posY; + public float posZ; + public float posRot; + + public uint logType; + + public string message; + + public bool invalidPacket = false; + + public ChatMessagePacket(byte[] data) + { + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryReader binReader = new BinaryReader(mem)) + { + try{ + binReader.ReadUInt64(); + posX = binReader.ReadSingle(); + posY = binReader.ReadSingle(); + posZ = binReader.ReadSingle(); + posRot = binReader.ReadSingle(); + logType = binReader.ReadUInt32(); + message = Encoding.ASCII.GetString(binReader.ReadBytes(0x200)).Trim(new [] { '\0' }); + } + catch (Exception){ + invalidPacket = true; + } + } + } + } + } +} diff --git a/FFXIVClassic World Server/Packets/Receive/Subpackets/PartyChatMessagePacket.cs b/FFXIVClassic World Server/Packets/Receive/Subpackets/PartyChatMessagePacket.cs new file mode 100644 index 00000000..ef20b3fc --- /dev/null +++ b/FFXIVClassic World Server/Packets/Receive/Subpackets/PartyChatMessagePacket.cs @@ -0,0 +1,31 @@ +using System; +using System.IO; +using System.Text; + +namespace FFXIVClassic_World_Server.Packets.Receive.Subpackets +{ + class PartyChatMessagePacket + { + public uint actorId; + public string message; + + public bool invalidPacket = false; + + public PartyChatMessagePacket(byte[] data) + { + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryReader binReader = new BinaryReader(mem)) + { + try{ + actorId = binReader.ReadUInt32(); + message = Encoding.ASCII.GetString(binReader.ReadBytes(0x200)).Trim(new [] { '\0' }); + } + catch (Exception){ + invalidPacket = true; + } + } + } + } + } +} diff --git a/FFXIVClassic World Server/Packets/Send/Subpackets/Groups/GroupHeaderPacket.cs b/FFXIVClassic World Server/Packets/Send/Subpackets/Groups/GroupHeaderPacket.cs index 0c237f5e..d1d46a3a 100644 --- a/FFXIVClassic World Server/Packets/Send/Subpackets/Groups/GroupHeaderPacket.cs +++ b/FFXIVClassic World Server/Packets/Send/Subpackets/Groups/GroupHeaderPacket.cs @@ -46,6 +46,7 @@ namespace FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups binWriter.Seek(0x64, SeekOrigin.Begin); + //Does this change chat???? binWriter.Write((UInt32)0x6D); binWriter.Write((UInt32)0x6D); binWriter.Write((UInt32)0x6D); diff --git a/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInviteResultPacket.cs b/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/GroupInviteResultPacket.cs similarity index 80% rename from FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInviteResultPacket.cs rename to FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/GroupInviteResultPacket.cs index f3fa8701..6197b16c 100644 --- a/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInviteResultPacket.cs +++ b/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/GroupInviteResultPacket.cs @@ -5,13 +5,14 @@ using System.Text; namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group { - class PartyInviteResultPacket + class GroupInviteResultPacket { public bool invalidPacket = false; + public uint groupType; public uint result; - public PartyInviteResultPacket(byte[] data) + public GroupInviteResultPacket(byte[] data) { using (MemoryStream mem = new MemoryStream(data)) { @@ -19,6 +20,7 @@ namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group { try { + groupType = binReader.ReadUInt32(); result = binReader.ReadUInt32(); } catch (Exception) diff --git a/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInvitePacket.cs b/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInvitePacket.cs index 796a1792..1a4d55e3 100644 --- a/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInvitePacket.cs +++ b/FFXIVClassic World Server/Packets/WorldPackets/Receive/Group/PartyInvitePacket.cs @@ -23,7 +23,7 @@ namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group { command = binReader.ReadUInt16(); - if (command == 0) + if (command == 1) actorId = binReader.ReadUInt32(); else name = Encoding.ASCII.GetString(binReader.ReadBytes(0x20)).Trim(new[] { '\0' }); diff --git a/FFXIVClassic World Server/Server.cs b/FFXIVClassic World Server/Server.cs index d6221bb6..0e3d6247 100644 --- a/FFXIVClassic World Server/Server.cs +++ b/FFXIVClassic World Server/Server.cs @@ -233,16 +233,23 @@ namespace FFXIVClassic_World_Server //Party Invite Request case 0x1022: PartyInvitePacket partyInvitePacket = new PartyInvitePacket(subpacket.data); - if (partyInvitePacket.command == 0) + if (partyInvitePacket.command == 1) mWorldManager.ProcessPartyInvite(GetSession(subpacket.header.sourceId), partyInvitePacket.actorId); - else if (partyInvitePacket.command == 1) + else if (partyInvitePacket.command == 0) { } break; - //Party Invite Result + //Group Invite Result case 0x1023: - PartyInviteResultPacket partyInviteResultPacket = new PartyInviteResultPacket(subpacket.data); + GroupInviteResultPacket groupInviteResultPacket = new GroupInviteResultPacket(subpacket.data); + + switch (groupInviteResultPacket.groupType) + { + case 0x2711: + mWorldManager.ProcessPartyInviteResult(GetSession(subpacket.header.sourceId), groupInviteResultPacket.result); + break; + } break; //Linkshell create request diff --git a/FFXIVClassic World Server/WorldMaster.cs b/FFXIVClassic World Server/WorldMaster.cs index 9181d46d..779bf352 100644 --- a/FFXIVClassic World Server/WorldMaster.cs +++ b/FFXIVClassic World Server/WorldMaster.cs @@ -219,10 +219,7 @@ namespace FFXIVClassic_World_Server mRetainerGroupManager.GetRetainerGroup(session.sessionId).SendGroupPackets(session); List linkshells = mLinkshellManager.GetPlayerLinkshellMembership(session.sessionId); foreach (Linkshell ls in linkshells) - ls.SendGroupPackets(session); - - mRelationGroupManager.CreatePartyRelationGroup(157, session.sessionId).SendGroupPackets(session); - + ls.SendGroupPackets(session); } private void SendMotD(Session session) @@ -292,9 +289,50 @@ namespace FFXIVClassic_World_Server } } - public void ProcessPartyInvite(Session request, uint invitee) + public void ProcessPartyInvite(Session requestSession, uint invitee) { - throw new NotImplementedException(); + if (mServer.GetSession(invitee) == null) + { + requestSession.SendGameMessage(30544, 0x20); + } + else + { + Session inviteeSession = mServer.GetSession(invitee); + Relation inviteRelation = mRelationGroupManager.CreatePartyRelationGroup(requestSession.sessionId, invitee); + inviteRelation.SendGroupPacketsAll(requestSession.sessionId, invitee); + inviteeSession.SendGameMessage(30430, 0x20, (object)mServer.GetNameForId(requestSession.sessionId)); //X Invited you + requestSession.SendGameMessage(30433, 0x20, (object)mServer.GetNameForId(inviteeSession.sessionId)); //You invite X + } + } + + public void ProcessPartyInviteResult(Session inviteeSession, uint resultCode) + { + Relation relation = mRelationGroupManager.GetPartyRelationGroup(inviteeSession.sessionId); + Session inviterSession = mServer.GetSession(relation.GetHost()); + + //Accept + if (resultCode == 1) + { + Party oldParty = mPartyManager.GetParty(inviteeSession.sessionId); + if (oldParty.members.Count == 1) + { + mPartyManager.DeleteParty(oldParty.groupIndex); + Party newParty = mPartyManager.GetParty(inviterSession.sessionId); + mPartyManager.AddToParty(newParty.groupIndex, inviteeSession.sessionId); + newParty.SendGroupPacketsAll(newParty.members); + SendPartySync(newParty); + newParty.OnPlayerJoin(inviteeSession); + } + } + else //Refuse + { + inviterSession.SendGameMessage(30573, 0x20, (object)mServer.GetNameForId(inviteeSession.sessionId)); //X rejects your invite + } + + //Delete the relation + mRelationGroupManager.DeleteRelationGroup(relation.groupIndex); + relation.SendDeletePackets(inviterSession.sessionId, inviteeSession.sessionId); + } public void IncrementGroupIndex()