mirror of
				https://bitbucket.org/Ioncannon/project-meteor-server.git
				synced 2025-05-20 08:26:59 -04:00 
			
		
		
		
	Kicked/Promote leader added but broke login. D/Cing now.
This commit is contained in:
		@@ -81,10 +81,9 @@
 | 
			
		||||
    <Compile Include="actors\chara\player\Equipment.cs" />
 | 
			
		||||
    <Compile Include="actors\chara\player\Inventory.cs" />
 | 
			
		||||
    <Compile Include="actors\chara\Work.cs" />
 | 
			
		||||
    <Compile Include="actors\group\GroupInvitationRelationGroup.cs" />
 | 
			
		||||
    <Compile Include="actors\group\LinkshellGroup.cs" />
 | 
			
		||||
    <Compile Include="actors\group\PartyGroup.cs" />
 | 
			
		||||
    <Compile Include="actors\group\RetainerGroup.cs" />
 | 
			
		||||
    <Compile Include="actors\group\Group.cs" />
 | 
			
		||||
    <Compile Include="actors\group\Party.cs" />
 | 
			
		||||
    <Compile Include="actors\group\Relation.cs" />
 | 
			
		||||
    <Compile Include="actors\group\work\ContentWork.cs" />
 | 
			
		||||
    <Compile Include="actors\debug\Debug.cs" />
 | 
			
		||||
    <Compile Include="actors\director\Director.cs" />
 | 
			
		||||
@@ -94,7 +93,6 @@
 | 
			
		||||
    <Compile Include="actors\director\quest\QuestDirectorMan0u001.cs" />
 | 
			
		||||
    <Compile Include="actors\director\WeatherDirector.cs" />
 | 
			
		||||
    <Compile Include="actors\EventList.cs" />
 | 
			
		||||
    <Compile Include="actors\group\Group.cs" />
 | 
			
		||||
    <Compile Include="actors\group\work\GroupGlobalSave.cs" />
 | 
			
		||||
    <Compile Include="actors\group\work\GroupGlobalTemp.cs" />
 | 
			
		||||
    <Compile Include="actors\group\work\GroupMemberSave.cs" />
 | 
			
		||||
@@ -288,6 +286,7 @@
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\Group\CreateLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\Group\DeleteLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\Group\ModifyLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\Group\PartyModifyPacket.cs" />
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\SessionBeginConfirmPacket.cs" />
 | 
			
		||||
    <Compile Include="packets\WorldPackets\Send\SessionEndConfirmPacket.cs" />
 | 
			
		||||
    <Compile Include="Program.cs" />
 | 
			
		||||
 
 | 
			
		||||
@@ -248,7 +248,7 @@ namespace FFXIVClassic_Map_Server
 | 
			
		||||
                        break;
 | 
			
		||||
                    //Party Window Opened, Request State
 | 
			
		||||
                    case 0x01C5:
 | 
			
		||||
                        client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(session.id, true, true, 1), true, false));
 | 
			
		||||
                        client.QueuePacket(BasePacket.CreatePacket(RecruiterStatePacket.BuildPacket(session.id, false, false, 0), true, false));
 | 
			
		||||
                        break;
 | 
			
		||||
                    //Search Recruiting
 | 
			
		||||
                    case 0x01C7:
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,8 @@ namespace FFXIVClassic_Map_Server
 | 
			
		||||
        private Dictionary<uint, ActorClass> actorClasses = new Dictionary<uint,ActorClass>();
 | 
			
		||||
        private Dictionary<ulong, Party> currentPlayerParties = new Dictionary<ulong, Party>(); //GroupId, Party object
 | 
			
		||||
 | 
			
		||||
        private Object groupLock = new Object();
 | 
			
		||||
 | 
			
		||||
        private Server mServer;
 | 
			
		||||
 | 
			
		||||
        public WorldManager(Server server)
 | 
			
		||||
@@ -700,37 +702,41 @@ namespace FFXIVClassic_Map_Server
 | 
			
		||||
        //World server sent a party member list synch packet to the zone server. Add and update players that may be a part of it.
 | 
			
		||||
        public void PartyMemberListRecieved(PartySyncPacket syncPacket)
 | 
			
		||||
        {
 | 
			
		||||
            Party group;         
 | 
			
		||||
 | 
			
		||||
            //If no members on this server, get out or clean
 | 
			
		||||
            if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0)
 | 
			
		||||
                return;
 | 
			
		||||
            else if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0)
 | 
			
		||||
                NoMembersInParty(currentPlayerParties[syncPacket.partyGroupId]);
 | 
			
		||||
 | 
			
		||||
            //Get or create group
 | 
			
		||||
            if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId))
 | 
			
		||||
            lock (currentPlayerParties)
 | 
			
		||||
            {
 | 
			
		||||
                group = new Party(syncPacket.partyGroupId, syncPacket.owner);
 | 
			
		||||
                currentPlayerParties.Add(syncPacket.partyGroupId, group);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                group = currentPlayerParties[syncPacket.partyGroupId];
 | 
			
		||||
                Party group;
 | 
			
		||||
 | 
			
		||||
            currentPlayerParties[syncPacket.partyGroupId].members = syncPacket.memberActorIds.ToList();
 | 
			
		||||
                //If no members on this server, get out or clean
 | 
			
		||||
                if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0)
 | 
			
		||||
                    return;
 | 
			
		||||
                else if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0)
 | 
			
		||||
                    NoMembersInParty(currentPlayerParties[syncPacket.partyGroupId]);
 | 
			
		||||
 | 
			
		||||
            //Add group to everyone
 | 
			
		||||
            foreach (uint member in currentPlayerParties[syncPacket.partyGroupId].members)
 | 
			
		||||
            {
 | 
			
		||||
                Session session = Server.GetServer().GetSession(member);
 | 
			
		||||
                //Get or create group
 | 
			
		||||
                if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId))
 | 
			
		||||
                {
 | 
			
		||||
                    group = new Party(syncPacket.partyGroupId, syncPacket.owner);
 | 
			
		||||
                    currentPlayerParties.Add(syncPacket.partyGroupId, group);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    group = currentPlayerParties[syncPacket.partyGroupId];
 | 
			
		||||
 | 
			
		||||
                if (session == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
                group.members = syncPacket.memberActorIds.ToList();
 | 
			
		||||
 | 
			
		||||
                Player player = session.GetActor();
 | 
			
		||||
                if (player == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
                player.SetParty(group);
 | 
			
		||||
                //Add group to everyone
 | 
			
		||||
                for (int i = 0; i < group.members.Count; i++ )
 | 
			
		||||
                {
 | 
			
		||||
                    uint member = group.members[i];
 | 
			
		||||
                    Session session = Server.GetServer().GetSession(member);
 | 
			
		||||
 | 
			
		||||
                    if (session == null)
 | 
			
		||||
                        continue;
 | 
			
		||||
 | 
			
		||||
                    Player player = session.GetActor();
 | 
			
		||||
                    if (player == null)
 | 
			
		||||
                        continue;
 | 
			
		||||
                    player.SetParty(group);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@ using FFXIVClassic_Map_Server.packets.receive.events;
 | 
			
		||||
using FFXIVClassic_Map_Server.packets.send.actor.inventory;
 | 
			
		||||
using FFXIVClassic_Map_Server.actors.group;
 | 
			
		||||
using FFXIVClassic_Map_Server.packets.send.group;
 | 
			
		||||
using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_Map_Server.Actors
 | 
			
		||||
{
 | 
			
		||||
@@ -1290,8 +1291,10 @@ namespace FFXIVClassic_Map_Server.Actors
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PartyOustPlayer()
 | 
			
		||||
        {            
 | 
			
		||||
        public void PartyOustPlayer(string name)
 | 
			
		||||
        {
 | 
			
		||||
            SubPacket oustPacket = PartyModifyPacket.BuildPacket(playerSession, 1, name);
 | 
			
		||||
            QueuePacket(oustPacket);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PartyLeave()
 | 
			
		||||
@@ -1302,8 +1305,10 @@ namespace FFXIVClassic_Map_Server.Actors
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void PartyPromote()
 | 
			
		||||
        public void PartyPromote(string name)
 | 
			
		||||
        {
 | 
			
		||||
            SubPacket promotePacket = PartyModifyPacket.BuildPacket(playerSession, 0, name);
 | 
			
		||||
            QueuePacket(promotePacket);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //A party member list packet came, set the party
 | 
			
		||||
 
 | 
			
		||||
@@ -20,14 +20,14 @@ namespace FFXIVClassic_Map_Server.actors.group
 | 
			
		||||
            members.Add(leaderCharaId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetLeader(uint actorId)
 | 
			
		||||
        public void SetLeader(uint leaderCharaId)
 | 
			
		||||
        {
 | 
			
		||||
            partyGroupWork._globalTemp.owner = (ulong)((actorId << 32) | 0xB36F92);
 | 
			
		||||
            partyGroupWork._globalTemp.owner = (ulong)(((ulong)leaderCharaId << 32) | 0xB36F92);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public uint GetLeader()
 | 
			
		||||
        {
 | 
			
		||||
            return (uint)((partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF);
 | 
			
		||||
            return (uint)((ulong)(partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public bool IsInParty(uint charaId)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,11 +25,10 @@ namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        partyGroupId = binReader.ReadUInt64();
 | 
			
		||||
                        uint owner = binReader.ReadUInt32();
 | 
			
		||||
                        owner = binReader.ReadUInt32();
 | 
			
		||||
                        uint numMembers = binReader.ReadUInt32();
 | 
			
		||||
                        memberActorIds = new uint[numMembers];
 | 
			
		||||
 | 
			
		||||
                        PartyGroup group = new PartyGroup(partyGroupId, owner);
 | 
			
		||||
                        
 | 
			
		||||
                        for (int i = 0; i < numMembers; i++)                        
 | 
			
		||||
                            memberActorIds[i] = binReader.ReadUInt32();                        
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,30 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_Map_Server.Actors;
 | 
			
		||||
using FFXIVClassic_Map_Server.dataobjects;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group
 | 
			
		||||
{
 | 
			
		||||
    class PartyModifyPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const ushort OPCODE = 0x1020;
 | 
			
		||||
        public const uint PACKET_SIZE = 0x48;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(Session session, ushort command, string name)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[PACKET_SIZE - 0x20];
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt16)command);
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(name), 0, Encoding.ASCII.GetByteCount(name) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(name));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return new SubPacket(true, OPCODE, session.id, session.id, data);
 | 
			
		||||
        }      
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -23,15 +23,15 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                    binWriter.Write((UInt32)group.groupTypeId);
 | 
			
		||||
                    binWriter.Write((Int32)group.localizedNamed);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
                    binWriter.Write((UInt32)group.GetTypeId());
 | 
			
		||||
                    binWriter.Write((Int32)group.GetGroupLocalizedName());
 | 
			
		||||
 | 
			
		||||
                    binWriter.Write((UInt16)0x121C);
 | 
			
		||||
 | 
			
		||||
                    binWriter.Seek(0x20, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName));                    
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));                    
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,15 +33,15 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
 | 
			
		||||
                        Group group = groups[offset+i];
 | 
			
		||||
 | 
			
		||||
                        binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                        binWriter.Write((UInt32)group.groupTypeId);
 | 
			
		||||
                        binWriter.Write((Int32)group.localizedNamed);
 | 
			
		||||
                        binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
                        binWriter.Write((UInt32)group.GetTypeId());
 | 
			
		||||
                        binWriter.Write((Int32)group.GetGroupLocalizedName());
 | 
			
		||||
 | 
			
		||||
                        binWriter.Write((UInt16)0x121C);
 | 
			
		||||
 | 
			
		||||
                        binWriter.Seek(0x20, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
                        binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName));                    
 | 
			
		||||
                        binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));                    
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    binWriter.Seek(0x200, SeekOrigin.Begin);
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ namespace FFXIVClassic_Map_Server.packets.send.groups
 | 
			
		||||
 | 
			
		||||
        public static SubPacket buildPacket(uint playerActorID, Group group)
 | 
			
		||||
        {
 | 
			
		||||
            return buildPacket(playerActorID, group.groupId);
 | 
			
		||||
            return buildPacket(playerActorID, group.groupIndex);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket buildPacket(uint playerActorID, ulong groupId)
 | 
			
		||||
 
 | 
			
		||||
@@ -33,17 +33,17 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
 | 
			
		||||
                    //Write list id
 | 
			
		||||
                    binWriter.Write((UInt64)3);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
                    binWriter.Write((UInt64)0);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
 | 
			
		||||
                    //This seems to change depending on what the list is for
 | 
			
		||||
                    binWriter.Write((UInt32)group.groupTypeId);
 | 
			
		||||
                    binWriter.Write((UInt32)group.GetTypeId());
 | 
			
		||||
                    binWriter.Seek(0x40, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
                    //This is for Linkshell
 | 
			
		||||
                    binWriter.Write((UInt32)group.localizedNamed);
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(group.groupName), 0, Encoding.ASCII.GetByteCount(group.groupName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.groupName));
 | 
			
		||||
                    binWriter.Write((UInt32)group.GetGroupLocalizedName());
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(group.GetGroupName()), 0, Encoding.ASCII.GetByteCount(group.GetGroupName()) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(group.GetGroupName()));
 | 
			
		||||
 | 
			
		||||
                    binWriter.Seek(0x64, SeekOrigin.Begin);
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +52,7 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
                    binWriter.Write((UInt32)0x6D);
 | 
			
		||||
                    binWriter.Write((UInt32)0x6D);
 | 
			
		||||
 | 
			
		||||
                    binWriter.Write((UInt32)group.members.Count);
 | 
			
		||||
                    binWriter.Write((UInt32)group.GetMemberCount());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,8 +27,8 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
                    binWriter.Write((UInt64)locationCode);
 | 
			
		||||
                    binWriter.Write((UInt64)sequenceId);
 | 
			
		||||
                    //Write List Info
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                    binWriter.Write((UInt32)group.members.Count);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
                    binWriter.Write((UInt32)group.GetMemberCount());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ namespace FFXIVClassic_Map_Server.packets.send.group
 | 
			
		||||
                    binWriter.Write((UInt64)locationCode);
 | 
			
		||||
                    binWriter.Write((UInt64)sequenceId);
 | 
			
		||||
                    //Write List Info
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupId);
 | 
			
		||||
                    binWriter.Write((UInt64)group.groupIndex);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -48,6 +48,17 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
 | 
			
		||||
            return new List<GroupMember>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SendGroupPacketsAll(List<uint> sessionIds)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < sessionIds.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                Session session = Server.GetServer().GetSession(sessionIds[i]);
 | 
			
		||||
 | 
			
		||||
                if (session != null)
 | 
			
		||||
                    SendGroupPackets(session);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SendGroupPackets(Session session)
 | 
			
		||||
        {
 | 
			
		||||
            ulong time = Utils.MilisUnixTimeStampUTC();
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,90 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
 | 
			
		||||
            members.Add(leaderCharaId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetLeaderPlayerRequest(Session requestSession, string name)
 | 
			
		||||
        {
 | 
			
		||||
            if (GetLeader() != requestSession.sessionId)
 | 
			
		||||
            {
 | 
			
		||||
                requestSession.SendGameMessage(30428, 0x20, Server.GetServer().GetNameForId(requestSession.sessionId));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            uint newLeader = GetIdForName(name);
 | 
			
		||||
 | 
			
		||||
            if (newLeader == 0)
 | 
			
		||||
            {
 | 
			
		||||
                requestSession.SendGameMessage(30575, 0x20);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            else if (newLeader == GetLeader())
 | 
			
		||||
            {
 | 
			
		||||
                requestSession.SendGameMessage(30563, 0x20, name);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            SetLeader(newLeader);
 | 
			
		||||
            SendLeaderWorkToAllMembers();
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < members.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                Session session = Server.GetServer().GetSession(members[i]);
 | 
			
		||||
                if (session == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
                session.SendGameMessage(30429, 0x20, Server.GetServer().GetNameForId(members[i]));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Server.GetServer().GetWorldManager().SendPartySync(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void KickPlayerRequest(Session requestSession, string name)
 | 
			
		||||
        {
 | 
			
		||||
            if (GetLeader() != requestSession.sessionId)
 | 
			
		||||
            {
 | 
			
		||||
                requestSession.SendGameMessage(30428, 0x20, Server.GetServer().GetNameForId(requestSession.sessionId));
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            uint kickedMemberId = GetIdForName(name);
 | 
			
		||||
 | 
			
		||||
            if (kickedMemberId == 0)
 | 
			
		||||
            {
 | 
			
		||||
                requestSession.SendGameMessage(30575, 0x20);
 | 
			
		||||
                return;
 | 
			
		||||
            }           
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < members.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                Session session = Server.GetServer().GetSession(members[i]);
 | 
			
		||||
                if (session == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                if (members[i] == kickedMemberId)
 | 
			
		||||
                    session.SendGameMessage(30410, 0x20);
 | 
			
		||||
                else
 | 
			
		||||
                    session.SendGameMessage(30428, 0x20, (Object)name);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //All good, remove
 | 
			
		||||
            members.Remove(kickedMemberId);
 | 
			
		||||
            SendGroupPacketsAll(members);
 | 
			
		||||
            Server.GetServer().GetWorldManager().SendPartySync(this);            
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
        public void SendLeaderWorkToAllMembers()
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < members.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                SynchGroupWorkValuesPacket leaderUpdate = new SynchGroupWorkValuesPacket(groupIndex);
 | 
			
		||||
                leaderUpdate.addProperty(this, "partyGroupWork._globalTemp.owner");
 | 
			
		||||
                leaderUpdate.setTarget("partyGroupWork/leader");
 | 
			
		||||
                Session session = Server.GetServer().GetSession(members[i]);
 | 
			
		||||
                if (session == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
                else                
 | 
			
		||||
                    session.clientConnection.QueuePacket(leaderUpdate.buildPacket(session.sessionId, session.sessionId), true, false);                
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SetLeader(uint actorId)
 | 
			
		||||
        {
 | 
			
		||||
            partyGroupWork._globalTemp.owner = (ulong)((actorId << 32) | 0xB36F92);
 | 
			
		||||
@@ -30,10 +114,22 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
 | 
			
		||||
            return (uint)((partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        public uint GetIdForName(string name)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < members.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (Server.GetServer().GetNameForId(members[i]).Equals(name))
 | 
			
		||||
                {
 | 
			
		||||
                    return members[i];
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsInParty(uint charaId)
 | 
			
		||||
        {
 | 
			
		||||
            return members.Contains(charaId);
 | 
			
		||||
        }
 | 
			
		||||
        }        
 | 
			
		||||
 | 
			
		||||
        public override void SendInitWorkValues(Session session)
 | 
			
		||||
        {
 | 
			
		||||
@@ -64,5 +160,6 @@ namespace FFXIVClassic_World_Server.DataObjects.Group
 | 
			
		||||
            return groupMembers;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								FFXIVClassic World Server/DataObjects/LuaParam.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								FFXIVClassic World Server/DataObjects/LuaParam.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.DataObjects
 | 
			
		||||
{
 | 
			
		||||
    class LuaParam
 | 
			
		||||
    {
 | 
			
		||||
        public int typeID;
 | 
			
		||||
        public Object value;
 | 
			
		||||
 | 
			
		||||
        public LuaParam(int type, Object value)
 | 
			
		||||
        {
 | 
			
		||||
            this.typeID = type;
 | 
			
		||||
            this.value = value;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										380
									
								
								FFXIVClassic World Server/DataObjects/LuaUtils.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								FFXIVClassic World Server/DataObjects/LuaUtils.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,380 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.DataObjects
 | 
			
		||||
{
 | 
			
		||||
    class LuaUtils
 | 
			
		||||
    {
 | 
			
		||||
    
 | 
			
		||||
        public class Type7Param
 | 
			
		||||
        {
 | 
			
		||||
            public uint actorId;
 | 
			
		||||
            public byte unknown;
 | 
			
		||||
            public byte slot;
 | 
			
		||||
            public byte inventoryType;
 | 
			
		||||
 | 
			
		||||
            public Type7Param(uint actorId, byte unknown, byte slot, byte inventoryType)
 | 
			
		||||
            {
 | 
			
		||||
                this.actorId = actorId;
 | 
			
		||||
                this.unknown = unknown;
 | 
			
		||||
                this.slot = slot;
 | 
			
		||||
                this.inventoryType = inventoryType;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class Type9Param
 | 
			
		||||
        {
 | 
			
		||||
            public ulong item1;
 | 
			
		||||
            public ulong item2;
 | 
			
		||||
 | 
			
		||||
            public Type9Param(ulong item1, ulong item2)
 | 
			
		||||
            {
 | 
			
		||||
                this.item1 = item1;
 | 
			
		||||
                this.item2 = item2;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<LuaParam> ReadLuaParams(BinaryReader reader)
 | 
			
		||||
        {
 | 
			
		||||
            List<LuaParam> luaParams = new List<LuaParam>();
 | 
			
		||||
 | 
			
		||||
            bool isDone = false;
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                byte code = reader.ReadByte();
 | 
			
		||||
                object value = null;
 | 
			
		||||
                bool wasNil = false;
 | 
			
		||||
 | 
			
		||||
                switch (code)
 | 
			
		||||
                {
 | 
			
		||||
                    case 0x0: //Int32
 | 
			
		||||
                        value = Utils.SwapEndian(reader.ReadInt32());                        
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1: //Int32
 | 
			
		||||
                        value = Utils.SwapEndian(reader.ReadUInt32());        
 | 
			
		||||
                        break;          
 | 
			
		||||
                    case 0x2: //Null Termed String                        
 | 
			
		||||
                        List<byte> list = new List<byte>();
 | 
			
		||||
                        while(true){
 | 
			
		||||
                            byte readByte = reader.ReadByte();
 | 
			
		||||
                            if (readByte == 0)
 | 
			
		||||
                                break;
 | 
			
		||||
                            list.Add(readByte);
 | 
			
		||||
                        }
 | 
			
		||||
                        value = Encoding.ASCII.GetString(list.ToArray());
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x3: //Boolean True
 | 
			
		||||
                        value = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x4: //Boolean False
 | 
			
		||||
                        value = false;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x5: //Nil
 | 
			
		||||
                        wasNil = true;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x6: //Actor (By Id)
 | 
			
		||||
                        value = Utils.SwapEndian(reader.ReadUInt32());
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x7: //Weird one used for inventory
 | 
			
		||||
                        uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32());
 | 
			
		||||
                        byte type7Unknown = reader.ReadByte();
 | 
			
		||||
                        byte type7Slot = reader.ReadByte();
 | 
			
		||||
                        byte type7InventoryType = reader.ReadByte();
 | 
			
		||||
                        value = new Type7Param(type7ActorId, type7Unknown, type7Slot, type7InventoryType);
 | 
			
		||||
                        break;  
 | 
			
		||||
                    case 0x9: //Two Longs (only storing first one)
 | 
			
		||||
                        value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64()));
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xC: //Byte
 | 
			
		||||
                        value = reader.ReadByte();
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1B: //Short?
 | 
			
		||||
                        value = reader.ReadUInt16();
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xF: //End
 | 
			
		||||
                        isDone = true;
 | 
			
		||||
                        continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (isDone)
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                if (value != null)
 | 
			
		||||
                    luaParams.Add(new LuaParam(code, value));
 | 
			
		||||
                else if (wasNil)
 | 
			
		||||
                    luaParams.Add(new LuaParam(code, value));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return luaParams;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void WriteLuaParams(BinaryWriter writer, List<LuaParam> luaParams)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (LuaParam l in luaParams)
 | 
			
		||||
            {           
 | 
			
		||||
                if (l.typeID == 0x1)
 | 
			
		||||
                    writer.Write((Byte)0);
 | 
			
		||||
                else
 | 
			
		||||
                    writer.Write((Byte)l.typeID);
 | 
			
		||||
 | 
			
		||||
                switch (l.typeID)
 | 
			
		||||
                {
 | 
			
		||||
                    case 0x0: //Int32                        
 | 
			
		||||
                        writer.Write((Int32)Utils.SwapEndian((Int32)l.value));
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1: //Int32                        
 | 
			
		||||
                        writer.Write((UInt32)Utils.SwapEndian((UInt32)l.value));
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x2: //Null Termed String
 | 
			
		||||
                        string sv = (string)l.value;
 | 
			
		||||
                        writer.Write(Encoding.ASCII.GetBytes(sv), 0, Encoding.ASCII.GetByteCount(sv));
 | 
			
		||||
                        writer.Write((Byte)0);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x3: //Boolean True                        
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x4: //Boolean False                        
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x5: //Nil                        
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x6: //Actor (By Id)
 | 
			
		||||
                        writer.Write((UInt32)Utils.SwapEndian((UInt32)l.value));
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x7: //Weird one used for inventory
 | 
			
		||||
                        Type7Param type7 = (Type7Param)l.value;
 | 
			
		||||
                        writer.Write((UInt32)Utils.SwapEndian((UInt32)type7.actorId));
 | 
			
		||||
                        writer.Write((Byte)type7.unknown);
 | 
			
		||||
                        writer.Write((Byte)type7.slot);
 | 
			
		||||
                        writer.Write((Byte)type7.inventoryType);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x9: //Two Longs (only storing first one)
 | 
			
		||||
                        writer.Write((UInt64)Utils.SwapEndian(((Type9Param)l.value).item1));
 | 
			
		||||
                        writer.Write((UInt64)Utils.SwapEndian(((Type9Param)l.value).item2));
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xC: //Byte
 | 
			
		||||
                        writer.Write((Byte)l.value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1B: //Short?                        
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xF: //End                        
 | 
			
		||||
                        continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            writer.Write((Byte)0xF);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<LuaParam> ReadLuaParams(byte[] bytesIn)
 | 
			
		||||
        {
 | 
			
		||||
            List<LuaParam> luaParams = new List<LuaParam>();            
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream memStream = new MemoryStream(bytesIn))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryReader reader = new BinaryReader(memStream))
 | 
			
		||||
                {
 | 
			
		||||
                    bool isDone = false;
 | 
			
		||||
                    while (true)
 | 
			
		||||
                    {
 | 
			
		||||
                        byte code = reader.ReadByte();
 | 
			
		||||
                        object value = null;
 | 
			
		||||
                        bool wasNil = false;
 | 
			
		||||
 | 
			
		||||
                        switch (code)
 | 
			
		||||
                        {
 | 
			
		||||
                            case 0x0: //Int32
 | 
			
		||||
                                value = Utils.SwapEndian(reader.ReadInt32());
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x1: //Int32
 | 
			
		||||
                                value = Utils.SwapEndian(reader.ReadUInt32());
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x2: //Null Termed String                        
 | 
			
		||||
                                List<byte> list = new List<byte>();
 | 
			
		||||
                                while (true)
 | 
			
		||||
                                {
 | 
			
		||||
                                    byte readByte = reader.ReadByte();
 | 
			
		||||
                                    if (readByte == 0)
 | 
			
		||||
                                        break;
 | 
			
		||||
                                    list.Add(readByte);
 | 
			
		||||
                                }
 | 
			
		||||
                                value = Encoding.ASCII.GetString(list.ToArray());
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x3: //Boolean True
 | 
			
		||||
                                value = true;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x4: //Boolean False
 | 
			
		||||
                                value = false;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x5: //Nil
 | 
			
		||||
                                wasNil = true;
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x6: //Actor (By Id)
 | 
			
		||||
                                value = Utils.SwapEndian(reader.ReadUInt32());
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x7: //Weird one used for inventory
 | 
			
		||||
                                uint type7ActorId = Utils.SwapEndian(reader.ReadUInt32());
 | 
			
		||||
                                byte type7Unknown = reader.ReadByte();
 | 
			
		||||
                                byte type7Slot = reader.ReadByte();
 | 
			
		||||
                                byte type7InventoryType = reader.ReadByte();
 | 
			
		||||
                                value = new Type7Param(type7ActorId, type7Unknown, type7Slot, type7InventoryType);
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x9: //Two Longs (only storing first one)
 | 
			
		||||
                                value = new Type9Param(Utils.SwapEndian(reader.ReadUInt64()), Utils.SwapEndian(reader.ReadUInt64()));
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0xC: //Byte
 | 
			
		||||
                                value = reader.ReadByte();
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0x1B: //Short?
 | 
			
		||||
                                value = reader.ReadUInt16();
 | 
			
		||||
                                break;
 | 
			
		||||
                            case 0xF: //End
 | 
			
		||||
                                isDone = true;
 | 
			
		||||
                                continue;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (isDone)
 | 
			
		||||
                            break;
 | 
			
		||||
 | 
			
		||||
                        if (value != null)
 | 
			
		||||
                            luaParams.Add(new LuaParam(code, value));
 | 
			
		||||
                        else if (wasNil)
 | 
			
		||||
                            luaParams.Add(new LuaParam(code, value));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return luaParams;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static List<LuaParam> CreateLuaParamList(params object[] list)
 | 
			
		||||
        {
 | 
			
		||||
            List<LuaParam> luaParams = new List<LuaParam>();
 | 
			
		||||
 | 
			
		||||
            foreach (object o in list)
 | 
			
		||||
            {
 | 
			
		||||
                if (o != null && o.GetType().IsArray)
 | 
			
		||||
                {
 | 
			
		||||
                    Array arrayO = (Array)o;
 | 
			
		||||
                    foreach (object o2 in arrayO)
 | 
			
		||||
                        AddToList(o2, luaParams);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    AddToList(o, luaParams);                     
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return luaParams;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static void AddToList(object o, List<LuaParam> luaParams)
 | 
			
		||||
        {
 | 
			
		||||
            if (o is int)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x0, (int)o));
 | 
			
		||||
            }
 | 
			
		||||
            else if (o is uint)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x1, (uint)o));
 | 
			
		||||
            }                
 | 
			
		||||
            else if (o is Double)
 | 
			
		||||
            {
 | 
			
		||||
                if (((double)o) % 1 == 0)
 | 
			
		||||
                    luaParams.Add(new LuaParam(0x0, (int)(double)o));
 | 
			
		||||
            }
 | 
			
		||||
            else if (o is string)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x2, (string)o));
 | 
			
		||||
            }
 | 
			
		||||
            else if (o is bool)
 | 
			
		||||
            {
 | 
			
		||||
                if (((bool)o))
 | 
			
		||||
                    luaParams.Add(new LuaParam(0x3, null));
 | 
			
		||||
                else
 | 
			
		||||
                    luaParams.Add(new LuaParam(0x4, null));
 | 
			
		||||
            }
 | 
			
		||||
            else if (o == null)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x5, null));
 | 
			
		||||
            }            
 | 
			
		||||
            else if (o is Type7Param)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x7, (Type7Param)o)); 
 | 
			
		||||
            }
 | 
			
		||||
            else if (o is Type9Param)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0x9, (Type9Param)o));
 | 
			
		||||
            }
 | 
			
		||||
            else if (o is byte)
 | 
			
		||||
            {
 | 
			
		||||
                luaParams.Add(new LuaParam(0xC, (byte)o));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static object[] CreateLuaParamObjectList(List <LuaParam> luaParams)
 | 
			
		||||
        {
 | 
			
		||||
            object[] list = new object[luaParams.Count];
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < list.Length; i++)
 | 
			
		||||
                list[i] = luaParams[i].value;
 | 
			
		||||
 | 
			
		||||
            return list;
 | 
			
		||||
        }
 | 
			
		||||
    
 | 
			
		||||
      
 | 
			
		||||
        public static string DumpParams(List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            if (lParams == null)
 | 
			
		||||
                return "Param list was null?";
 | 
			
		||||
 | 
			
		||||
            string dumpString = "";
 | 
			
		||||
            for (int i = 0; i < lParams.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                switch (lParams[i].typeID)
 | 
			
		||||
                {
 | 
			
		||||
                    case 0x0: //Int32
 | 
			
		||||
                        dumpString += String.Format("0x{0:X}", (int)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1: //Int32
 | 
			
		||||
                        dumpString += String.Format("0x{0:X}", (uint)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x2: //Null Termed String                        
 | 
			
		||||
                        dumpString += String.Format("\"{0}\"", (string)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x3: //Boolean True
 | 
			
		||||
                        dumpString += "true";
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x4: //Boolean False
 | 
			
		||||
                        dumpString += "false";
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x5: //NULL???                        
 | 
			
		||||
                        dumpString += "nil";
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x6: //Actor (By Id)
 | 
			
		||||
                        dumpString += String.Format("0x{0:X}", (uint)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x7: //Weird one used for inventory
 | 
			
		||||
                        Type7Param type7Param = ((Type7Param)lParams[i].value);
 | 
			
		||||
                        dumpString += String.Format("Type7 Param: (0x{0:X}, 0x{1:X}, 0x{2:X}, 0x{3:X})", type7Param.actorId, type7Param.unknown, type7Param.slot, type7Param.inventoryType);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xC: //Byte
 | 
			
		||||
                        dumpString += String.Format("0x{0:X}", (byte)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x9: //Long (+ 8 bytes ignored)
 | 
			
		||||
                        Type9Param type9Param = ((Type9Param)lParams[i].value);
 | 
			
		||||
                        dumpString += String.Format("Type9 Param: (0x{0:X}, 0x{1:X})", type9Param.item1, type9Param.item2);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0x1B: //Short?
 | 
			
		||||
                        dumpString += String.Format("0x{0:X}", (ushort)lParams[i].value);
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 0xF: //End
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (i != lParams.Count - 1)
 | 
			
		||||
                    dumpString += ", ";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return dumpString;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
using System;
 | 
			
		||||
using FFXIVClassic_World_Server.Packets.Send.Subpackets;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Net.Sockets;
 | 
			
		||||
@@ -28,6 +29,30 @@ namespace FFXIVClassic_World_Server.DataObjects
 | 
			
		||||
            connection.owner = this;
 | 
			
		||||
            Database.LoadZoneSessionInfo(this);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
       
 | 
			
		||||
        public void SendGameMessage( ushort textId, byte log, params object[] msgParams)
 | 
			
		||||
        {
 | 
			
		||||
            if (msgParams == null || msgParams.Length == 0)
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, log), true, false);
 | 
			
		||||
            else
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, log, LuaUtils.CreateLuaParamList(msgParams)), true, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SendGameMessage( ushort textId, byte log, string customSender, params object[] msgParams)
 | 
			
		||||
        {
 | 
			
		||||
            if (msgParams == null || msgParams.Length == 0)
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, customSender, log), true, false);
 | 
			
		||||
            else
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, customSender, log, LuaUtils.CreateLuaParamList(msgParams)), true, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SendGameMessage(ushort textId, byte log, uint displayId, params object[] msgParams)
 | 
			
		||||
        {
 | 
			
		||||
            if (msgParams == null || msgParams.Length == 0)
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, displayId, log), true, false);
 | 
			
		||||
            else
 | 
			
		||||
                clientConnection.QueuePacket(GameMessagePacket.BuildPacket(0x5FF80001, sessionId, 0x5FF80001, textId, displayId, log, LuaUtils.CreateLuaParamList(msgParams)), true, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -193,6 +193,41 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
            return members;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Linkshell GetLinkshell(ulong groupIndex, string lsName)
 | 
			
		||||
        {
 | 
			
		||||
            using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
 | 
			
		||||
            {
 | 
			
		||||
                try
 | 
			
		||||
                {
 | 
			
		||||
                    conn.Open();
 | 
			
		||||
                    MySqlCommand cmd = new MySqlCommand("SELECT id, name, crestIcon, master FROM server_linkshells WHERE name = @lsName", conn);
 | 
			
		||||
                    cmd.Parameters.AddWithValue("@lsName", lsName);
 | 
			
		||||
                    using (MySqlDataReader Reader = cmd.ExecuteReader())
 | 
			
		||||
                    {
 | 
			
		||||
                        while (Reader.Read())
 | 
			
		||||
                        {
 | 
			
		||||
                            ulong lsId = Reader.GetUInt64("id");
 | 
			
		||||
                            string name = Reader.GetString("name");
 | 
			
		||||
                            ushort crest = Reader.GetUInt16("crestIcon");
 | 
			
		||||
                            uint master = Reader.GetUInt32("master");
 | 
			
		||||
 | 
			
		||||
                            Linkshell linkshell = new Linkshell(lsId, groupIndex, name, crest, master, 0xa);
 | 
			
		||||
                            return linkshell;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                catch (MySqlException e)
 | 
			
		||||
                {
 | 
			
		||||
                    Program.Log.Error(e.ToString());
 | 
			
		||||
                }
 | 
			
		||||
                finally
 | 
			
		||||
                {
 | 
			
		||||
                    conn.Dispose();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Linkshell GetLinkshell(ulong groupIndex, ulong lsId)
 | 
			
		||||
        {
 | 
			
		||||
            using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD)))
 | 
			
		||||
 
 | 
			
		||||
@@ -83,12 +83,15 @@
 | 
			
		||||
    <Compile Include="DataObjects\Group\Relation.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\Group\RetainerGroup.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\Group\RetainerGroupMember.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\LuaParam.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\LuaUtils.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\ZoneServer.cs" />
 | 
			
		||||
    <Compile Include="DataObjects\Session.cs" />
 | 
			
		||||
    <Compile Include="LinkshellManager.cs" />
 | 
			
		||||
    <Compile Include="PacketProcessor.cs" />
 | 
			
		||||
    <Compile Include="Packets\Receive\HelloPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\Receive\Subpackets\GroupCreatedPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\Subpackets\GameMessagePacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\Subpackets\Groups\CreateNamedGroup.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\Subpackets\Groups\CreateNamedGroupMultiple.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\Subpackets\Groups\DeleteGroupPacket.cs" />
 | 
			
		||||
@@ -105,22 +108,19 @@
 | 
			
		||||
    <Compile Include="Packets\Send\_0x2Packet.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\_0x7Packet.cs" />
 | 
			
		||||
    <Compile Include="Packets\Send\_0x8PingPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\PartyLeavePacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\PartyModifyPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\SetActiveLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\ModifyLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\CreateRelationPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\CreateLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\GetGroupPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\DeleteLinkshellPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\Group\GroupMemberChangePacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\SessionBeginConfirmPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\WorldRequestZoneChangePacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Receive\SessionEndConfirmPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\ErrorPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\Group\PartySyncPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\Group\GroupWorkValuesPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\Group\GroupMemberListPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\Group\GroupMemberListEndPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\Group\GroupMemberListStartPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\SessionBeginPacket.cs" />
 | 
			
		||||
    <Compile Include="Packets\WorldPackets\Send\SessionEndPacket.cs" />
 | 
			
		||||
    <Compile Include="PartyManager.cs" />
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,10 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
    {
 | 
			
		||||
        private WorldManager mWorldManager;
 | 
			
		||||
        private Object mGroupLockReference;
 | 
			
		||||
        private Dictionary<ulong, Group> mCurrentWorldGroupsReference;
 | 
			
		||||
        private Dictionary<ulong, Linkshell> mLinkshellList = new Dictionary<ulong, Linkshell>();
 | 
			
		||||
        private Dictionary<string, ulong> mNameToIdLookup = new Dictionary<string, ulong>();
 | 
			
		||||
        private Dictionary<ulong, Group> mCurrentWorldGroupsReference; //GroupId, LS
 | 
			
		||||
        private Dictionary<ulong, Linkshell> mLinkshellList = new Dictionary<ulong, Linkshell>(); //GroupId, LS
 | 
			
		||||
        private Dictionary<ulong, Linkshell> mLSIdToIdLookup = new Dictionary<ulong, Linkshell>(); //Name, GroupId
 | 
			
		||||
        private Dictionary<string, ulong> mNameToIdLookup = new Dictionary<string, ulong>(); //Name, GroupId
 | 
			
		||||
 | 
			
		||||
        public LinkshellManager(WorldManager worldManager, Object groupLock, Dictionary<ulong, Group> worldGroupList)
 | 
			
		||||
        {
 | 
			
		||||
@@ -162,14 +163,31 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
            if (mNameToIdLookup.ContainsKey(name))
 | 
			
		||||
                return (Linkshell)mCurrentWorldGroupsReference[mNameToIdLookup[name]];
 | 
			
		||||
            else
 | 
			
		||||
                return null;
 | 
			
		||||
            {
 | 
			
		||||
                lock (mGroupLockReference)
 | 
			
		||||
                {
 | 
			
		||||
                    Linkshell ls = Database.GetLinkshell(mWorldManager.GetGroupIndex(), name);
 | 
			
		||||
                    ls.LoadMembers();
 | 
			
		||||
 | 
			
		||||
                    if (ls != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        mLinkshellList.Add(ls.groupIndex, ls);
 | 
			
		||||
                        mNameToIdLookup.Add(ls.name, ls.groupIndex);
 | 
			
		||||
                        mCurrentWorldGroupsReference.Add(ls.groupIndex, ls);
 | 
			
		||||
                        mWorldManager.IncrementGroupIndex();
 | 
			
		||||
                        return ls;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                        return null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Get a single linkshell group either already instantiated or make one from the db
 | 
			
		||||
        public Linkshell GetLinkshell(ulong lsId)
 | 
			
		||||
        {
 | 
			
		||||
            if (mLinkshellList.ContainsKey(lsId))
 | 
			
		||||
                return mLinkshellList[lsId];
 | 
			
		||||
            if (mLSIdToIdLookup.ContainsKey(lsId))
 | 
			
		||||
                return mLSIdToIdLookup[lsId];
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                lock (mGroupLockReference)
 | 
			
		||||
@@ -181,6 +199,7 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
                    {                        
 | 
			
		||||
                        mLinkshellList.Add(ls.groupIndex, ls);
 | 
			
		||||
                        mNameToIdLookup.Add(ls.name, ls.groupIndex);
 | 
			
		||||
                        mLSIdToIdLookup.Add(ls.dbId, ls);
 | 
			
		||||
                        mCurrentWorldGroupsReference.Add(ls.groupIndex, ls);
 | 
			
		||||
                        mWorldManager.IncrementGroupIndex();
 | 
			
		||||
                        return ls;
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,348 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_World_Server.DataObjects;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.Send.Subpackets
 | 
			
		||||
{
 | 
			
		||||
    class GameMessagePacket
 | 
			
		||||
    {        
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR1 = 0x157;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR2 = 0x158;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR3 = 0x159;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR4 = 0x15a;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_ACTOR5 = 0x15b;
 | 
			
		||||
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x15c;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x15d;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x15e;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x15f;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x160;
 | 
			
		||||
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x161;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x162;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x163;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x164;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x165;
 | 
			
		||||
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x166;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x167;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x168;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x169;
 | 
			
		||||
        private const ushort OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x16a;
 | 
			
		||||
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_ACTOR1 = 0x30;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_ACTOR2 = 0x38;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_ACTOR3 = 0x40;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_ACTOR4 = 0x50;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_ACTOR5 = 0x70;
 | 
			
		||||
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 = 0x48;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 = 0x58;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 = 0x68;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 = 0x78;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 = 0x98;
 | 
			
		||||
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 = 0x30;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 = 0x38;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 = 0x40;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 = 0x50;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 = 0x60;
 | 
			
		||||
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 = 0x28;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 = 0x38;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 = 0x38;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 = 0x48;
 | 
			
		||||
        private const ushort SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 = 0x68;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR1 - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {                    
 | 
			
		||||
                    binWriter.Write((UInt32)actorId);
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(OPCODE_GAMEMESSAGE_WITH_ACTOR1, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint actorId, uint textOwnerActorId, ushort textId, byte log, List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            int lParamsSize = findSizeOfParams(lParams);
 | 
			
		||||
            byte[] data;
 | 
			
		||||
            ushort opcode;
 | 
			
		||||
 | 
			
		||||
            if (lParamsSize <= 0x8)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR2 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR2;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x10)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR3 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR3;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x20)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR4 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_ACTOR5 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_ACTOR5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)actorId);
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                    LuaUtils.WriteLuaParams(binWriter, lParams);
 | 
			
		||||
 | 
			
		||||
                    if (lParamsSize <= 0x14-12)
 | 
			
		||||
                    {
 | 
			
		||||
                        binWriter.Seek(0x14, SeekOrigin.Begin);
 | 
			
		||||
                        binWriter.Write((UInt32)8);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(opcode, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER1 - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER1, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, string sender, byte log, List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            int lParamsSize = findSizeOfParams(lParams);
 | 
			
		||||
            byte[] data;
 | 
			
		||||
            ushort opcode;
 | 
			
		||||
 | 
			
		||||
            if (lParamsSize <= 0x8)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER2 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER2;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x10)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER3 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER3;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x20)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER4 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_CUSTOM_SENDER5 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_CUSTOM_SENDER5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                    binWriter.Write(Encoding.ASCII.GetBytes(sender), 0, Encoding.ASCII.GetByteCount(sender) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(sender));
 | 
			
		||||
                    LuaUtils.WriteLuaParams(binWriter, lParams);
 | 
			
		||||
 | 
			
		||||
                    if (lParamsSize <= 0x14 - 12)
 | 
			
		||||
                    {
 | 
			
		||||
                        binWriter.Seek(0x30, SeekOrigin.Begin);
 | 
			
		||||
                        binWriter.Write((UInt32)8);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(opcode, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER1 - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)senderDisplayNameId);
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER1, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, uint senderDisplayNameId, byte log, List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            int lParamsSize = findSizeOfParams(lParams);
 | 
			
		||||
            byte[] data;
 | 
			
		||||
            ushort opcode;
 | 
			
		||||
 | 
			
		||||
            if (lParamsSize <= 0x8)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER2 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER2;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x10)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER3 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER3;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x20)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER4 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITH_DISPID_SENDER5 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITH_DISPID_SENDER5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)senderDisplayNameId);
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                    LuaUtils.WriteLuaParams(binWriter, lParams);
 | 
			
		||||
 | 
			
		||||
                    if (lParamsSize <= 0x14 - 12)
 | 
			
		||||
                    {
 | 
			
		||||
                        binWriter.Seek(0x14, SeekOrigin.Begin);
 | 
			
		||||
                        binWriter.Write((UInt32)8);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(opcode, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR1 - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(OPCODE_GAMEMESSAGE_WITHOUT_ACTOR1, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(uint sourceId, uint targetId, uint textOwnerActorId, ushort textId, byte log, List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            int lParamsSize = findSizeOfParams(lParams);
 | 
			
		||||
            byte[] data;
 | 
			
		||||
            ushort opcode;
 | 
			
		||||
 | 
			
		||||
            if (lParamsSize <= 0x8)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR2 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR2;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x10)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR3 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR3;
 | 
			
		||||
            }
 | 
			
		||||
            else if (lParamsSize <= 0x20)
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR4 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR4;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                data = new byte[SIZE_GAMEMESSAGE_WITHOUT_ACTOR5 - 0x20];
 | 
			
		||||
                opcode = OPCODE_GAMEMESSAGE_WITHOUT_ACTOR5;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32)textOwnerActorId);
 | 
			
		||||
                    binWriter.Write((UInt16)textId);
 | 
			
		||||
                    binWriter.Write((UInt16)log);
 | 
			
		||||
                    LuaUtils.WriteLuaParams(binWriter, lParams);
 | 
			
		||||
 | 
			
		||||
                    if (lParamsSize <= 0x8)
 | 
			
		||||
                    {
 | 
			
		||||
                        binWriter.Seek(0x10, SeekOrigin.Begin);
 | 
			
		||||
                        binWriter.Write((UInt32)8);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(opcode, sourceId, targetId, data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static int findSizeOfParams(List<LuaParam> lParams)
 | 
			
		||||
        {
 | 
			
		||||
            int total = 0;
 | 
			
		||||
            foreach (LuaParam l in lParams)
 | 
			
		||||
            {
 | 
			
		||||
                switch (l.typeID)
 | 
			
		||||
                {
 | 
			
		||||
                    case 0:
 | 
			
		||||
                    case 1:
 | 
			
		||||
                    case 2:
 | 
			
		||||
                        total += 1 + 0x20;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 6:
 | 
			
		||||
                        total += 5;
 | 
			
		||||
                        break;
 | 
			
		||||
                    case 3:
 | 
			
		||||
                    case 4:
 | 
			
		||||
                    case 5:
 | 
			
		||||
                        total += 1;
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return total + 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,32 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group
 | 
			
		||||
{
 | 
			
		||||
    class PartyLeavePacket
 | 
			
		||||
    {
 | 
			
		||||
        public bool invalidPacket = false;
 | 
			
		||||
                
 | 
			
		||||
        public bool isDisband;
 | 
			
		||||
 | 
			
		||||
        public PartyLeavePacket(byte[] data)
 | 
			
		||||
        {
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryReader binReader = new BinaryReader(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        isDisband = binReader.ReadByte() == 1;
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception)
 | 
			
		||||
                    {
 | 
			
		||||
                        invalidPacket = true;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +1,21 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group
 | 
			
		||||
{
 | 
			
		||||
    class GroupMemberChangePacket
 | 
			
		||||
    class PartyModifyPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const int GROUP_MEMBER_ADD = 0;
 | 
			
		||||
        public const int GROUP_MEMBER_REMOVE = 0;
 | 
			
		||||
 | 
			
		||||
        public bool invalidPacket = false;
 | 
			
		||||
        public uint controlCode;
 | 
			
		||||
        public ulong groupId;
 | 
			
		||||
        public uint memberId;
 | 
			
		||||
 | 
			
		||||
        public GroupMemberChangePacket(byte[] data)
 | 
			
		||||
        public const ushort MODIFY_LEADER = 0;
 | 
			
		||||
        public const ushort MODIFY_KICKPLAYER = 1;
 | 
			
		||||
 | 
			
		||||
        public ushort command;
 | 
			
		||||
        public string name;
 | 
			
		||||
 | 
			
		||||
        public PartyModifyPacket(byte[] data)
 | 
			
		||||
        {
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
@@ -21,9 +23,8 @@ namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive.Group
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
                    {
 | 
			
		||||
                        controlCode = binReader.ReadUInt32();
 | 
			
		||||
                        groupId = binReader.ReadUInt64();
 | 
			
		||||
                        memberId = binReader.ReadUInt32();
 | 
			
		||||
                        command = binReader.ReadUInt16();
 | 
			
		||||
                        name = Encoding.ASCII.GetString(binReader.ReadBytes(0x20)).Trim(new[] { '\0' });
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_World_Server.DataObjects;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group
 | 
			
		||||
{
 | 
			
		||||
    class GroupMemberListEndPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const ushort OPCODE = 0x1022;
 | 
			
		||||
        public const uint PACKET_SIZE = 0x28;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(Session session, ulong groupId)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[PACKET_SIZE - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt64)groupId);                    
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(true, OPCODE, 0, session.sessionId, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_World_Server.DataObjects;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group
 | 
			
		||||
{
 | 
			
		||||
    class GroupMemberListPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const ushort OPCODE = 0x1021;
 | 
			
		||||
        public const uint PACKET_SIZE = 0x2C;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(Session session, ulong groupId, uint numMembersInPacket)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[PACKET_SIZE - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt64)groupId);
 | 
			
		||||
                    binWriter.Write((UInt32)numMembersInPacket);
 | 
			
		||||
 | 
			
		||||
                    //Members
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(true, OPCODE, 0, session.sessionId, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_World_Server.DataObjects;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group
 | 
			
		||||
{
 | 
			
		||||
    class GroupMemberListStartPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const ushort OPCODE = 0x1020;
 | 
			
		||||
        public const uint PACKET_SIZE = 0x30;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(Session session, int resultCode, ulong groupId, int numMembers)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[PACKET_SIZE - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt32) resultCode);
 | 
			
		||||
                    binWriter.Write((UInt64) groupId);
 | 
			
		||||
                    binWriter.Write((UInt32) numMembers);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(true, OPCODE, 0, session.sessionId, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,29 +0,0 @@
 | 
			
		||||
using FFXIVClassic.Common;
 | 
			
		||||
using FFXIVClassic_World_Server.DataObjects;
 | 
			
		||||
using System;
 | 
			
		||||
using System.IO;
 | 
			
		||||
 | 
			
		||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group
 | 
			
		||||
{
 | 
			
		||||
    class GroupWorkValuesPacket
 | 
			
		||||
    {
 | 
			
		||||
        public const ushort OPCODE = 0x1023;
 | 
			
		||||
        public const uint PACKET_SIZE = 0x80;
 | 
			
		||||
 | 
			
		||||
        public static SubPacket BuildPacket(Session session, ulong groupId)
 | 
			
		||||
        {
 | 
			
		||||
            byte[] data = new byte[PACKET_SIZE - 0x20];
 | 
			
		||||
 | 
			
		||||
            using (MemoryStream mem = new MemoryStream(data))
 | 
			
		||||
            {
 | 
			
		||||
                using (BinaryWriter binWriter = new BinaryWriter(mem))
 | 
			
		||||
                {
 | 
			
		||||
                    binWriter.Write((UInt64)groupId);
 | 
			
		||||
                    //Write data
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new SubPacket(true, OPCODE, 0, session.sessionId, data);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -199,7 +199,25 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
                            GetWorldManager().DoZoneServerChange(session, zoneChangePacket.destinationZoneId, "", zoneChangePacket.destinationSpawnType, zoneChangePacket.destinationX, zoneChangePacket.destinationY, zoneChangePacket.destinationZ, zoneChangePacket.destinationRot);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        break;                    
 | 
			
		||||
                        break;
 | 
			
		||||
                    //Change leader or kick
 | 
			
		||||
                    case 0x1020:
 | 
			
		||||
                        PartyModifyPacket partyModifyPacket = new PartyModifyPacket(subpacket.data);
 | 
			
		||||
 | 
			
		||||
                        Party pt = mWorldManager.GetPartyManager().GetParty(subpacket.header.targetId);
 | 
			
		||||
 | 
			
		||||
                        if (pt.GetMemberCount() <= 1)
 | 
			
		||||
                            return;
 | 
			
		||||
                    
 | 
			
		||||
                        if (partyModifyPacket.command == PartyModifyPacket.MODIFY_LEADER)                        
 | 
			
		||||
                            pt.SetLeaderPlayerRequest(GetSession(subpacket.header.sourceId), partyModifyPacket.name);                        
 | 
			
		||||
                        else if (partyModifyPacket.command == PartyModifyPacket.MODIFY_KICKPLAYER)
 | 
			
		||||
                            pt.KickPlayerRequest(GetSession(subpacket.header.sourceId), partyModifyPacket.name); 
 | 
			
		||||
 | 
			
		||||
                        break;
 | 
			
		||||
                    //Party Resign or Disband
 | 
			
		||||
                    case 0x1021:
 | 
			
		||||
                        break;
 | 
			
		||||
                    //Linkshell create request
 | 
			
		||||
                    case 0x1025:
 | 
			
		||||
                        CreateLinkshellPacket createLinkshellPacket = new CreateLinkshellPacket(subpacket.data);
 | 
			
		||||
 
 | 
			
		||||
@@ -212,13 +212,13 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
 | 
			
		||||
            //Send party, retainer, ls groups
 | 
			
		||||
            Party pt = mPartyManager.GetParty(session.sessionId);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 156);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 157);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 158);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 159);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 160);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 161);
 | 
			
		||||
            mPartyManager.AddToParty(pt.groupIndex, 162);
 | 
			
		||||
 | 
			
		||||
            
 | 
			
		||||
            if (session.sessionId == 0x6c)
 | 
			
		||||
            {
 | 
			
		||||
                mPartyManager.AddToParty(pt.groupIndex, 156);
 | 
			
		||||
            }
 | 
			
		||||
             
 | 
			
		||||
            pt.SendGroupPackets(session);
 | 
			
		||||
            SendPartySync(pt);
 | 
			
		||||
            mRetainerGroupManager.GetRetainerGroup(session.sessionId).SendGroupPackets(session);
 | 
			
		||||
@@ -238,12 +238,18 @@ namespace FFXIVClassic_World_Server
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SendPartySync(Party party)
 | 
			
		||||
        {            
 | 
			
		||||
        {
 | 
			
		||||
            List<ZoneServer> alreadySent = new List<ZoneServer>();
 | 
			
		||||
            foreach (uint member in party.members)
 | 
			
		||||
            {
 | 
			
		||||
                Session session = Server.GetServer().GetSession(member);                
 | 
			
		||||
                if (session == null)
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                if (alreadySent.Contains(session.routing1))
 | 
			
		||||
                    continue;
 | 
			
		||||
 | 
			
		||||
                alreadySent.Add(session.routing1);
 | 
			
		||||
                SubPacket syncPacket = PartySyncPacket.BuildPacket(session, party);
 | 
			
		||||
                session.routing1.SendPacket(syncPacket);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user