1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-21 20:27:47 +00:00

Moving zone/login stuff away from packetprocessor into a "WorldManager" class.

This commit is contained in:
Filip Maj 2016-01-17 23:36:34 -05:00
parent a640e08fe1
commit 887da7b503
8 changed files with 331 additions and 73 deletions

View file

@ -543,51 +543,5 @@ namespace FFXIVClassic_Lobby_Server
return cheevosPacket.buildPacket(player.actorId); return cheevosPacket.buildPacket(player.actorId);
} }
public static void loadZones(Efficient32bitHashTable<Zone> zoneList)
{
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();
string query = @"
SELECT
id,
regionId,
zoneName,
dayMusic,
nightMusic,
battleMusic,
isInn,
canRideChocobo,
canStealth,
isInstanceRaid
FROM server_zones
WHERE zoneName IS NOT NULL";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
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));
zoneList.Add(zone.actorId, zone);
count++;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
Log.info(String.Format("Loaded {0} zones.", count));
}
} }
} }

View file

@ -213,6 +213,7 @@
<Compile Include="utils\CharacterUtils.cs" /> <Compile Include="utils\CharacterUtils.cs" />
<Compile Include="utils\SQLGeneration.cs" /> <Compile Include="utils\SQLGeneration.cs" />
<Compile Include="actors\area\Zone.cs" /> <Compile Include="actors\area\Zone.cs" />
<Compile Include="WorldManager.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="App.config" /> <None Include="App.config" />

View file

@ -42,23 +42,16 @@ namespace FFXIVClassic_Lobby_Server
{ {
class PacketProcessor class PacketProcessor
{ {
Server mServer;
LuaEngine luaEngine = new LuaEngine(); LuaEngine luaEngine = new LuaEngine();
Dictionary<uint, ConnectedPlayer> mPlayers; Dictionary<uint, ConnectedPlayer> mPlayers;
List<ClientConnection> mConnections; List<ClientConnection> mConnections;
StaticActors mStaticActors = new StaticActors(); public PacketProcessor(Server server, Dictionary<uint, ConnectedPlayer> playerList, List<ClientConnection> connectionList)
DebugProg debug = new DebugProg();
WorldMaster worldMaster = new WorldMaster();
Efficient32bitHashTable<Zone> zoneList = new Efficient32bitHashTable<Zone>();
public PacketProcessor(Dictionary<uint, ConnectedPlayer> playerList, List<ClientConnection> connectionList)
{ {
mPlayers = playerList; mPlayers = playerList;
mConnections = connectionList; mConnections = connectionList;
mServer = server;
Database.loadZones(zoneList);
} }
public void processPacket(ClientConnection client, BasePacket packet) public void processPacket(ClientConnection client, BasePacket packet)
@ -191,7 +184,7 @@ namespace FFXIVClassic_Lobby_Server
//Unknown //Unknown
case 0x0002: case 0x0002:
player.getActor().zone = zoneList.Get(player.getActor().zoneId); player.getActor().zone = mServer.GetWorldManager().GetZone(player.getActor().zoneId);
BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); //Bed, Book created 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 reply10 = new BasePacket("./packets/login/login10.bin"); //Item Storage, Inn Door created
@ -305,8 +298,8 @@ namespace FFXIVClassic_Lobby_Server
player.getActor().zone.addActorToZone(player.getActor()); player.getActor().zone.addActorToZone(player.getActor());
BasePacket innSpawn = player.getActor().zone.getSpawnPackets(player.actorID); BasePacket innSpawn = player.getActor().zone.getSpawnPackets(player.actorID);
BasePacket debugSpawn = debug.getSpawnPackets(player.actorID); BasePacket debugSpawn = mServer.GetWorldManager().GetDebugActor().getSpawnPackets(player.actorID);
BasePacket worldMasterSpawn = worldMaster.getSpawnPackets(player.actorID); BasePacket worldMasterSpawn = mServer.GetWorldManager().GetActor().getSpawnPackets(player.actorID);
innSpawn.debugPrintPacket(); innSpawn.debugPrintPacket();
client.queuePacket(innSpawn); client.queuePacket(innSpawn);

View file

@ -11,6 +11,8 @@ using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Lobby_Server.packets;
using System.IO; using System.IO;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server;
using FFXIVClassic_Map_Server.actors;
namespace FFXIVClassic_Lobby_Server namespace FFXIVClassic_Lobby_Server
{ {
@ -24,6 +26,8 @@ namespace FFXIVClassic_Lobby_Server
private Dictionary<uint,ConnectedPlayer> mConnectedPlayerList = new Dictionary<uint,ConnectedPlayer>(); private Dictionary<uint,ConnectedPlayer> mConnectedPlayerList = new Dictionary<uint,ConnectedPlayer>();
private List<ClientConnection> mConnectionList = new List<ClientConnection>(); private List<ClientConnection> mConnectionList = new List<ClientConnection>();
private WorldManager mWorldManager;
private StaticActors mStaticActors = new StaticActors();
private PacketProcessor mProcessor; private PacketProcessor mProcessor;
private Thread mProcessorThread; private Thread mProcessorThread;
private Thread mGameThread; private Thread mGameThread;
@ -31,6 +35,9 @@ namespace FFXIVClassic_Lobby_Server
#region Socket Handling #region Socket Handling
public bool startServer() public bool startServer()
{ {
mWorldManager = new WorldManager();
mWorldManager.LoadZoneList();
IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), FFXIV_MAP_PORT); IPEndPoint serverEndPoint = new System.Net.IPEndPoint(IPAddress.Parse(ConfigConstants.OPTIONS_BINDIP), FFXIV_MAP_PORT);
try{ try{
@ -63,7 +70,7 @@ namespace FFXIVClassic_Lobby_Server
Console.WriteLine("{0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port); Console.WriteLine("{0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port);
Console.ForegroundColor = ConsoleColor.Gray; Console.ForegroundColor = ConsoleColor.Gray;
mProcessor = new PacketProcessor(mConnectedPlayerList, mConnectionList); mProcessor = new PacketProcessor(this, mConnectedPlayerList, mConnectionList);
//mGameThread = new Thread(new ThreadStart(mProcessor.update)); //mGameThread = new Thread(new ThreadStart(mProcessor.update));
//mGameThread.Start(); //mGameThread.Start();
@ -274,5 +281,11 @@ namespace FFXIVClassic_Lobby_Server
mProcessor.doWarp(Convert.ToUInt32(map), Single.Parse(x), Single.Parse(y), Single.Parse(z)); mProcessor.doWarp(Convert.ToUInt32(map), Single.Parse(x), Single.Parse(y), Single.Parse(z));
} }
public WorldManager GetWorldManager()
{
return mWorldManager;
} }
}
} }

View file

@ -0,0 +1,245 @@
using FFXIVClassic_Lobby_Server;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Map_Server.actors;
using FFXIVClassic_Map_Server.actors.debug;
using FFXIVClassic_Map_Server.actors.world;
using FFXIVClassic_Map_Server.common.EfficientHashTables;
using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.packets.send;
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server
{
class WorldManager
{
private DebugProg debug = new DebugProg();
private WorldMaster worldMaster = new WorldMaster();
private Dictionary<uint, Zone> zoneList;
private Dictionary<uint, ZoneEntrance> zoneEntranceList;
public void LoadZoneList()
{
zoneList = new Dictionary<uint, Zone>();
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();
string query = @"
SELECT
id,
regionId,
zoneName,
dayMusic,
nightMusic,
battleMusic,
isInn,
canRideChocobo,
canStealth,
isInstanceRaid
FROM server_zones
WHERE zoneName IS NOT NULL";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
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));
zoneList[zone.actorId] = zone;
count++;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
Log.info(String.Format("Loaded {0} zones.", count));
}
public void LoadZoneEntranceList()
{
zoneEntranceList = new Dictionary<uint, ZoneEntrance>();
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();
string query = @"
SELECT
id,
zoneId,
spawnType,
spawnX,
spawnY,
spawnZ,
spawnRotation
FROM server_zones_spawnlocations";
MySqlCommand cmd = new MySqlCommand(query, conn);
using (MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
uint id = reader.GetUInt32(0);
ZoneEntrance entance = new ZoneEntrance(reader.GetUInt32(1), reader.GetByte(2), reader.GetFloat(3), reader.GetFloat(4), reader.GetFloat(5), reader.GetFloat(6));
zoneEntranceList[id] = entance;
count++;
}
}
}
catch (MySqlException e)
{ Console.WriteLine(e); }
finally
{
conn.Dispose();
}
}
Log.info(String.Format("Loaded {0} zone spawn locations.", count));
}
//Moves the actor to the new zone if exists. No packets are sent nor position changed.
public void DoSeamlessZoneChange(Player player, uint destinationZoneId)
{
Zone oldZone;
if (player.zone != null)
{
oldZone = player.zone;
oldZone.removeActorToZone(player);
}
//Add player to new zone and update
Zone newZone = GetZone(destinationZoneId);
//This server does not contain that zoneId
if (newZone == null)
return;
newZone.addActorToZone(player);
}
//Moves actor to new zone, and sends packets to spawn at the given zone entrance
public void DoTeleportZoneChange(Player player, uint destinationZoneId, uint zoneEntrance)
{
if (!zoneEntranceList.ContainsKey(zoneEntrance))
{
Log.error("Given zone entrance was not found: " + zoneEntrance);
return;
}
ZoneEntrance ze = zoneEntranceList[zoneEntrance];
DoTeleportZoneChange(player, destinationZoneId, ze.spawnType, ze.spawnX, ze.spawnY, ze.spawnZ, ze.spawnRotation);
}
//Moves actor to new zone, and sends packets to spawn at the given coords.
public void DoTeleportZoneChange(Player player, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
{
Zone oldZone;
//Remove player from currentZone if transfer else it's login
if (player.zone != null)
{
oldZone = player.zone;
oldZone.removeActorToZone(player);
}
//Add player to new zone and update
Zone newZone = GetZone(destinationZoneId);
//This server does not contain that zoneId
if (newZone == null)
return;
newZone.addActorToZone(player);
//Update player actor's properties
player.zoneId = newZone.actorId;
player.zone = newZone;
player.positionX = spawnX;
player.positionY = spawnY;
player.positionZ = spawnZ;
player.rotation = spawnRotation;
//Send packets
player.sendZoneInPackets(this);
}
public Player GetPCInWorld(string name)
{
foreach (Zone zone in zoneList.Values)
{
Player p = zone.FindPCInZone(name);
if (p != null)
return p;
}
return null;
}
public Player GetPCInWorld(uint charId)
{
foreach (Zone zone in zoneList.Values)
{
Player p = zone.FindPCInZone(charId);
if (p != null)
return p;
}
return null;
}
public Zone GetZone(uint zoneId)
{
return zoneList[zoneId];
}
public WorldMaster GetActor()
{
return worldMaster;
}
public DebugProg GetDebugActor()
{
return debug;
}
public class ZoneEntrance
{
public uint zoneId;
public byte spawnType;
public float spawnX;
public float spawnY;
public float spawnZ;
public float spawnRotation;
public ZoneEntrance(uint zoneId, byte spawnType, float x, float y, float z, float rot)
{
this.zoneId = zoneId;
this.spawnType = spawnType;
this.spawnX = x;
this.spawnY = y;
this.spawnZ = z;
this.spawnRotation = rot;
}
}
}
}

View file

@ -1,6 +1,7 @@
using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Map_Server.dataobjects;
using FFXIVClassic_Map_Server.dataobjects.chara;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using System; using System;
@ -23,7 +24,9 @@ namespace FFXIVClassic_Map_Server
public int minX = -100, minY = -100, maxX = 100, maxY = 100; public int minX = -100, minY = -100, maxX = 100, maxY = 100;
private int numXBlocks, numYBlocks; private int numXBlocks, numYBlocks;
private int halfWidth, halfHeight; private int halfWidth, halfHeight;
private List<Actor>[,] actorBlock;
private Dictionary<uint, Actor> mActorList = new Dictionary<uint,Actor>();
private List<Actor>[,] mActorBlock;
public Zone(uint id, string zoneName, ushort regionId, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool canStealth, bool isInn, bool canRideChocobo, bool isInstanceRaid) public Zone(uint id, string zoneName, ushort regionId, ushort bgmDay, ushort bgmNight, ushort bgmBattle, bool canStealth, bool isInn, bool canRideChocobo, bool isInstanceRaid)
: base(id) : base(id)
@ -48,7 +51,7 @@ namespace FFXIVClassic_Map_Server
numXBlocks = (maxX - minX) / boundingGridSize; numXBlocks = (maxX - minX) / boundingGridSize;
numYBlocks = (maxY - minY) / boundingGridSize; numYBlocks = (maxY - minY) / boundingGridSize;
actorBlock = new List<Actor>[numXBlocks, numYBlocks]; mActorBlock = new List<Actor>[numXBlocks, numYBlocks];
halfWidth = numXBlocks / 2; halfWidth = numXBlocks / 2;
halfHeight = numYBlocks / 2; halfHeight = numYBlocks / 2;
@ -56,7 +59,7 @@ namespace FFXIVClassic_Map_Server
{ {
for (int x = 0; x < numXBlocks; x++ ) for (int x = 0; x < numXBlocks; x++ )
{ {
actorBlock[x, y] = new List<Actor>(); mActorBlock[x, y] = new List<Actor>();
} }
} }
@ -86,6 +89,8 @@ namespace FFXIVClassic_Map_Server
public void addActorToZone(Actor actor) public void addActorToZone(Actor actor)
{ {
mActorList.Add(actor.actorId, actor);
int gridX = (int)actor.positionX / boundingGridSize; int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize; int gridY = (int)actor.positionZ / boundingGridSize;
@ -102,12 +107,14 @@ namespace FFXIVClassic_Map_Server
if (gridY >= numYBlocks) if (gridY >= numYBlocks)
gridY = numYBlocks - 1; gridY = numYBlocks - 1;
lock (actorBlock) lock (mActorBlock)
actorBlock[gridX, gridY].Add(actor); mActorBlock[gridX, gridY].Add(actor);
} }
public void removeActorToZone(Actor actor) public void removeActorToZone(Actor actor)
{ {
mActorList.Remove(actor.actorId);
int gridX = (int)actor.positionX / boundingGridSize; int gridX = (int)actor.positionX / boundingGridSize;
int gridY = (int)actor.positionZ / boundingGridSize; int gridY = (int)actor.positionZ / boundingGridSize;
@ -124,8 +131,8 @@ namespace FFXIVClassic_Map_Server
if (gridY >= numYBlocks) if (gridY >= numYBlocks)
gridY = numYBlocks - 1; gridY = numYBlocks - 1;
lock (actorBlock) lock (mActorBlock)
actorBlock[gridX, gridY].Remove(actor); mActorBlock[gridX, gridY].Remove(actor);
} }
public void updateActorPosition(Actor actor) public void updateActorPosition(Actor actor)
@ -166,10 +173,10 @@ namespace FFXIVClassic_Map_Server
if (gridX == gridOldX && gridY == gridOldY) if (gridX == gridOldX && gridY == gridOldY)
return; return;
lock (actorBlock) lock (mActorBlock)
actorBlock[gridOldX, gridOldY].Remove(actor); mActorBlock[gridOldX, gridOldY].Remove(actor);
lock (actorBlock) lock (mActorBlock)
actorBlock[gridX, gridY].Add(actor); mActorBlock[gridX, gridY].Add(actor);
} }
public List<Actor> getActorsAroundPoint(float x, float y, int checkDistance) public List<Actor> getActorsAroundPoint(float x, float y, int checkDistance)
@ -196,7 +203,7 @@ namespace FFXIVClassic_Map_Server
{ {
for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++) for (int gy = gridY - checkDistance; gy <= gridY + checkDistance; gy++)
{ {
result.AddRange(actorBlock[gx, gy]); result.AddRange(mActorBlock[gx, gy]);
} }
} }
@ -219,7 +226,7 @@ namespace FFXIVClassic_Map_Server
{ {
for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++) for (int gx = ((gridX - checkDistance) < 0 ? 0 : (gridX - checkDistance)); gx <= ((gridX + checkDistance) >= numXBlocks ? numXBlocks - 1 : (gridX + checkDistance)); gx++)
{ {
result.AddRange(actorBlock[gx, gy]); result.AddRange(mActorBlock[gx, gy]);
} }
} }
@ -227,5 +234,26 @@ namespace FFXIVClassic_Map_Server
} }
#endregion #endregion
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];
}
} }
} }

View file

@ -2,6 +2,7 @@
using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.packets; using FFXIVClassic_Lobby_Server.packets;
using FFXIVClassic_Map_Server.lua; using FFXIVClassic_Map_Server.lua;
using FFXIVClassic_Map_Server.packets.send;
using FFXIVClassic_Map_Server.packets.send.actor; using FFXIVClassic_Map_Server.packets.send.actor;
using FFXIVClassic_Map_Server.packets.send.player; using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
@ -356,6 +357,27 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
return propPacketUtil.done(); return propPacketUtil.done();
} }
public void sendZoneInPackets(WorldManager world)
{
ClientConnection client;
client.queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId), true, false);
//client.queuePacket(_0x2Packet.buildPacket(player.actorID), true, false);
client.queuePacket(SetMusicPacket.buildPacket(actorId, 0x3D, 0x01), true, false);
client.queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR), true, false);
client.queuePacket(getSpawnPackets(actorId));
client.queuePacket(getInitPackets(actorId));
BasePacket innSpawn = zone.getSpawnPackets(actorId);
BasePacket debugSpawn = world.GetDebugActor().getSpawnPackets(actorId);
BasePacket worldMasterSpawn = world.GetActor().getSpawnPackets(actorId);
client.queuePacket(innSpawn);
client.queuePacket(debugSpawn);
client.queuePacket(worldMasterSpawn);
}
public bool isMyPlayer(uint otherActorId) public bool isMyPlayer(uint otherActorId)
{ {
return actorId == otherActorId; return actorId == otherActorId;

View file

@ -154,6 +154,8 @@ namespace FFXIVClassic_Map_Server.common
return r; return r;
} }
} }
} }