diff --git a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj index 1b165c55..85139a2d 100644 --- a/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj +++ b/FFXIVClassic Map Server/FFXIVClassic Map Server.csproj @@ -61,6 +61,8 @@ + + @@ -221,7 +223,7 @@ - + diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 260d13df..12cf82a8 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -195,14 +195,7 @@ namespace FFXIVClassic_Lobby_Server //subpacket.debugPrintSubPacket(); UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data); player.updatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState); - - //Update Instance - List instanceUpdatePackets = player.updateInstance(player.getActor().zone.getActorsAroundActor(player.getActor(), 50)); - foreach (BasePacket bp in instanceUpdatePackets) - { - // bp.debugPrintPacket(); - client.queuePacket(bp); - } + player.getActor().sendInstanceUpdate(); break; //Set Target case 0x00CD: @@ -218,9 +211,22 @@ namespace FFXIVClassic_Lobby_Server player.getActor().currentLockedTarget = lockTarget.actorID; break; //Start Event - case 0x012D: + case 0x012D: subpacket.debugPrintSubPacket(); EventStartPacket eventStart = new EventStartPacket(subpacket.data); + + /* + if (eventStart.error != null) + { + player.errorMessage += eventStart.error; + + if (eventStart.errorIndex == eventStart.errorNum - 1) + Log.error("\n"+player.errorMessage); + + + break; + } + */ player.getActor().eventCurrentOwner = eventStart.scriptOwnerActorID; player.getActor().eventCurrentStarter = eventStart.eventStarter; @@ -230,7 +236,10 @@ namespace FFXIVClassic_Lobby_Server { ownerActor = mServer.GetWorldManager().GetActorInWorld(player.getActor().eventCurrentOwner); if (ownerActor == null) + { + Log.debug(String.Format("\n===Event START===\nCould not find actor 0x{0:X} for event started by caller: 0x{1:X}\nEvent Starter: {2}\nParams: {3}", eventStart.actorID, eventStart.scriptOwnerActorID, eventStart.eventStarter, LuaUtils.dumpParams(eventStart.luaParams))); break; + } } mServer.GetLuaEngine().doActorOnEventStarted(player.getActor(), ownerActor, eventStart); diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs index 0478b2f0..7ed19a98 100644 --- a/FFXIVClassic Map Server/Server.cs +++ b/FFXIVClassic Map Server/Server.cs @@ -429,7 +429,12 @@ namespace FFXIVClassic_Lobby_Server { Log.info(String.Format("Got request to reset zone: {0}", client.getActor().zoneId)); if (client != null) + { + client.getActor().zone.clear(); + client.getActor().zone.addActorToZone(client.getActor()); + client.getActor().sendInstanceUpdate(); client.queuePacket(BasePacket.createPacket(SendMessagePacket.buildPacket(client.actorID, client.actorID, SendMessagePacket.MESSAGE_TYPE_GENERAL_INFO, "", String.Format("Resting zone {0}...", client.getActor().zoneId)), true, false)); + } mWorldManager.reloadZone(client.getActor().zoneId); } } @@ -462,7 +467,7 @@ namespace FFXIVClassic_Lobby_Server doWarp(client, split[1]); } } - if (split.Length >= 3) + if (split.Length >= 5) { if (split[0].Equals("warp")) { diff --git a/FFXIVClassic Map Server/WorldManager.cs b/FFXIVClassic Map Server/WorldManager.cs index 9e41de7b..89843859 100644 --- a/FFXIVClassic Map Server/WorldManager.cs +++ b/FFXIVClassic Map Server/WorldManager.cs @@ -1,10 +1,12 @@ using FFXIVClassic_Lobby_Server; using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.common.EfficientHashTables; using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects.chara; using FFXIVClassic_Map_Server.packets.send; +using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.login; using MySql.Data.MySqlClient; using System; @@ -42,11 +44,13 @@ namespace FFXIVClassic_Map_Server string query = @" SELECT id, - regionId, zoneName, + regionId, + className, dayMusic, nightMusic, battleMusic, + isIsolated, isInn, canRideChocobo, canStealth, @@ -60,7 +64,7 @@ namespace FFXIVClassic_Map_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)); + Zone zone = new Zone(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt16(2), reader.GetString(3), reader.GetUInt16(4), reader.GetUInt16(5), reader.GetUInt16(6), reader.GetBoolean(7), reader.GetBoolean(8), reader.GetBoolean(9), reader.GetBoolean(10), reader.GetBoolean(11)); zoneList[zone.actorId] = zone; count++; } @@ -147,7 +151,7 @@ namespace FFXIVClassic_Map_Server actorClassName, eventConditions FROM gamedata_actor_class - WHERE name is not NULL + WHERE name is not NULL AND zoneId > 0 "; MySqlCommand cmd = new MySqlCommand(query, conn); @@ -216,7 +220,7 @@ namespace FFXIVClassic_Map_Server customDisplayName, actorClassName, eventConditions - FROM gamedata_actorclass + FROM gamedata_actor_class WHERE name is not NULL AND zoneId = @zoneId "; @@ -228,14 +232,14 @@ namespace FFXIVClassic_Map_Server while (reader.Read()) { string customName = null; - if (reader.IsDBNull(10)) + if (!reader.IsDBNull(10)) customName = reader.GetString(10); Npc npc = new Npc(reader.GetUInt32(0), reader.GetString(1), reader.GetUInt32(2), reader.GetFloat(3), reader.GetFloat(4), reader.GetFloat(5), reader.GetFloat(6), reader.GetUInt16(7), reader.GetUInt32(8), reader.GetUInt32(9), customName, reader.GetString(11)); - if (!reader.IsDBNull(11)) + if (!reader.IsDBNull(12)) { - string eventConditions = reader.GetString(11); + string eventConditions = reader.GetString(12); npc.loadEventConditions(eventConditions); } @@ -327,8 +331,11 @@ namespace FFXIVClassic_Map_Server player.rotation = spawnRotation; //Send packets - player.playerSession.queuePacket(_0xE2Packet.buildPacket(0x6c, 0xF), true, false); + player.playerSession.queuePacket(DeleteAllActorsPacket.buildPacket(player.actorId), true, false); + player.playerSession.queuePacket(_0xE2Packet.buildPacket(player.actorId, 0x0), true, false); player.sendZoneInPackets(this, spawnType); + player.playerSession.clearInstance(); + player.sendInstanceUpdate(); } //Login Zone In @@ -346,8 +353,11 @@ namespace FFXIVClassic_Map_Server zone.addActorToZone(player); //Send packets + player.playerSession.queuePacket(DeleteAllActorsPacket.buildPacket(player.actorId), true, false); player.playerSession.queuePacket(_0x2Packet.buildPacket(player.actorId), true, false); - player.sendZoneInPackets(this, 0x1); + player.sendZoneInPackets(this, 0x1); + player.playerSession.clearInstance(); + player.sendInstanceUpdate(); } public void reloadZone(uint zoneId) @@ -356,7 +366,7 @@ namespace FFXIVClassic_Map_Server return; Zone zone = zoneList[zoneId]; - zone.clear(); + //zone.clear(); LoadNPCs(zone.actorId); } diff --git a/FFXIVClassic Map Server/actors/Actor.cs b/FFXIVClassic Map Server/actors/Actor.cs index 5e3b52d9..00a23a6c 100644 --- a/FFXIVClassic Map Server/actors/Actor.cs +++ b/FFXIVClassic Map Server/actors/Actor.cs @@ -2,6 +2,7 @@ using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Map_Server.actors; +using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.dataobjects.chara; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; diff --git a/FFXIVClassic Map Server/actors/area/Area.cs b/FFXIVClassic Map Server/actors/area/Area.cs new file mode 100644 index 00000000..d11a76a7 --- /dev/null +++ b/FFXIVClassic Map Server/actors/area/Area.cs @@ -0,0 +1,322 @@ +using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.dataobjects; +using FFXIVClassic_Map_Server.dataobjects.chara; +using FFXIVClassic_Map_Server.lua; +using FFXIVClassic_Map_Server.packets.send.actor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.Actors +{ + class Area : Actor + { + public string zoneName; + public ushort regionId; + public bool isIsolated, canStealth, isInn, canRideChocobo, isInstanceRaid; + public ushort weatherNormal, weatherCommon, weatherRare; + public ushort bgmDay, bgmNight, bgmBattle; + + + private string classPath; + + public int boundingGridSize = 50; + public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000; + private int numXBlocks, numYBlocks; + private int halfWidth, halfHeight; + + private Dictionary mActorList = new Dictionary(); + private List[,] mActorBlock; + + public Area(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid) + : base(id) + { + + this.zoneName = zoneName; + this.regionId = regionId; + this.canStealth = canStealth; + this.isIsolated = isIsolated; + this.isInn = isInn; + this.canRideChocobo = canRideChocobo; + this.isInstanceRaid = isInstanceRaid; + + this.bgmDay = bgmDay; + this.bgmNight = bgmNight; + this.bgmBattle = bgmBattle; + + this.displayNameId = 0; + this.customDisplayName = "_areaMaster"; + this.actorName = String.Format("_areaMaster@{0:X5}",id<<8); + + this.className = className; + + numXBlocks = (maxX - minX) / boundingGridSize; + numYBlocks = (maxY - minY) / boundingGridSize; + mActorBlock = new List[numXBlocks, numYBlocks]; + halfWidth = numXBlocks / 2; + halfHeight = numYBlocks / 2; + + for (int y = 0; y < numYBlocks; y++) + { + for (int x = 0; x < numXBlocks; x++ ) + { + mActorBlock[x, y] = new List(); + } + } + + } + + public override SubPacket createScriptBindPacket(uint playerActorId) + { + List lParams; + lParams = LuaUtils.createLuaParamList(classPath, false, true, zoneName, "/Area/Zone/ZoneDefault", -1, (byte)1, true, false, false, false, false, false, false, false); + return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, "ZoneDefault", lParams); + } + + public override BasePacket getSpawnPackets(uint playerActorId) + { + List subpackets = new List(); + subpackets.Add(createAddActorPacket(playerActorId, 0)); + subpackets.Add(createSpeedPacket(playerActorId)); + subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1)); + subpackets.Add(createNamePacket(playerActorId)); + subpackets.Add(createStatePacket(playerActorId)); + subpackets.Add(createIsZoneingPacket(playerActorId)); + subpackets.Add(createScriptBindPacket(playerActorId)); + subpackets[6].debugPrintSubPacket(); + return BasePacket.createPacket(subpackets, true, false); + } + + #region Actor Management + + public void addActorToZone(Actor actor) + { + if (!mActorList.ContainsKey(actor.actorId)) + mActorList.Add(actor.actorId, actor); + + int gridX = (int)actor.positionX / boundingGridSize; + int gridY = (int)actor.positionZ / boundingGridSize; + + gridX += halfWidth; + gridY += halfHeight; + + //Boundries + if (gridX < 0) + gridX = 0; + if (gridX >= numXBlocks) + gridX = numXBlocks - 1; + if (gridY < 0) + gridY = 0; + if (gridY >= numYBlocks) + gridY = numYBlocks - 1; + + lock (mActorBlock) + mActorBlock[gridX, gridY].Add(actor); + } + + public void removeActorToZone(Actor actor) + { + mActorList.Remove(actor.actorId); + + int gridX = (int)actor.positionX / boundingGridSize; + int gridY = (int)actor.positionZ / boundingGridSize; + + gridX += halfWidth; + gridY += halfHeight; + + //Boundries + if (gridX < 0) + gridX = 0; + if (gridX >= numXBlocks) + gridX = numXBlocks - 1; + if (gridY < 0) + gridY = 0; + if (gridY >= numYBlocks) + gridY = numYBlocks - 1; + + lock (mActorBlock) + mActorBlock[gridX, gridY].Remove(actor); + } + + public void updateActorPosition(Actor actor) + { + int gridX = (int)actor.positionX / boundingGridSize; + int gridY = (int)actor.positionZ / boundingGridSize; + + gridX += halfWidth; + gridY += halfHeight; + + //Boundries + if (gridX < 0) + gridX = 0; + if (gridX >= numXBlocks) + gridX = numXBlocks - 1; + if (gridY < 0) + gridY = 0; + if (gridY >= numYBlocks) + gridY = numYBlocks - 1; + + int gridOldX = (int)actor.oldPositionX / boundingGridSize; + int gridOldY = (int)actor.oldPositionZ / boundingGridSize; + + gridOldX += halfWidth; + gridOldY += halfHeight; + + //Boundries + if (gridOldX < 0) + gridOldX = 0; + if (gridOldX >= numXBlocks) + gridOldX = numXBlocks - 1; + if (gridOldY < 0) + gridOldY = 0; + if (gridOldY >= numYBlocks) + gridOldY = numYBlocks - 1; + + //Still in same block + if (gridX == gridOldX && gridY == gridOldY) + return; + + lock (mActorBlock) + { + mActorBlock[gridOldX, gridOldY].Remove(actor); + mActorBlock[gridX, gridY].Add(actor); + } + } + + public List getActorsAroundPoint(float x, float y, int checkDistance) + { + checkDistance /= boundingGridSize; + + int gridX = (int)x/boundingGridSize; + int gridY = (int)y/boundingGridSize; + + gridX += halfWidth; + gridY += halfHeight; + + //Boundries + if (gridX < 0) + gridX = 0; + if (gridX >= numXBlocks) + gridX = numXBlocks - 1; + if (gridY < 0) + gridY = 0; + if (gridY >= numYBlocks) + gridY = numYBlocks - 1; + + List result = new List(); + + for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++) + { + for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) + { + result.AddRange(mActorBlock[gx, gy]); + } + } + + return result; + } + + public List getActorsAroundActor(Actor actor, int checkDistance) + { + checkDistance /= boundingGridSize; + + int gridX = (int)actor.positionX / boundingGridSize; + int gridY = (int)actor.positionZ / boundingGridSize; + + gridX += halfWidth; + gridY += halfHeight; + + //Boundries + if (gridX < 0) + gridX = 0; + if (gridX >= numXBlocks) + gridX = numXBlocks - 1; + if (gridY < 0) + gridY = 0; + if (gridY >= numYBlocks) + gridY = numYBlocks - 1; + + List result = new List(); + + for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++) + { + for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++) + { + result.AddRange(mActorBlock[gx, gy]); + } + } + + //Remove players if isolation zone + if (isIsolated) + { + for (int i = 0; i < result.Count; i++) + { + if (result[i] is Player) + result.RemoveAt(i); + } + } + + return result; + } + + #endregion + + public Actor FindActorInZone(uint id) + { + if (!mActorList.ContainsKey(id)) + return null; + return mActorList[id]; + } + + public Player FindPCInZone(string name) + { + foreach (Actor a in mActorList.Values) + { + if (a is Player) + { + if (((Player)a).customDisplayName.Equals(name)) + return (Player)a; + } + } + return null; + } + + public Player FindPCInZone(uint id) + { + if (!mActorList.ContainsKey(id)) + return null; + return (Player)mActorList[id]; + } + + public void clear() + { + //Clear All + mActorList.Clear(); + for (int y = 0; y < numYBlocks; y++) + { + for (int x = 0; x < numXBlocks; x++) + { + mActorBlock[x, y].Clear(); + } + } + } + + public void broadcastPacketAroundActor(Actor actor, SubPacket packet) + { + List aroundActor = getActorsAroundActor(actor, 50); + foreach (Actor a in aroundActor) + { + if (a is Player) + { + SubPacket clonedPacket = new SubPacket(packet, actor.actorId); + Player p = (Player)a; + p.queuePacket(clonedPacket); + } + } + } + + } +} diff --git a/FFXIVClassic Map Server/actors/area/PrivateArea.cs b/FFXIVClassic Map Server/actors/area/PrivateArea.cs new file mode 100644 index 00000000..9f9e821a --- /dev/null +++ b/FFXIVClassic Map Server/actors/area/PrivateArea.cs @@ -0,0 +1,32 @@ +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.Actors; +using FFXIVClassic_Map_Server.lua; +using FFXIVClassic_Map_Server.packets.send.actor; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FFXIVClassic_Map_Server.actors.area +{ + class PrivateArea : Area + { + private Zone parentZone; + private string privateAreaName; + + public PrivateArea(Zone parent, uint id, string className, string privateAreaName,ushort bgmDay, ushort bgmNight, ushort bgmBattle) + : base(id, parent.zoneName, parent.regionId, className, bgmDay, bgmNight, bgmBattle, parent.isIsolated, parent.isInn, parent.canRideChocobo, parent.canStealth, true) + { + this.parentZone = parent; + this.privateAreaName = privateAreaName; + } + + public override SubPacket createScriptBindPacket(uint playerActorId) + { + List lParams; + lParams = LuaUtils.createLuaParamList("/Area/PrivateArea/" + className, false, true, zoneName, privateAreaName, 0xE1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, false, false, false); + return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams); + } + } +} diff --git a/FFXIVClassic Map Server/actors/area/Zone.cs b/FFXIVClassic Map Server/actors/area/Zone.cs index c054baf3..73c909d2 100644 --- a/FFXIVClassic Map Server/actors/area/Zone.cs +++ b/FFXIVClassic Map Server/actors/area/Zone.cs @@ -1,7 +1,5 @@ -using FFXIVClassic_Lobby_Server.common; -using FFXIVClassic_Lobby_Server.packets; -using FFXIVClassic_Map_Server.dataobjects; -using FFXIVClassic_Map_Server.dataobjects.chara; +using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.Actors; using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.packets.send.actor; using System; @@ -10,298 +8,39 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace FFXIVClassic_Map_Server.Actors +namespace FFXIVClassic_Map_Server.actors.area { - class Zone : Actor + class Zone : Area { - public string zoneName; - public ushort regionId; - public bool canStealth, isInn, canRideChocobo, isInstanceRaid; - public ushort weatherNormal, weatherCommon, weatherRare; - public ushort bgmDay, bgmNight, bgmBattle; - - public int boundingGridSize = 50; - public int minX = -1000, minY = -1000, maxX = 1000, maxY = 1000; - private int numXBlocks, numYBlocks; - private int halfWidth, halfHeight; + Dictionary> privateAreas = new Dictionary>(); - private Dictionary mActorList = new Dictionary(); - private List[,] mActorBlock; - - public Zone(uint id, string zoneName, ushort regionId, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid) - : base(id) + public Zone(uint id, string zoneName, ushort regionId, string className, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool isIsolated, bool isInn, bool canRideChocobo, bool canStealth, bool isInstanceRaid) + : base(id, zoneName, regionId, className, bgmDay, bgmNight, bgmBattle, isIsolated, isInn, canRideChocobo, canStealth, isInstanceRaid) { - this.zoneName = zoneName; - this.regionId = regionId; - this.canStealth = canStealth; - this.isInn = isInn; - this.canRideChocobo = canRideChocobo; - this.isInstanceRaid = isInstanceRaid; + } - this.bgmDay = bgmDay; - this.bgmNight = bgmNight; - this.bgmBattle = bgmBattle; - - this.displayNameId = 0; - this.customDisplayName = "_areaMaster"; - this.actorName = String.Format("_areaMaster@{0:X5}",id<<8); - - this.className = "ZoneMasterPrvI0"; - - numXBlocks = (maxX - minX) / boundingGridSize; - numYBlocks = (maxY - minY) / boundingGridSize; - mActorBlock = new List[numXBlocks, numYBlocks]; - halfWidth = numXBlocks / 2; - halfHeight = numYBlocks / 2; - - for (int y = 0; y < numYBlocks; y++) + public PrivateArea getPrivateArea(string type, uint number) + { + if (privateAreas.ContainsKey(type)) { - for (int x = 0; x < numXBlocks; x++ ) - { - mActorBlock[x, y] = new List(); - } + Dictionary instances = privateAreas[type]; + if (instances.ContainsKey(number)) + return instances[number]; + else + return null; } - + else + return null; } public override SubPacket createScriptBindPacket(uint playerActorId) { + bool isEntranceDesion = false; + List lParams; - lParams = LuaUtils.createLuaParamList("/Area/Zone/ZoneMasterPrvI0", false, true, zoneName, "", -1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, false, false, false); - return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams); - } - - public override BasePacket getSpawnPackets(uint playerActorId) - { - List subpackets = new List(); - subpackets.Add(createAddActorPacket(playerActorId, 0)); - subpackets.Add(createSpeedPacket(playerActorId)); - subpackets.Add(createSpawnPositonPacket(playerActorId, 0x1)); - subpackets.Add(createNamePacket(playerActorId)); - subpackets.Add(createStatePacket(playerActorId)); - subpackets.Add(createIsZoneingPacket(playerActorId)); - subpackets.Add(createScriptBindPacket(playerActorId)); - subpackets[6].debugPrintSubPacket(); - return BasePacket.createPacket(subpackets, true, false); - } - - #region Actor Management - - public void addActorToZone(Actor actor) - { - if (!mActorList.ContainsKey(actor.actorId)) - mActorList.Add(actor.actorId, actor); - - int gridX = (int)actor.positionX / boundingGridSize; - int gridY = (int)actor.positionZ / boundingGridSize; - - gridX += halfWidth; - gridY += halfHeight; - - //Boundries - if (gridX < 0) - gridX = 0; - if (gridX >= numXBlocks) - gridX = numXBlocks - 1; - if (gridY < 0) - gridY = 0; - if (gridY >= numYBlocks) - gridY = numYBlocks - 1; - - lock (mActorBlock) - mActorBlock[gridX, gridY].Add(actor); - } - - public void removeActorToZone(Actor actor) - { - mActorList.Remove(actor.actorId); - - int gridX = (int)actor.positionX / boundingGridSize; - int gridY = (int)actor.positionZ / boundingGridSize; - - gridX += halfWidth; - gridY += halfHeight; - - //Boundries - if (gridX < 0) - gridX = 0; - if (gridX >= numXBlocks) - gridX = numXBlocks - 1; - if (gridY < 0) - gridY = 0; - if (gridY >= numYBlocks) - gridY = numYBlocks - 1; - - lock (mActorBlock) - mActorBlock[gridX, gridY].Remove(actor); - } - - public void updateActorPosition(Actor actor) - { - int gridX = (int)actor.positionX / boundingGridSize; - int gridY = (int)actor.positionZ / boundingGridSize; - - gridX += halfWidth; - gridY += halfHeight; - - //Boundries - if (gridX < 0) - gridX = 0; - if (gridX >= numXBlocks) - gridX = numXBlocks - 1; - if (gridY < 0) - gridY = 0; - if (gridY >= numYBlocks) - gridY = numYBlocks - 1; - - int gridOldX = (int)actor.oldPositionX / boundingGridSize; - int gridOldY = (int)actor.oldPositionZ / boundingGridSize; - - gridOldX += halfWidth; - gridOldY += halfHeight; - - //Boundries - if (gridOldX < 0) - gridOldX = 0; - if (gridOldX >= numXBlocks) - gridOldX = numXBlocks - 1; - if (gridOldY < 0) - gridOldY = 0; - if (gridOldY >= numYBlocks) - gridOldY = numYBlocks - 1; - - //Still in same block - if (gridX == gridOldX && gridY == gridOldY) - return; - - lock (mActorBlock) - { - mActorBlock[gridOldX, gridOldY].Remove(actor); - mActorBlock[gridX, gridY].Add(actor); - } - } - - public List getActorsAroundPoint(float x, float y, int checkDistance) - { - checkDistance /= boundingGridSize; - - int gridX = (int)x/boundingGridSize; - int gridY = (int)y/boundingGridSize; - - gridX += halfWidth; - gridY += halfHeight; - - //Boundries - if (gridX < 0) - gridX = 0; - if (gridX >= numXBlocks) - gridX = numXBlocks - 1; - if (gridY < 0) - gridY = 0; - if (gridY >= numYBlocks) - gridY = numYBlocks - 1; - - List result = new List(); - - for (int gx = gridX - checkDistance; gx <= gridX + checkDistance; gx++) - { - for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) - { - result.AddRange(mActorBlock[gx, gy]); - } - } - - return result; - } - - public List getActorsAroundActor(Actor actor, int checkDistance) - { - checkDistance /= boundingGridSize; - - int gridX = (int)actor.positionX / boundingGridSize; - int gridY = (int)actor.positionZ / boundingGridSize; - - gridX += halfWidth; - gridY += halfHeight; - - //Boundries - if (gridX < 0) - gridX = 0; - if (gridX >= numXBlocks) - gridX = numXBlocks - 1; - if (gridY < 0) - gridY = 0; - if (gridY >= numYBlocks) - gridY = numYBlocks - 1; - - List result = new List(); - - for (int gy = ((gridY - checkDistance) < 0 ? 0 : (gridY - checkDistance)); gy <= ((gridY + checkDistance) >= numYBlocks ? numYBlocks - 1 : (gridY + checkDistance)); gy++) - { - for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++) - { - result.AddRange(mActorBlock[gx, gy]); - } - } - - return result; - } - - #endregion - - public Actor FindActorInZone(uint id) - { - if (!mActorList.ContainsKey(id)) - return null; - return mActorList[id]; - } - - public Player FindPCInZone(string name) - { - foreach (Actor a in mActorList.Values) - { - if (a is Player) - { - if (((Player)a).customDisplayName.Equals(name)) - return (Player)a; - } - } - return null; - } - - public Player FindPCInZone(uint id) - { - if (!mActorList.ContainsKey(id)) - return null; - return (Player)mActorList[id]; - } - - public void clear() - { - //Clear All - mActorList.Clear(); - for (int y = 0; y < numYBlocks; y++) - { - for (int x = 0; x < numXBlocks; x++) - { - mActorBlock[x, y].Clear(); - } - } - } - - public void broadcastPacketAroundActor(Actor actor, SubPacket packet) - { - List aroundActor = getActorsAroundActor(actor, 50); - foreach (Actor a in aroundActor) - { - if (a is Player) - { - SubPacket clonedPacket = new SubPacket(packet, actor.actorId); - Player p = (Player)a; - p.queuePacket(clonedPacket); - } - } + lParams = LuaUtils.createLuaParamList("/Area/Zone/" + className, false, true, zoneName, "", -1, canRideChocobo ? (byte)1 : (byte)0, canStealth, isInn, false, false, false, true, isInstanceRaid, isEntranceDesion); + return ActorInstantiatePacket.buildPacket(actorId, playerActorId, actorName, className, lParams); } } diff --git a/FFXIVClassic Map Server/actors/chara/player/Player.cs b/FFXIVClassic Map Server/actors/chara/player/Player.cs index 53831dd5..58236d45 100644 --- a/FFXIVClassic Map Server/actors/chara/player/Player.cs +++ b/FFXIVClassic Map Server/actors/chara/player/Player.cs @@ -1,6 +1,7 @@ using FFXIVClassic_Lobby_Server; using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.packets; +using FFXIVClassic_Map_Server.actors.area; using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects.chara; using FFXIVClassic_Map_Server.lua; @@ -87,8 +88,9 @@ namespace FFXIVClassic_Map_Server.Actors charaWork.property[4] = 1; charaWork.command[0] = 0xA0F00000 | 21001; - charaWork.command[1] = 0xA0F00000 | 21002; - charaWork.command[2] = 0xA0F00000 | 12003; + charaWork.command[1] = 0xA0F00000 | 21001; + + charaWork.command[2] = 0xA0F00000 | 21002; charaWork.command[3] = 0xA0F00000 | 12004; charaWork.command[4] = 0xA0F00000 | 21005; charaWork.command[5] = 0xA0F00000 | 21006; @@ -103,9 +105,6 @@ namespace FFXIVClassic_Map_Server.Actors charaWork.command[14] = 0xA0F00000 | 29497; charaWork.command[15] = 0xA0F00000 | 22015; - charaWork.command[32] = 0xA0F00000 | 27155; - //charaWork.command[33] = 0xA0F00000 | 27150; - charaWork.command[34] = 0xA0F00000 | 27300; charaWork.commandAcquired[27150 - 26000] = true; @@ -120,10 +119,15 @@ namespace FFXIVClassic_Map_Server.Actors charaWork.battleTemp.generalParameter[3] = 1; - charaWork.eventSave.bazaarTax = 5; charaWork.battleSave.potencial = 6.6f; - + + charaWork.commandCategory[0] = 1; + charaWork.commandCategory[1] = 1; + + charaWork.parameterSave.commandSlot_compatibility[0] = true; + charaWork.parameterSave.commandSlot_compatibility[1] = true; + charaWork.commandBorder = 0x20; Database.loadPlayerCharacter(this); @@ -737,5 +741,18 @@ namespace FFXIVClassic_Map_Server.Actors return eventMenuId; } + + internal void sendInstanceUpdate() + { + + //Update Instance + List instanceUpdatePackets = playerSession.updateInstance(zone.getActorsAroundActor(this, 50)); + foreach (BasePacket bp in instanceUpdatePackets) + { + // bp.debugPrintPacket(); + queuePacket(bp); + } + + } } } diff --git a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs index ac0ae74f..060a3c24 100644 --- a/FFXIVClassic Map Server/actors/director/WeatherDirector.cs +++ b/FFXIVClassic Map Server/actors/director/WeatherDirector.cs @@ -14,7 +14,7 @@ namespace FFXIVClassic_Map_Server.Actors { private uint weatherId; - public WeatherDirector(uint weatherId, Zone zone) + public WeatherDirector(uint weatherId) : base(0x5FF80002) { this.weatherId = weatherId; diff --git a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs index 1138d031..f25f3025 100644 --- a/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs +++ b/FFXIVClassic Map Server/dataobjects/ConnectedPlayer.cs @@ -19,6 +19,8 @@ namespace FFXIVClassic_Map_Server.dataobjects private ClientConnection zoneConnection; private ClientConnection chatConnection; + public string errorMessage = ""; + bool isDisconnected; public ConnectedPlayer(uint actorId) @@ -60,7 +62,7 @@ namespace FFXIVClassic_Map_Server.dataobjects public void queuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted) { - zoneConnection.queuePacket(subPacket, isAuthed, isEncrypted); + zoneConnection.queuePacket(subPacket, isAuthed, isEncrypted); } public Player getActor() @@ -142,5 +144,11 @@ namespace FFXIVClassic_Map_Server.dataobjects return basePackets; } + + public void clearInstance() + { + actorInstanceList.Clear(); + } + } } diff --git a/FFXIVClassic Map Server/packets/BasePacket.cs b/FFXIVClassic Map Server/packets/BasePacket.cs index b06121d3..a56f9768 100644 --- a/FFXIVClassic Map Server/packets/BasePacket.cs +++ b/FFXIVClassic Map Server/packets/BasePacket.cs @@ -163,7 +163,7 @@ namespace FFXIVClassic_Lobby_Server.packets while (binreader.BaseStream.Position + 4 < data.Length) { uint read = binreader.ReadUInt32(); - if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3) //Original ID + if (read == 0x029B2941 || read == 0x02977DC7 || read == 0x0297D2C8 || read == 0x0230d573 || read == 0x23317df || read == 0x23344a3 || read == 0x1730bdb) //Original ID { binWriter.BaseStream.Seek(binreader.BaseStream.Position - 0x4, SeekOrigin.Begin); binWriter.Write(actorID); diff --git a/FFXIVClassic Map Server/packets/receive/events/EventStartPacket.cs b/FFXIVClassic Map Server/packets/receive/events/EventStartPacket.cs index aa3b3de0..835972fc 100644 --- a/FFXIVClassic Map Server/packets/receive/events/EventStartPacket.cs +++ b/FFXIVClassic Map Server/packets/receive/events/EventStartPacket.cs @@ -1,4 +1,5 @@ -using FFXIVClassic_Map_Server.lua; +using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Map_Server.lua; using System; using System.Collections.Generic; using System.IO; @@ -21,6 +22,10 @@ namespace FFXIVClassic_Map_Server.packets.receive.events public uint val2; public byte val3; + public uint errorIndex; + public uint errorNum; + public string error = null; + public string eventStarter; public List luaParams; @@ -37,7 +42,20 @@ namespace FFXIVClassic_Map_Server.packets.receive.events val1 = binReader.ReadUInt32(); val2 = binReader.ReadUInt32(); val3 = binReader.ReadByte(); + /* + //Lua Error Dump + if (val1 == 0x39800010) + { + errorIndex = actorID; + errorNum = scriptOwnerActorID; + error = ASCIIEncoding.ASCII.GetString(binReader.ReadBytes(0x80)).Replace("\0", ""); + if (errorIndex == 0) + Log.error("LUA ERROR:"); + + return; + } + */ List strList = new List(); byte curByte; while ((curByte = binReader.ReadByte())!=0) diff --git a/FFXIVClassic Map Server/packets/send/Actor/ActorInstantiatePacket.cs b/FFXIVClassic Map Server/packets/send/Actor/ActorInstantiatePacket.cs index 61b1c5a8..b7fa6d20 100644 --- a/FFXIVClassic Map Server/packets/send/Actor/ActorInstantiatePacket.cs +++ b/FFXIVClassic Map Server/packets/send/Actor/ActorInstantiatePacket.cs @@ -22,8 +22,10 @@ namespace FFXIVClassic_Map_Server.packets.send.actor { using (BinaryWriter binWriter = new BinaryWriter(mem)) { - int value = 0; - binWriter.Write((Int32)value); + int value1 = 0x10; //Instance ID? + int value2 = 0x3980; + binWriter.Write((Int16)value1); + binWriter.Write((Int16)value2); binWriter.Write(Encoding.ASCII.GetBytes(objectName), 0, Encoding.ASCII.GetByteCount(objectName) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(objectName)); binWriter.BaseStream.Seek(0x24, SeekOrigin.Begin); binWriter.Write(Encoding.ASCII.GetBytes(className), 0, Encoding.ASCII.GetByteCount(className) >= 0x20 ? 0x20 : Encoding.ASCII.GetByteCount(className));