From d77344b72561bd13ea399b094b21fdbfd913ca0a Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Sun, 17 Jan 2016 11:48:55 -0500 Subject: [PATCH] Multiple zones are now stored on the server and accessed properly. --- FFXIVClassic Map Server/Database.cs | 15 +- .../FFXIVClassic Map Server.csproj | 1 + FFXIVClassic Map Server/PacketProcessor.cs | 22 ++- FFXIVClassic Map Server/actors/Actor.cs | 4 +- .../actors/director/WeatherDirector.cs | 4 +- .../common/EfficientHashTables.cs | 160 ++++++++++++++++++ 6 files changed, 187 insertions(+), 19 deletions(-) create mode 100644 FFXIVClassic Map Server/common/EfficientHashTables.cs diff --git a/FFXIVClassic Map Server/Database.cs b/FFXIVClassic Map Server/Database.cs index 3d35f4e1..edab6e27 100644 --- a/FFXIVClassic Map Server/Database.cs +++ b/FFXIVClassic Map Server/Database.cs @@ -14,6 +14,7 @@ using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Map_Server.packets.send.player; using FFXIVClassic_Lobby_Server.dataobjects; using FFXIVClassic_Map_Server; +using FFXIVClassic_Map_Server.common.EfficientHashTables; namespace FFXIVClassic_Lobby_Server { @@ -143,7 +144,7 @@ namespace FFXIVClassic_Lobby_Server player.oldPositionZ = player.positionZ = reader.GetFloat(3); player.oldRotation = player.rotation = reader.GetFloat(4); player.currentMainState = reader.GetUInt16(5); - player.currentZoneId = reader.GetUInt32(6); + player.zoneId = reader.GetUInt32(6); player.charaWork.parameterSave.state_mainSkill[0] = reader.GetByte(7); player.gcCurrent = reader.GetByte(8); player.gcRankLimsa = reader.GetByte(9); @@ -542,16 +543,15 @@ namespace FFXIVClassic_Lobby_Server return cheevosPacket.buildPacket(player.actorId); } - public static List loadZones() + public static void loadZones(Efficient32bitHashTable zoneList) { - List zones = new List(); + int count = 0; 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(); - //Load Last 5 Completed string query = @" SELECT id, @@ -563,7 +563,7 @@ namespace FFXIVClassic_Lobby_Server isInn, canRideChocobo, canStealth, - isInstanceRaid, + isInstanceRaid FROM server_zones WHERE zoneName IS NOT NULL"; @@ -573,7 +573,8 @@ namespace FFXIVClassic_Lobby_Server { while (reader.Read()) { Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(2), reader.GetUInt16(1), reader.GetUInt16(3), reader.GetUInt16(4), reader.GetUInt16(5), reader.GetBoolean(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9)); - zones.Add(zone); + zoneList.Add(zone.actorId, zone); + count++; } } } @@ -585,7 +586,7 @@ namespace FFXIVClassic_Lobby_Server } } - return zones; + Log.info(String.Format("Loaded {0} zones.", count)); } } diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index e88c792d..42f3674e 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -75,6 +75,7 @@ + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index eb2a5e46..f622e2e4 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -36,6 +36,7 @@ using FFXIVClassic_Map_Server.actors; using System.Net; using FFXIVClassic_Map_Server.actors.debug; using FFXIVClassic_Map_Server.actors.world; +using FFXIVClassic_Map_Server.common.EfficientHashTables; namespace FFXIVClassic_Lobby_Server { @@ -50,14 +51,14 @@ namespace FFXIVClassic_Lobby_Server DebugProg debug = new DebugProg(); WorldMaster worldMaster = new WorldMaster(); - List zoneList; + Efficient32bitHashTable zoneList = new Efficient32bitHashTable(); public PacketProcessor(Dictionary playerList, List connectionList) { mPlayers = playerList; mConnections = connectionList; - zoneList = Database.loadZones(); + Database.loadZones(zoneList); } public void processPacket(ClientConnection client, BasePacket packet) @@ -188,7 +189,10 @@ namespace FFXIVClassic_Lobby_Server client.queuePacket(BasePacket.createPacket(PongPacket.buildPacket(player.actorID, pingPacket.time), true, false)); break; //Unknown - case 0x0002: + case 0x0002: + + player.getActor().zone = zoneList.Get(player.getActor().zoneId); + BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); //Bed, Book created BasePacket reply10 = new BasePacket("./packets/login/login10.bin"); //Item Storage, Inn Door created BasePacket reply11 = new BasePacket("./packets/login/login11.bin"); //NPC Create ??? Final init @@ -297,10 +301,10 @@ namespace FFXIVClassic_Lobby_Server BasePacket tpacket = player.getActor().getInitPackets(player.actorID); //tpacket.debugPrintPacket(); client.queuePacket(tpacket); - - inn.addActorToZone(player.getActor()); - BasePacket innSpawn = inn.getSpawnPackets(player.actorID); + player.getActor().zone.addActorToZone(player.getActor()); + + BasePacket innSpawn = player.getActor().zone.getSpawnPackets(player.actorID); BasePacket debugSpawn = debug.getSpawnPackets(player.actorID); BasePacket worldMasterSpawn = worldMaster.getSpawnPackets(player.actorID); innSpawn.debugPrintPacket(); @@ -328,9 +332,9 @@ namespace FFXIVClassic_Lobby_Server //Update Position UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data); player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState); - + //Update Instance - List instanceUpdatePackets = player.updateInstance(inn.getActorsAroundActor(player.getActor(), 50)); + List instanceUpdatePackets = player.updateInstance(player.getActor().zone.getActorsAroundActor(player.getActor(), 50)); foreach (BasePacket bp in instanceUpdatePackets) client.queuePacket(bp); @@ -519,10 +523,12 @@ namespace FFXIVClassic_Lobby_Server */ private void initNpcs() { + /* List npcList = Database.getNpcList(); foreach (Npc npc in npcList) inn.addActorToZone(npc); Log.info(String.Format("Loaded {0} npcs...", npcList.Count)); + * */ } private void loadTest(ClientConnection client, ConnectedPlayer player) diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 5084622f..339704c1 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -28,8 +28,8 @@ namespace FFXIVClassic_Map_Server.dataobjects public float oldPositionX, oldPositionY, oldPositionZ, oldRotation; public ushort moveState, oldMoveState; - public uint currentZoneId; - + public uint zoneId; + public Zone zone = null; public bool isZoning = false; public bool spawnedFirstTime = false; diff --git a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs index 7da80180..d96e391c 100644 --- a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs +++ b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs @@ -20,9 +20,9 @@ namespace FFXIVClassic_Map_Server.actors.director this.weatherId = weatherId; this.displayNameId = 0; - this.customDisplayName = String.Format("weatherDire_{0}", zone.zoneName, zone.currentZoneId); + this.customDisplayName = String.Format("weatherDire_{0}", zone.zoneName, zone.actorId); - this.actorName = String.Format("weatherDire_{0}@{0:04x}", zone.zoneName, zone.currentZoneId); + this.actorName = String.Format("weatherDire_{0}@{0:04x}", zone.zoneName, zone.actorId); this.className = "Debug"; } diff --git a/FFXIVClassic Map Server/common/EfficientHashTables.cs b/FFXIVClassic Map Server/common/EfficientHashTables.cs new file mode 100644 index 00000000..3f94c510 --- /dev/null +++ b/FFXIVClassic Map Server/common/EfficientHashTables.cs @@ -0,0 +1,160 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.common +{ + namespace EfficientHashTables + { + public class Efficient64bitHashTable + { + private class element + { + public ulong _key; + public T _value; + }; + private element[][] _buckets; + private uint _capacity; + + public Efficient64bitHashTable() + { + _capacity = 214373; // some prime number + _buckets = new element[_capacity][]; + } + public Efficient64bitHashTable(uint capacity) + { + _capacity = capacity; + _buckets = new element[_capacity][]; + } + + public uint hash(ulong key) + { + return (uint)(key % _capacity); + } + + public void Add(ulong key, T value) + { + uint hsh = hash(key); + element[] e; + if (_buckets[hsh] == null) + _buckets[hsh] = e = new element[1]; + else + { + foreach (var elem in _buckets[hsh]) + if (elem._key == key) + { + elem._value = value; + return; + } + e = new element[_buckets[hsh].Length + 1]; + Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length); + _buckets[hsh] = e; + } + e[0] = new element { _key = key, _value = value }; + } + + public T Get(ulong key) + { + uint hsh = hash(key); + element[] e = _buckets[hsh]; + if (e == null) return default(T); + foreach (var f in e) + if (f._key == key) + return f._value; + return default(T); + } + + public bool Has(ulong key) + { + uint hsh = hash(key); + element[] e = _buckets[hsh]; + if (e == null) return false; + foreach (var f in e) + if (f._key == key) + return true; + return false; + } + + public int Count() + { + int r = 0; + foreach (var e in _buckets) + if (e != null) + r += e.Length; + return r; + } + } + + public class Efficient32bitHashTable + { + private class element + { + public uint _key; + public T _value; + }; + private element[][] _buckets; + private uint _capacity; + + public Efficient32bitHashTable() + { + _capacity = 463; // some prime number + _buckets = new element[_capacity][]; + } + public Efficient32bitHashTable(uint capacity) + { + _capacity = capacity; + _buckets = new element[_capacity][]; + } + + public uint hash(uint key) + { + return (uint)(key % _capacity); + } + + public void Add(uint key, T value) + { + uint hsh = hash(key); + element[] e; + if (_buckets[hsh] == null) + _buckets[hsh] = e = new element[1]; + else + { + foreach (var elem in _buckets[hsh]) + if (elem._key == key) + { + elem._value = value; + return; + } + e = new element[_buckets[hsh].Length + 1]; + Array.Copy(_buckets[hsh], 0, e, 1, _buckets[hsh].Length); + _buckets[hsh] = e; + } + e[0] = new element { _key = key, _value = value }; + } + + public T Get(uint key) + { + uint hsh = hash(key); + element[] e = _buckets[hsh]; + if (e == null) return default(T); + foreach (var f in e) + if (f._key == key) + return f._value; + return default(T); + } + + public int Count() + { + int r = 0; + foreach (var e in _buckets) + if (e != null) + r += e.Length; + return r; + } + + } + } + +}