diff --git a/FFXIVClassic Map Server/ConfigConstants.cs b/FFXIVClassic Map Server/ConfigConstants.cs index c3ea8d54..a9717dd2 100644 --- a/FFXIVClassic Map Server/ConfigConstants.cs +++ b/FFXIVClassic Map Server/ConfigConstants.cs @@ -10,7 +10,6 @@ namespace FFXIVClassic_Map_Server public static String OPTIONS_PORT; public static bool OPTIONS_TIMESTAMP = false; - public static uint DATABASE_WORLDID; public static String DATABASE_HOST; public static String DATABASE_PORT; public static String DATABASE_NAME; @@ -33,7 +32,6 @@ namespace FFXIVClassic_Map_Server ConfigConstants.OPTIONS_PORT = configIni.GetValue("General", "server_port", "1989"); ConfigConstants.OPTIONS_TIMESTAMP = configIni.GetValue("General", "showtimestamp", "true").ToLower().Equals("true"); - ConfigConstants.DATABASE_WORLDID = UInt32.Parse(configIni.GetValue("Database", "worldid", "0")); ConfigConstants.DATABASE_HOST = configIni.GetValue("Database", "host", ""); ConfigConstants.DATABASE_PORT = configIni.GetValue("Database", "port", ""); ConfigConstants.DATABASE_NAME = configIni.GetValue("Database", "database", ""); diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 39a41099..3c11d4d6 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -45,30 +45,7 @@ namespace FFXIVClassic_Map_Server } } return id; - } - - public static DBWorld GetServer(uint serverId) - { - using (var 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))) - { - DBWorld world = null; - try - { - conn.Open(); - world = conn.Query("SELECT * FROM servers WHERE id=@ServerId", new {ServerId = serverId}).SingleOrDefault(); - } - catch (MySqlException e) - { - Program.Log.Error(e.ToString()); - } - finally - { - conn.Dispose(); - } - - return world; - } - } + } public static List GetNpcList() { diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 862dba9c..74bfe102 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -123,7 +123,6 @@ - @@ -283,6 +282,7 @@ + diff --git a/FFXIVClassic Map Server/Program.cs b/FFXIVClassic Map Server/Program.cs index 921278a1..21932165 100644 --- a/FFXIVClassic Map Server/Program.cs +++ b/FFXIVClassic Map Server/Program.cs @@ -51,14 +51,7 @@ namespace FFXIVClassic_Map_Server startServer = false; } } - - //Check World ID - DBWorld thisWorld = Database.GetServer(ConfigConstants.DATABASE_WORLDID); - if (thisWorld != null) - Program.Log.Info("Successfully pulled world info from DB. Server name is {0}.", thisWorld.name); - else - Program.Log.Info("World info could not be retrieved from the DB. Welcome and MOTD will not be displayed."); - + //Start server if A-OK if (startServer) { diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 75b4887b..5e1f9f2f 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -16,13 +16,10 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -<<<<<<< HEAD -using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group; -======= using FFXIVClassic_Map_Server.actors.group; using FFXIVClassic_Map_Server.packets.send.group; using FFXIVClassic_Map_Server.packets.WorldPackets.Receive; ->>>>>>> 2bdc238bc2ab3e4f397e0a61d8ab9cc2b2d7d590 +using FFXIVClassic_Map_Server.packets.WorldPackets.Send.Group; namespace FFXIVClassic_Map_Server { @@ -34,7 +31,7 @@ namespace FFXIVClassic_Map_Server private Dictionary> seamlessBoundryList; private Dictionary zoneEntranceList; private Dictionary actorClasses = new Dictionary(); - private Dictionary currentPlayerParties = new Dictionary(); //GroupId, Party object + private Dictionary currentPlayerParties = new Dictionary(); //GroupId, Party object private Server mServer; @@ -703,42 +700,34 @@ 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) { - PartyGroup group; - List members = new List(); - - //Build member list for players on this server - foreach (uint actorId in syncPacket.memberActorIds) - { - Player p = GetPCInWorld(actorId); - - if (p == null) - continue; - - GroupMember member = new GroupMember(actorId, -1, 0, false, true, p.customDisplayName); - members.Add(member); - } + Party group; //If no members on this server, get out or clean - if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && members.Count == 0) + if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0) return; - else if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && members.Count == 0) + else if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId) && syncPacket.memberActorIds.Length == 0) NoMembersInParty(currentPlayerParties[syncPacket.partyGroupId]); //Get or create group if (!currentPlayerParties.ContainsKey(syncPacket.partyGroupId)) { - group = new PartyGroup(syncPacket.partyGroupId, syncPacket.owner); + group = new Party(syncPacket.partyGroupId, syncPacket.owner); currentPlayerParties.Add(syncPacket.partyGroupId, group); } else group = currentPlayerParties[syncPacket.partyGroupId]; - currentPlayerParties[syncPacket.partyGroupId].members = members; + currentPlayerParties[syncPacket.partyGroupId].members = syncPacket.memberActorIds.ToList(); //Add group to everyone - foreach (GroupMember member in members) + foreach (uint member in currentPlayerParties[syncPacket.partyGroupId].members) { - Player player = GetPCInWorld(member.actorId); + Session session = Server.GetServer().GetSession(member); + + if (session == null) + continue; + + Player player = session.GetActor(); if (player == null) continue; player.SetParty(group); @@ -746,10 +735,10 @@ namespace FFXIVClassic_Map_Server } //Player was removed from the party either due to leaving it or leaving the server. Remove if empty. - public void NoMembersInParty(PartyGroup party) + public void NoMembersInParty(Party party) { - if (currentPlayerParties.ContainsKey(party.groupId)) - currentPlayerParties.Remove(party.groupId); + if (currentPlayerParties.ContainsKey(party.groupIndex)) + currentPlayerParties.Remove(party.groupIndex); } public Player GetPCInWorld(string name) diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 56ca1d47..84afd6d5 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -1274,10 +1274,42 @@ namespace FFXIVClassic_Map_Server.Actors playerSession.UpdateInstance(aroundMe); } - //A party member list packet came, set the party - public void SetParty(PartyGroup group) + public bool IsInParty() { - if (group is PartyGroup) + return currentParty != null; + } + + public bool IsPartyLeader() + { + if (IsInParty()) + { + Party party = (Party)currentParty; + return party.GetLeader() == actorId; + } + else + return false; + } + + public void PartyOustPlayer() + { + } + + public void PartyLeave() + { + } + + public void PartyDisband() + { + } + + public void PartyPromote() + { + } + + //A party member list packet came, set the party + public void SetParty(Party group) + { + if (group is Party) { RemoveFromCurrentPartyAndCleanup(); currentParty = group; @@ -1290,18 +1322,20 @@ namespace FFXIVClassic_Map_Server.Actors if (currentParty == null) return; - for (int i = 0; i < currentParty.members.Count; i++) + Party partyGroup = (Party) currentParty; + + for (int i = 0; i < partyGroup.members.Count; i++) { - if (currentParty.members[i].actorId == actorId) + if (partyGroup.members[i] == actorId) { - currentParty.members.RemoveAt(i); + partyGroup.members.RemoveAt(i); break; } } //currentParty.members.Remove(this); - if (currentParty.members.Count == 0) - Server.GetWorldManager().NoMembersInParty((PartyGroup)currentParty); + if (partyGroup.members.Count == 0) + Server.GetWorldManager().NoMembersInParty((Party)currentParty); currentParty = null; } diff --git a/FFXIVClassic Map Server/actors/group/Group.cs b/FFXIVClassic Map Server/actors/group/Group.cs index 3fb2a774..91c6fde5 100644 --- a/FFXIVClassic Map Server/actors/group/Group.cs +++ b/FFXIVClassic Map Server/actors/group/Group.cs @@ -1,91 +1,85 @@ using FFXIVClassic.Common; -using FFXIVClassic_Map_Server.actors.group.work; -using FFXIVClassic_Map_Server.Actors; -using FFXIVClassic_Map_Server.packets.send.actor; +using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.packets.send.group; -using FFXIVClassic_Map_Server.packets.send.groups; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace FFXIVClassic_Map_Server.actors.group { class Group { public const uint PlayerPartyGroup = 10001; - public const uint CompanyGroup = 20001; + public const uint CompanyGroup = 20002; public const uint GroupInvitationRelationGroup = 50001; public const uint TradeRelationGroup = 50002; public const uint BazaarBuyItemRelationGroup = 50009; - + public const uint RetainerGroup = 80001; - public ulong groupId; - public uint groupTypeId; - public int localizedNamed = -1; - public string groupName = ""; - - public List members = new List(); - - public Group(ulong id, uint typeId) + public readonly ulong groupIndex; + + public Group(ulong groupIndex) { - groupId = id; - groupTypeId = typeId; + this.groupIndex = groupIndex; } - public Group(ulong id, uint typeId, int nameId, object work) + public virtual int GetMemberCount() { - groupId = id; - groupTypeId = typeId; - localizedNamed = nameId; + return 0; } - public Group(ulong id, uint typeId, string name, object work) + public virtual uint GetTypeId() { - groupId = id; - groupTypeId = typeId; - groupName = name; - localizedNamed = -1; + return 0; } - public void add(Actor actor) + public virtual string GetGroupName() { - GroupMember member = new GroupMember(actor.actorId, (int)actor.displayNameId, 0, false, true, actor.customDisplayName); - members.Add(member); + return ""; } - public void sendMemberPackets(Player toPlayer) + public virtual int GetGroupLocalizedName() + { + return -1; + } + + public virtual List BuildMemberList() + { + return new List(); + } + + public void SendGroupPackets(Session session) { ulong time = Utils.MilisUnixTimeStampUTC(); + List members = BuildMemberList(); - toPlayer.QueuePacket(GroupHeaderPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); - toPlayer.QueuePacket(GroupMembersBeginPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); + Server.GetWorldConnection().QueuePacket(GroupHeaderPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false); + Server.GetWorldConnection().QueuePacket(GroupMembersBeginPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false); int currentIndex = 0; while (true) { - if (members.Count - currentIndex >= 64) - toPlayer.QueuePacket(GroupMembersX64Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); - else if (members.Count - currentIndex >= 32) - toPlayer.QueuePacket(GroupMembersX32Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); - else if (members.Count - currentIndex >= 16) - toPlayer.QueuePacket(GroupMembersX16Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); - else if (members.Count - currentIndex > 0) - toPlayer.QueuePacket(GroupMembersX08Packet.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, members, ref currentIndex)); + if (GetMemberCount() - currentIndex >= 64) + Server.GetWorldConnection().QueuePacket(GroupMembersX64Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false); + else if (GetMemberCount() - currentIndex >= 32) + Server.GetWorldConnection().QueuePacket(GroupMembersX32Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false); + else if (GetMemberCount() - currentIndex >= 16) + Server.GetWorldConnection().QueuePacket(GroupMembersX16Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false); + else if (GetMemberCount() - currentIndex > 0) + Server.GetWorldConnection().QueuePacket(GroupMembersX08Packet.buildPacket(session.id, session.GetActor().zoneId, time, members, ref currentIndex), true, false); else break; } - - - toPlayer.QueuePacket(GroupMembersEndPacket.buildPacket(toPlayer.actorId, toPlayer.zoneId, time, this)); + + Server.GetWorldConnection().QueuePacket(GroupMembersEndPacket.buildPacket(session.id, session.GetActor().zoneId, time, this), true, false); } - public virtual void sendWorkValues(Player player){} + public virtual void SendInitWorkValues(Session session) + { + } } } diff --git a/FFXIVClassic Map Server/actors/group/GroupInvitationRelationGroup.cs b/FFXIVClassic Map Server/actors/group/GroupInvitationRelationGroup.cs deleted file mode 100644 index 6e6cb999..00000000 --- a/FFXIVClassic Map Server/actors/group/GroupInvitationRelationGroup.cs +++ /dev/null @@ -1,37 +0,0 @@ -using FFXIVClassic.Common; -using FFXIVClassic_Map_Server.actors.group.work; -using FFXIVClassic_Map_Server.Actors; -using FFXIVClassic_Map_Server.packets.send.groups; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FFXIVClassic_Map_Server.actors.group -{ - class GroupInvitationRelationGroup : Group - { - RelationWork work; - - public GroupInvitationRelationGroup(uint id, uint hostActorId, uint commandType) : base(id, Group.GroupInvitationRelationGroup) - { - work = new RelationWork(); - work._globalTemp.host = hostActorId; - work._globalTemp.variableCommand = commandType; - } - - public override void sendWorkValues(Player player) - { - SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupId); - groupWork.addProperty(this, "work._globalTemp.host"); - groupWork.addProperty(this, "work._globalTemp.variableCommand"); - groupWork.setTarget("/_init"); - - SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); - test.DebugPrintSubPacket(); - player.QueuePacket(test); - } - - } -} diff --git a/FFXIVClassic Map Server/actors/group/LinkshellGroup.cs b/FFXIVClassic Map Server/actors/group/LinkshellGroup.cs deleted file mode 100644 index 1f48b24d..00000000 --- a/FFXIVClassic Map Server/actors/group/LinkshellGroup.cs +++ /dev/null @@ -1,42 +0,0 @@ -using FFXIVClassic_Map_Server.actors.group.work; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FFXIVClassic_Map_Server.actors.group -{ - class LinkshellGroup : Group - { - private LinkshellWork linkshellWork; - - public LinkshellGroup(ulong id) : base(id, Group.CompanyGroup) - { - linkshellWork = new LinkshellWork(); - } - - public void setMaster(uint actorId) - { - linkshellWork._globalSave.master = (ulong)((0xB36F92 << 8) | actorId); - } - - public void setCrest(ushort crestId) - { - linkshellWork._globalSave.crestIcon[0] = crestId; - } - - public void setRank(byte rank = 1) - { - linkshellWork._globalSave.rank = rank; - } - - public void setMemberRank(int index, byte rank) - { - if (members.Count >= index) - return; - linkshellWork._memberSave[index].rank = rank; - } - - } -} diff --git a/FFXIVClassic Map Server/actors/group/Party.cs b/FFXIVClassic Map Server/actors/group/Party.cs new file mode 100644 index 00000000..5d0c7f21 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/Party.cs @@ -0,0 +1,53 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group.work; +using FFXIVClassic_Map_Server.dataobjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class Party : Group + { + public PartyWork partyGroupWork = new PartyWork(); + public List members = new List(); + + public Party(ulong groupId, uint leaderCharaId) : base(groupId) + { + partyGroupWork._globalTemp.owner = (ulong)(((ulong)leaderCharaId << 32) | 0xB36F92); + members.Add(leaderCharaId); + } + + public void SetLeader(uint actorId) + { + partyGroupWork._globalTemp.owner = (ulong)((actorId << 32) | 0xB36F92); + } + + public uint GetLeader() + { + return (uint)((partyGroupWork._globalTemp.owner >> 32) & 0xFFFFFFFF); + } + + public bool IsInParty(uint charaId) + { + return members.Contains(charaId); + } + + public override void SendInitWorkValues(Session session) + { + } + + public override int GetMemberCount() + { + return members.Count; + } + + public override uint GetTypeId() + { + return Group.PlayerPartyGroup; + } + + } +} diff --git a/FFXIVClassic Map Server/actors/group/PartyGroup.cs b/FFXIVClassic Map Server/actors/group/PartyGroup.cs deleted file mode 100644 index edf05743..00000000 --- a/FFXIVClassic Map Server/actors/group/PartyGroup.cs +++ /dev/null @@ -1,37 +0,0 @@ -using FFXIVClassic.Common; -using FFXIVClassic_Map_Server.actors.group.work; -using FFXIVClassic_Map_Server.packets.send.groups; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FFXIVClassic_Map_Server.actors.group -{ - class PartyGroup : Group - { - private PartyWork partyGroupWork; - - public PartyGroup(ulong id, uint owner) : base(id, Group.PlayerPartyGroup) - { - partyGroupWork = new PartyWork(); - partyGroupWork._globalTemp.owner = (ulong)((0xB36F92 << 8) | owner); - } - - public void setPartyOwner(uint actorId) - { - partyGroupWork._globalTemp.owner = (ulong)((0xB36F92 << 8) | actorId); - } - - public override void sendWorkValues(Actors.Player player) - { - SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupId); - groupWork.addProperty(this, "partyGroupWork._globalTemp.owner"); - groupWork.setTarget("/_init"); - - SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); - player.QueuePacket(test); - } - } -} diff --git a/FFXIVClassic Map Server/actors/group/Relation.cs b/FFXIVClassic Map Server/actors/group/Relation.cs new file mode 100644 index 00000000..0a686b07 --- /dev/null +++ b/FFXIVClassic Map Server/actors/group/Relation.cs @@ -0,0 +1,46 @@ +using FFXIVClassic.Common; +using FFXIVClassic_Map_Server.actors.group.work; +using FFXIVClassic_Map_Server.dataobjects; +using FFXIVClassic_Map_Server.packets.send.group; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.group +{ + class Relation : Group + { + public RelationWork work = new RelationWork(); + public uint charaOther; + + public Relation(ulong groupIndex, uint host, uint other, uint command) : base (groupIndex) + { + this.charaOther = other; + work._globalTemp.host = ((ulong)host << 32) | (0xc17909); + work._globalTemp.variableCommand = command; + } + + public override int GetMemberCount() + { + return 2; + } + + public override uint GetTypeId() + { + return Group.GroupInvitationRelationGroup; + } + + public override List BuildMemberList() + { + return null; + } + + public override void SendInitWorkValues(Session session) + { + + } + + } +} diff --git a/FFXIVClassic Map Server/actors/group/RetainerGroup.cs b/FFXIVClassic Map Server/actors/group/RetainerGroup.cs deleted file mode 100644 index 66fca5dc..00000000 --- a/FFXIVClassic Map Server/actors/group/RetainerGroup.cs +++ /dev/null @@ -1,44 +0,0 @@ -using FFXIVClassic.Common; -using FFXIVClassic_Map_Server.actors.group.work; -using FFXIVClassic_Map_Server.packets.send.groups; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace FFXIVClassic_Map_Server.actors.group -{ - class RetainerGroup : Group - { - private RetainerWork work; - - public RetainerGroup(ulong id) : base(id, Group.RetainerGroup) - { - work = new RetainerWork(); - } - - public void setRetainerProperties(int index, byte cdIDOffset, ushort placeName, byte condition, byte level) - { - if (members.Count >= index) - return; - work._memberSave[index].cdIDOffset = cdIDOffset; - work._memberSave[index].placeName = placeName; - work._memberSave[index].conditions = condition; - work._memberSave[index].level = level; - } - - public override void sendWorkValues(Actors.Player player) - { - SynchGroupWorkValuesPacket groupWork = new SynchGroupWorkValuesPacket(groupId); - groupWork.addProperty(this, "work._memberSave[0].cdIDOffset"); - groupWork.addProperty(this, "work._memberSave[0].placeName"); - groupWork.addProperty(this, "work._memberSave[0].conditions"); - groupWork.addProperty(this, "work._memberSave[0].level"); - groupWork.setTarget("/_init"); - - SubPacket test = groupWork.buildPacket(player.actorId, player.actorId); - player.QueuePacket(test); - } - } -} diff --git a/FFXIVClassic World Server/ConfigConstants.cs b/FFXIVClassic World Server/ConfigConstants.cs index 7f8b29aa..7f36a717 100644 --- a/FFXIVClassic World Server/ConfigConstants.cs +++ b/FFXIVClassic World Server/ConfigConstants.cs @@ -10,12 +10,15 @@ namespace FFXIVClassic_World_Server public static String OPTIONS_PORT; public static bool OPTIONS_TIMESTAMP = false; + public static uint DATABASE_WORLDID; public static String DATABASE_HOST; public static String DATABASE_PORT; public static String DATABASE_NAME; public static String DATABASE_USERNAME; public static String DATABASE_PASSWORD; + public static String PREF_SERVERNAME; + public static bool Load() { Program.Log.Info("Loading world_config.ini"); @@ -32,6 +35,7 @@ namespace FFXIVClassic_World_Server ConfigConstants.OPTIONS_PORT = configIni.GetValue("General", "server_port", "54992"); ConfigConstants.OPTIONS_TIMESTAMP = configIni.GetValue("General", "showtimestamp", "true").ToLower().Equals("true"); + ConfigConstants.DATABASE_WORLDID = UInt32.Parse(configIni.GetValue("Database", "worldid", "0")); ConfigConstants.DATABASE_HOST = configIni.GetValue("Database", "host", ""); ConfigConstants.DATABASE_PORT = configIni.GetValue("Database", "port", ""); ConfigConstants.DATABASE_NAME = configIni.GetValue("Database", "database", ""); diff --git a/FFXIVClassic Map Server/dataobjects/DBWorld.cs b/FFXIVClassic World Server/DataObjects/DBWorld.cs similarity index 67% rename from FFXIVClassic Map Server/dataobjects/DBWorld.cs rename to FFXIVClassic World Server/DataObjects/DBWorld.cs index 4cad9ca3..8a2c3a3b 100644 --- a/FFXIVClassic Map Server/dataobjects/DBWorld.cs +++ b/FFXIVClassic World Server/DataObjects/DBWorld.cs @@ -1,9 +1,9 @@ -namespace FFXIVClassic_Map_Server.dataobjects +namespace FFXIVClassic_World_Server.DataObjects { class DBWorld { - public ushort id; - public string Address; + public uint id; + public string address; public ushort port; public ushort listPosition; public ushort population; diff --git a/FFXIVClassic World Server/Database.cs b/FFXIVClassic World Server/Database.cs index b181fdcc..a342da8b 100644 --- a/FFXIVClassic World Server/Database.cs +++ b/FFXIVClassic World Server/Database.cs @@ -8,6 +8,41 @@ namespace FFXIVClassic_World_Server { class Database { + public static DBWorld GetServer(uint serverId) + { + using (var 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))) + { + DBWorld world = null; + try + { + conn.Open(); + MySqlCommand cmd = new MySqlCommand("SELECT name, address, port FROM servers WHERE id = @serverId", conn); + cmd.Parameters.AddWithValue("@serverId", serverId); + using (MySqlDataReader Reader = cmd.ExecuteReader()) + { + while (Reader.Read()) + { + world = new DBWorld(); + world.id = serverId; + world.name = Reader.GetString("name"); + world.address = Reader.GetString("address"); + world.port = Reader.GetUInt16("port"); + } + } + } + catch (MySqlException e) + { + Program.Log.Error(e.ToString()); + } + finally + { + conn.Dispose(); + } + + return world; + } + } + public static bool LoadZoneSessionInfo(Session session) { string characterName; diff --git a/FFXIVClassic World Server/FFXIVClassic World Server.csproj b/FFXIVClassic World Server/FFXIVClassic World Server.csproj index c8c34566..a7ab76de 100644 --- a/FFXIVClassic World Server/FFXIVClassic World Server.csproj +++ b/FFXIVClassic World Server/FFXIVClassic World Server.csproj @@ -75,6 +75,7 @@ + @@ -115,6 +116,7 @@ + diff --git a/FFXIVClassic World Server/LinkshellManager.cs b/FFXIVClassic World Server/LinkshellManager.cs index 1622c491..661d9d71 100644 --- a/FFXIVClassic World Server/LinkshellManager.cs +++ b/FFXIVClassic World Server/LinkshellManager.cs @@ -160,7 +160,7 @@ namespace FFXIVClassic_World_Server public Linkshell GetLinkshell(string name) { if (mNameToIdLookup.ContainsKey(name)) - return mCurrentWorldGroupsReference[mNameToIdLookup[name]]; + return (Linkshell)mCurrentWorldGroupsReference[mNameToIdLookup[name]]; else return null; } diff --git a/FFXIVClassic World Server/Packets/WorldPackets/Send/Group/PartySyncPacket.cs b/FFXIVClassic World Server/Packets/WorldPackets/Send/Group/PartySyncPacket.cs new file mode 100644 index 00000000..a142e461 --- /dev/null +++ b/FFXIVClassic World Server/Packets/WorldPackets/Send/Group/PartySyncPacket.cs @@ -0,0 +1,33 @@ +using FFXIVClassic.Common; +using FFXIVClassic_World_Server.DataObjects; +using FFXIVClassic_World_Server.DataObjects.Group; +using System; +using System.IO; + +namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group +{ + class PartySyncPacket + { + public const ushort OPCODE = 0x1020; + public const uint PACKET_SIZE = 0x60; + + public static SubPacket BuildPacket(Session session, Party party) + { + byte[] data = new byte[PACKET_SIZE - 0x20]; + + using (MemoryStream mem = new MemoryStream(data)) + { + using (BinaryWriter binWriter = new BinaryWriter(mem)) + { + binWriter.Write((UInt64)party.groupIndex); + binWriter.Write((UInt32)party.GetLeader()); + binWriter.Write((UInt32)party.members.Count); + for (int i = 0; i < party.members.Count; i++) + binWriter.Write((UInt32)party.members[i]); + } + } + + return new SubPacket(true, OPCODE, 0, session.sessionId, data); + } + } +} diff --git a/FFXIVClassic World Server/Program.cs b/FFXIVClassic World Server/Program.cs index 931a51c8..117e6903 100644 --- a/FFXIVClassic World Server/Program.cs +++ b/FFXIVClassic World Server/Program.cs @@ -1,4 +1,5 @@ -using MySql.Data.MySqlClient; +using FFXIVClassic_World_Server.DataObjects; +using MySql.Data.MySqlClient; using NLog; using NLog.Fluent; using System; @@ -56,6 +57,19 @@ namespace FFXIVClassic_World_Server startServer = false; } } + + //Check World ID + DBWorld thisWorld = Database.GetServer(ConfigConstants.DATABASE_WORLDID); + if (thisWorld != null) + { + Program.Log.Info("Successfully pulled world info from DB. Server name is {0}.", thisWorld.name); + ConfigConstants.PREF_SERVERNAME = thisWorld.name; + } + else + { + Program.Log.Info("World info could not be retrieved from the DB. Welcome and MOTD will not be displayed."); + ConfigConstants.PREF_SERVERNAME = "Unknown"; + } //Start server if A-OK if (startServer) diff --git a/FFXIVClassic World Server/Server.cs b/FFXIVClassic World Server/Server.cs index a4749535..de70d8b5 100644 --- a/FFXIVClassic World Server/Server.cs +++ b/FFXIVClassic World Server/Server.cs @@ -228,7 +228,7 @@ namespace FFXIVClassic_World_Server //Linkshell set active case 0x1028: SetActiveLinkshellPacket setActiveLinkshellPacket = new SetActiveLinkshellPacket(subpacket.data); - Linkshell ls = mWorldManager.GetLinkshellManager().GetLinkshell(); + //Linkshell ls = mWorldManager.GetLinkshellManager().GetLinkshell(); break; } } diff --git a/FFXIVClassic World Server/WorldMaster.cs b/FFXIVClassic World Server/WorldMaster.cs index 22d8b9ee..714e6a71 100644 --- a/FFXIVClassic World Server/WorldMaster.cs +++ b/FFXIVClassic World Server/WorldMaster.cs @@ -4,6 +4,7 @@ using FFXIVClassic_World_Server.DataObjects.Group; using FFXIVClassic_World_Server.Packets.Send.Subpackets; using FFXIVClassic_World_Server.Packets.Send.Subpackets.Groups; using FFXIVClassic_World_Server.Packets.WorldPackets.Send; +using FFXIVClassic_World_Server.Packets.WorldPackets.Send.Group; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -219,6 +220,7 @@ namespace FFXIVClassic_World_Server mPartyManager.AddToParty(pt.groupIndex, 161); mPartyManager.AddToParty(pt.groupIndex, 162); pt.SendGroupPackets(session); + SendPartySync(pt); mRetainerGroupManager.GetRetainerGroup(session.sessionId).SendGroupPackets(session); List linkshells = mLinkshellManager.GetPlayerLinkshellMembership(session.sessionId); foreach (Linkshell ls in linkshells) @@ -230,11 +232,23 @@ namespace FFXIVClassic_World_Server private void SendMotD(Session session) { session.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, session.sessionId, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "-------- Login Message --------"), true, false); - session.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, session.sessionId, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Welcome to !"), true, false); + session.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, session.sessionId, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Welcome to {0}!", ConfigConstants.PREF_SERVERNAME)), true, false); session.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, session.sessionId, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Welcome to Eorzea!"), true, false); session.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, session.sessionId, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", "Here is a test Message of the Day from the World Server!"), true, false); } + public void SendPartySync(Party party) + { + foreach (uint member in party.members) + { + Session session = Server.GetServer().GetSession(member); + if (session == null) + continue; + SubPacket syncPacket = PartySyncPacket.BuildPacket(session, party); + session.routing1.SendPacket(syncPacket); + } + } + public class ZoneEntrance { public uint zoneId;