mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
Built subpackets to let the zone servers talk to the world server. Implemented cross-server zoning but the E2 packet or something isn't being sent.
This commit is contained in:
parent
58fda93b45
commit
e30831fdc5
@ -258,6 +258,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
positionY = @y,
|
positionY = @y,
|
||||||
positionZ = @z,
|
positionZ = @z,
|
||||||
rotation = @rot,
|
rotation = @rot,
|
||||||
|
destinationZoneId = @destZone,
|
||||||
|
destinationSpawnType = @destSpawn,
|
||||||
currentZoneId = @zoneId
|
currentZoneId = @zoneId
|
||||||
WHERE id = @charaId
|
WHERE id = @charaId
|
||||||
";
|
";
|
||||||
@ -269,6 +271,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
cmd.Parameters.AddWithValue("@z", player.positionZ);
|
||||||
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
cmd.Parameters.AddWithValue("@rot", player.rotation);
|
||||||
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
cmd.Parameters.AddWithValue("@zoneId", player.zoneId);
|
||||||
|
cmd.Parameters.AddWithValue("@destZone", player.destinationZone);
|
||||||
|
cmd.Parameters.AddWithValue("@destSpawn", player.destinationSpawnType);
|
||||||
|
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
@ -402,7 +406,9 @@ namespace FFXIVClassic_Map_Server
|
|||||||
tribe,
|
tribe,
|
||||||
restBonus,
|
restBonus,
|
||||||
achievementPoints,
|
achievementPoints,
|
||||||
playTime
|
playTime,
|
||||||
|
destinationZoneId,
|
||||||
|
destinationSpawnType
|
||||||
FROM characters WHERE id = @charId";
|
FROM characters WHERE id = @charId";
|
||||||
|
|
||||||
cmd = new MySqlCommand(query, conn);
|
cmd = new MySqlCommand(query, conn);
|
||||||
@ -420,7 +426,6 @@ namespace FFXIVClassic_Map_Server
|
|||||||
player.currentMainState = reader.GetUInt16(5);
|
player.currentMainState = reader.GetUInt16(5);
|
||||||
player.zoneId = reader.GetUInt32(6);
|
player.zoneId = reader.GetUInt32(6);
|
||||||
player.isZoning = true;
|
player.isZoning = true;
|
||||||
player.zone = Server.GetWorldManager().GetZone(player.zoneId);
|
|
||||||
player.gcCurrent = reader.GetByte(7);
|
player.gcCurrent = reader.GetByte(7);
|
||||||
player.gcRankLimsa = reader.GetByte(8);
|
player.gcRankLimsa = reader.GetByte(8);
|
||||||
player.gcRankGridania = reader.GetByte(9);
|
player.gcRankGridania = reader.GetByte(9);
|
||||||
@ -434,6 +439,13 @@ namespace FFXIVClassic_Map_Server
|
|||||||
player.playerWork.restBonusExpRate = reader.GetInt32(17);
|
player.playerWork.restBonusExpRate = reader.GetInt32(17);
|
||||||
player.achievementPoints = reader.GetUInt32(18);
|
player.achievementPoints = reader.GetUInt32(18);
|
||||||
player.playTime = reader.GetUInt32(19);
|
player.playTime = reader.GetUInt32(19);
|
||||||
|
player.destinationZone = reader.GetUInt32("destinationZoneId");
|
||||||
|
player.destinationSpawnType = reader.GetByte("destinationSpawnType");
|
||||||
|
|
||||||
|
if (player.destinationZone != 0)
|
||||||
|
player.zoneId = player.destinationZone;
|
||||||
|
|
||||||
|
player.zone = Server.GetWorldManager().GetZone(player.zoneId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,6 +256,10 @@
|
|||||||
<Compile Include="packets\send\_0xE2Packet.cs" />
|
<Compile Include="packets\send\_0xE2Packet.cs" />
|
||||||
<Compile Include="packets\receive\PingPacket.cs" />
|
<Compile Include="packets\receive\PingPacket.cs" />
|
||||||
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
|
<Compile Include="packets\receive\UpdatePlayerPositionPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Receive\SessionEndPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Receive\SessionBeginPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\SessionBeginConfirmPacket.cs" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\SessionEndConfirmPacket.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="lua\LuaUtils.cs" />
|
<Compile Include="lua\LuaUtils.cs" />
|
||||||
@ -280,6 +284,7 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
</None>
|
</None>
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
|
<Compile Include="packets\WorldPackets\Send\WorldRequestZoneChangePacket.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Properties\Resources.resx">
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
@ -18,6 +18,8 @@ using FFXIVClassic_Map_Server.packets.send.recruitment;
|
|||||||
using FFXIVClassic_Map_Server.packets.receive.events;
|
using FFXIVClassic_Map_Server.packets.receive.events;
|
||||||
using FFXIVClassic_Map_Server.lua;
|
using FFXIVClassic_Map_Server.lua;
|
||||||
using FFXIVClassic_Map_Server.Actors;
|
using FFXIVClassic_Map_Server.Actors;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Receive;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server
|
namespace FFXIVClassic_Map_Server
|
||||||
{
|
{
|
||||||
@ -34,20 +36,33 @@ namespace FFXIVClassic_Map_Server
|
|||||||
{
|
{
|
||||||
Session session = mServer.GetSession(subpacket.header.targetId);
|
Session session = mServer.GetSession(subpacket.header.targetId);
|
||||||
|
|
||||||
|
if (session == null && subpacket.gameMessage.opcode != 0x1000)
|
||||||
|
return;
|
||||||
|
|
||||||
//Normal Game Opcode
|
//Normal Game Opcode
|
||||||
switch (subpacket.gameMessage.opcode)
|
switch (subpacket.gameMessage.opcode)
|
||||||
{
|
{
|
||||||
//World Server - End Session
|
//World Server - Session Begin
|
||||||
case 0x1000:
|
case 0x1000:
|
||||||
session.GetActor().CleanupAndSave();
|
subpacket.DebugPrintSubPacket();
|
||||||
break;
|
session = mServer.AddSession(subpacket.header.targetId);
|
||||||
//World Server - End Session and Zone
|
|
||||||
case 0x1001:
|
|
||||||
|
|
||||||
session.GetActor().CleanupAndSave();
|
if (session.GetActor().destinationZone != 0)
|
||||||
|
Server.GetWorldManager().DoZoneIn(session.GetActor(), false, session.GetActor().destinationSpawnType);
|
||||||
|
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
break;
|
break;
|
||||||
//World Server - Begin Session
|
//World Server - Session End
|
||||||
case 0x1002:
|
case 0x1001:
|
||||||
|
SessionEndPacket endSessionPacket = new SessionEndPacket(subpacket.data);
|
||||||
|
|
||||||
|
if (endSessionPacket.destinationZoneId == 0)
|
||||||
|
session.GetActor().CleanupAndSave();
|
||||||
|
else
|
||||||
|
session.GetActor().CleanupAndSave(endSessionPacket.destinationZoneId, endSessionPacket.destinationSpawnType, endSessionPacket.destinationX, endSessionPacket.destinationY, endSessionPacket.destinationZ, endSessionPacket.destinationRot);
|
||||||
|
|
||||||
|
client.QueuePacket(SessionEndConfirmPacket.BuildPacket(session, endSessionPacket.destinationZoneId), true, false);
|
||||||
|
client.FlushQueuedSendPackets();
|
||||||
break;
|
break;
|
||||||
//Ping
|
//Ping
|
||||||
case 0x0001:
|
case 0x0001:
|
||||||
@ -60,12 +75,12 @@ namespace FFXIVClassic_Map_Server
|
|||||||
case 0x0002:
|
case 0x0002:
|
||||||
|
|
||||||
subpacket.DebugPrintSubPacket();
|
subpacket.DebugPrintSubPacket();
|
||||||
|
|
||||||
session = mServer.AddSession(subpacket.header.targetId);
|
session = mServer.AddSession(subpacket.header.targetId);
|
||||||
|
|
||||||
client.QueuePacket(_0x2Packet.BuildPacket(session.id), true, false);
|
client.QueuePacket(_0x2Packet.BuildPacket(session.id), true, false);
|
||||||
|
|
||||||
Server.GetWorldManager().DoLogin(session.GetActor());
|
LuaEngine.OnBeginLogin(session.GetActor());
|
||||||
|
Server.GetWorldManager().DoZoneIn(session.GetActor(), true, 0x1);
|
||||||
|
LuaEngine.OnLogin(session.GetActor());
|
||||||
|
|
||||||
client.FlushQueuedSendPackets();
|
client.FlushQueuedSendPackets();
|
||||||
|
|
||||||
@ -98,7 +113,6 @@ namespace FFXIVClassic_Map_Server
|
|||||||
//Update Position
|
//Update Position
|
||||||
case 0x00CA:
|
case 0x00CA:
|
||||||
//Update Position
|
//Update Position
|
||||||
subpacket.DebugPrintSubPacket();
|
|
||||||
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
UpdatePlayerPositionPacket posUpdate = new UpdatePlayerPositionPacket(subpacket.data);
|
||||||
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
session.UpdatePlayerActorPosition(posUpdate.x, posUpdate.y, posUpdate.z, posUpdate.rot, posUpdate.moveState);
|
||||||
session.GetActor().SendInstanceUpdate();
|
session.GetActor().SendInstanceUpdate();
|
||||||
|
@ -95,6 +95,9 @@ namespace FFXIVClassic_Map_Server
|
|||||||
|
|
||||||
public Session AddSession(uint id)
|
public Session AddSession(uint id)
|
||||||
{
|
{
|
||||||
|
if (mSessionList.ContainsKey(id))
|
||||||
|
return mSessionList[id];
|
||||||
|
|
||||||
Session session = new Session(id);
|
Session session = new Session(id);
|
||||||
mSessionList.Add(id, session);
|
mSessionList.Add(id, session);
|
||||||
return session;
|
return session;
|
||||||
@ -104,7 +107,6 @@ namespace FFXIVClassic_Map_Server
|
|||||||
{
|
{
|
||||||
if (mSessionList.ContainsKey(id))
|
if (mSessionList.ContainsKey(id))
|
||||||
{
|
{
|
||||||
mSessionList[id].GetActor().CleanupAndSave();
|
|
||||||
mSessionList.Remove(id);
|
mSessionList.Remove(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -244,6 +246,11 @@ namespace FFXIVClassic_Map_Server
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public static ZoneConnection GetWorldConnection()
|
||||||
|
{
|
||||||
|
return mWorldConnection;
|
||||||
|
}
|
||||||
|
|
||||||
public static Server GetServer()
|
public static Server GetServer()
|
||||||
{
|
{
|
||||||
return mSelf;
|
return mSelf;
|
||||||
@ -254,11 +261,6 @@ namespace FFXIVClassic_Map_Server
|
|||||||
return mCommandProcessor;
|
return mCommandProcessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ZoneConnection GetWorldConnection()
|
|
||||||
{
|
|
||||||
return mWorldConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WorldManager GetWorldManager()
|
public static WorldManager GetWorldManager()
|
||||||
{
|
{
|
||||||
return mWorldManager;
|
return mWorldManager;
|
||||||
|
@ -384,9 +384,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
oldZone.AddActorToZone(player);
|
oldZone.AddActorToZone(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = "WorldManager.DoZoneChange: unable to change areas, new area is not valid.";
|
Program.Log.Debug("Request to change to zone not on this server by: {0}.", player.customDisplayName);
|
||||||
player.SendMessage(SendMessagePacket.MESSAGE_TYPE_SYSTEM, "[Debug]", message);
|
RequestWorldServerZoneChange(player, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation);
|
||||||
Program.Log.Debug(message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,8 +449,8 @@ namespace FFXIVClassic_Map_Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Login Zone In
|
//Session started, zone into world
|
||||||
public void DoLogin(Player player)
|
public void DoZoneIn(Player player, bool isLogin, ushort spawnType)
|
||||||
{
|
{
|
||||||
//Add player to new zone and update
|
//Add player to new zone and update
|
||||||
Zone zone = GetZone(player.zoneId);
|
Zone zone = GetZone(player.zoneId);
|
||||||
@ -463,14 +462,18 @@ namespace FFXIVClassic_Map_Server
|
|||||||
//Set the current zone and add player
|
//Set the current zone and add player
|
||||||
player.zone = zone;
|
player.zone = zone;
|
||||||
|
|
||||||
LuaEngine.OnBeginLogin(player);
|
|
||||||
|
|
||||||
zone.AddActorToZone(player);
|
zone.AddActorToZone(player);
|
||||||
|
|
||||||
//Send packets
|
//Send packets
|
||||||
player.SendZoneInPackets(this, 0x1);
|
if (!isLogin)
|
||||||
|
{
|
||||||
|
player.playerSession.QueuePacket(DeleteAllActorsPacket.BuildPacket(player.actorId), true, false);
|
||||||
|
player.playerSession.QueuePacket(_0xE2Packet.BuildPacket(player.actorId, 0x0), true, false);
|
||||||
|
player.playerSession.QueuePacket(_0xE2Packet.BuildPacket(player.actorId, 0x0), true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.SendZoneInPackets(this, spawnType);
|
||||||
|
|
||||||
LuaEngine.OnLogin(player);
|
|
||||||
LuaEngine.OnZoneIn(player);
|
LuaEngine.OnZoneIn(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,6 +488,12 @@ namespace FFXIVClassic_Map_Server
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RequestWorldServerZoneChange(Player player, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
ZoneConnection zc = Server.GetWorldConnection();
|
||||||
|
zc.RequestZoneChange(player.playerSession.id, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation);
|
||||||
|
}
|
||||||
|
|
||||||
public Player GetPCInWorld(string name)
|
public Player GetPCInWorld(string name)
|
||||||
{
|
{
|
||||||
foreach (Zone zone in zoneList.Values)
|
foreach (Zone zone in zoneList.Values)
|
||||||
|
@ -70,7 +70,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return SetActorSpeedPacket.BuildPacket(actorId, playerActorId);
|
return SetActorSpeedPacket.BuildPacket(actorId, playerActorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateSpawnPositonPacket(uint playerActorId, uint spawnType)
|
public SubPacket CreateSpawnPositonPacket(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
SubPacket spawnPacket;
|
SubPacket spawnPacket;
|
||||||
if (!spawnedFirstTime && playerActorId == actorId)
|
if (!spawnedFirstTime && playerActorId == actorId)
|
||||||
@ -91,7 +91,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return spawnPacket;
|
return spawnPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, uint spawnType)
|
public SubPacket CreateSpawnTeleportPacket(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
SubPacket spawnPacket;
|
SubPacket spawnPacket;
|
||||||
|
|
||||||
@ -223,7 +223,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return GetSpawnPackets(playerActorId, 0x1);
|
return GetSpawnPackets(playerActorId, 0x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public virtual BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||||
|
@ -116,7 +116,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId));
|
subpackets.Add(CreateAddActorPacket(playerActorId));
|
||||||
|
@ -84,6 +84,8 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
public Coroutine currentEventRunning;
|
public Coroutine currentEventRunning;
|
||||||
|
|
||||||
//Player Info
|
//Player Info
|
||||||
|
public uint destinationZone;
|
||||||
|
public ushort destinationSpawnType;
|
||||||
public uint[] timers = new uint[20];
|
public uint[] timers = new uint[20];
|
||||||
public ushort currentJob;
|
public ushort currentJob;
|
||||||
public uint currentTitle;
|
public uint currentTitle;
|
||||||
@ -259,7 +261,7 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
return ActorInstantiatePacket.BuildPacket(actorId, playerActorId, actorName, className, lParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override BasePacket GetSpawnPackets(uint playerActorId, uint spawnType)
|
public override BasePacket GetSpawnPackets(uint playerActorId, ushort spawnType)
|
||||||
{
|
{
|
||||||
List<SubPacket> subpackets = new List<SubPacket>();
|
List<SubPacket> subpackets = new List<SubPacket>();
|
||||||
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
subpackets.Add(CreateAddActorPacket(playerActorId, 8));
|
||||||
@ -647,13 +649,46 @@ namespace FFXIVClassic_Map_Server.Actors
|
|||||||
|
|
||||||
public void CleanupAndSave()
|
public void CleanupAndSave()
|
||||||
{
|
{
|
||||||
|
playerSession.LockUpdates(true);
|
||||||
|
|
||||||
//Remove actor from zone and main server list
|
//Remove actor from zone and main server list
|
||||||
zone.RemoveActorFromZone(this);
|
zone.RemoveActorFromZone(this);
|
||||||
|
|
||||||
|
//Set Destination to 0
|
||||||
|
this.destinationZone = 0;
|
||||||
|
this.destinationSpawnType = 0;
|
||||||
|
|
||||||
//Save Player
|
//Save Player
|
||||||
Database.SavePlayerPlayTime(this);
|
Database.SavePlayerPlayTime(this);
|
||||||
Database.SavePlayerPosition(this);
|
Database.SavePlayerPosition(this);
|
||||||
Program.Log.Info("{0} has been logged out and saved.", this.customDisplayName);
|
|
||||||
|
Server.GetServer().RemoveSession(playerSession.id);
|
||||||
|
|
||||||
|
Program.Log.Info("{0} has been removed from the session list.", this.customDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CleanupAndSave(uint destinationZone, ushort spawnType, float destinationX, float destinationY, float destinationZ, float destinationRot)
|
||||||
|
{
|
||||||
|
playerSession.LockUpdates(true);
|
||||||
|
|
||||||
|
//Remove actor from zone and main server list
|
||||||
|
zone.RemoveActorFromZone(this);
|
||||||
|
|
||||||
|
//Set destination
|
||||||
|
this.destinationZone = destinationZone;
|
||||||
|
this.destinationSpawnType = spawnType;
|
||||||
|
this.positionX = destinationX;
|
||||||
|
this.positionY = destinationY;
|
||||||
|
this.positionZ = destinationZ;
|
||||||
|
this.rotation = destinationRot;
|
||||||
|
|
||||||
|
//Save Player
|
||||||
|
Database.SavePlayerPlayTime(this);
|
||||||
|
Database.SavePlayerPosition(this);
|
||||||
|
|
||||||
|
Server.GetServer().RemoveSession(playerSession.id);
|
||||||
|
|
||||||
|
Program.Log.Info("{0} has been removed from the session list.", this.customDisplayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Area GetZone()
|
public Area GetZone()
|
||||||
|
@ -20,6 +20,8 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
public uint languageCode = 1;
|
public uint languageCode = 1;
|
||||||
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
private uint lastPingPacket = Utils.UnixTimeStampUTC();
|
||||||
|
|
||||||
|
public bool isUpdatesLocked = false;
|
||||||
|
|
||||||
public string errorMessage = "";
|
public string errorMessage = "";
|
||||||
|
|
||||||
public Session(uint sessionId)
|
public Session(uint sessionId)
|
||||||
@ -63,6 +65,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
public void UpdatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
public void UpdatePlayerActorPosition(float x, float y, float z, float rot, ushort moveState)
|
||||||
{
|
{
|
||||||
|
if (isUpdatesLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
playerActor.oldPositionX = playerActor.positionX;
|
playerActor.oldPositionX = playerActor.positionX;
|
||||||
playerActor.oldPositionY = playerActor.positionY;
|
playerActor.oldPositionY = playerActor.positionY;
|
||||||
playerActor.oldPositionZ = playerActor.positionZ;
|
playerActor.oldPositionZ = playerActor.positionZ;
|
||||||
@ -80,6 +85,9 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
|
|
||||||
public void UpdateInstance(List<Actor> list)
|
public void UpdateInstance(List<Actor> list)
|
||||||
{
|
{
|
||||||
|
if (isUpdatesLocked)
|
||||||
|
return;
|
||||||
|
|
||||||
List<BasePacket> basePackets = new List<BasePacket>();
|
List<BasePacket> basePackets = new List<BasePacket>();
|
||||||
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
List<SubPacket> RemoveActorSubpackets = new List<SubPacket>();
|
||||||
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
List<SubPacket> posUpdateSubpackets = new List<SubPacket>();
|
||||||
@ -132,5 +140,10 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
actorInstanceList.Clear();
|
actorInstanceList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void LockUpdates(bool f)
|
||||||
|
{
|
||||||
|
isUpdatesLocked = f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using FFXIVClassic.Common;
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using FFXIVClassic_Map_Server.packets.WorldPackets.Send;
|
||||||
|
|
||||||
namespace FFXIVClassic_Map_Server.dataobjects
|
namespace FFXIVClassic_Map_Server.dataobjects
|
||||||
{
|
{
|
||||||
@ -63,5 +64,11 @@ namespace FFXIVClassic_Map_Server.dataobjects
|
|||||||
if (socket.Connected)
|
if (socket.Connected)
|
||||||
socket.Disconnect(false);
|
socket.Disconnect(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RequestZoneChange(uint sessionId, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
WorldRequestZoneChangePacket.BuildPacket(sessionId, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation).DebugPrintSubPacket();
|
||||||
|
QueuePacket(WorldRequestZoneChangePacket.BuildPacket(sessionId, destinationZoneId, spawnType, spawnX, spawnY, spawnZ, spawnRotation), true, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionBeginPacket
|
||||||
|
{
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public SessionBeginPacket(byte[] data)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionEndPacket
|
||||||
|
{
|
||||||
|
public uint destinationZoneId;
|
||||||
|
public ushort destinationSpawnType;
|
||||||
|
public float destinationX;
|
||||||
|
public float destinationY;
|
||||||
|
public float destinationZ;
|
||||||
|
public float destinationRot;
|
||||||
|
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public SessionEndPacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
destinationZoneId = binReader.ReadUInt32();
|
||||||
|
destinationSpawnType = binReader.ReadUInt16();
|
||||||
|
destinationX = binReader.ReadSingle();
|
||||||
|
destinationY = binReader.ReadSingle();
|
||||||
|
destinationZ = binReader.ReadSingle();
|
||||||
|
destinationRot = binReader.ReadSingle();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class SessionBeginConfirmPacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1000;
|
||||||
|
public const uint PACKET_SIZE = 0x28;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(Session session, ushort errorCode = 0)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)session.id);
|
||||||
|
binWriter.Write((UInt16)errorCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SubPacket(true, OPCODE, 0, session.id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_Map_Server.dataobjects;
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class SessionEndConfirmPacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1001;
|
||||||
|
public const uint PACKET_SIZE = 0x30;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(Session session, uint destinationZone, ushort errorCode = 0)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)session.id);
|
||||||
|
binWriter.Write((UInt16)errorCode);
|
||||||
|
binWriter.Write((UInt32)destinationZone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new SubPacket(true, OPCODE, 0, session.id, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_Map_Server.packets.WorldPackets.Send
|
||||||
|
{
|
||||||
|
class WorldRequestZoneChangePacket
|
||||||
|
{
|
||||||
|
public const ushort OPCODE = 0x1002;
|
||||||
|
public const uint PACKET_SIZE = 0x048;
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(uint sessionId, uint destinationZoneId, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)sessionId);
|
||||||
|
binWriter.Write((UInt32)destinationZoneId);
|
||||||
|
binWriter.Write((UInt16)spawnType);
|
||||||
|
binWriter.Write((Single)spawnX);
|
||||||
|
binWriter.Write((Single)spawnY);
|
||||||
|
binWriter.Write((Single)spawnZ);
|
||||||
|
binWriter.Write((Single)spawnRotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SubPacket(OPCODE, sessionId, sessionId, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@ namespace FFXIVClassic_Map_Server.packets.send.actor
|
|||||||
public const float INNPOS_Z = 165.050003f;
|
public const float INNPOS_Z = 165.050003f;
|
||||||
public const float INNPOS_ROT = -1.530000f;
|
public const float INNPOS_ROT = -1.530000f;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(uint sourceActorID, uint targetActorID, uint actorId, float x, float y, float z, float rotation, uint spawnType, bool isZoningPlayer)
|
public static SubPacket BuildPacket(uint sourceActorID, uint targetActorID, uint actorId, float x, float y, float z, float rotation, ushort spawnType, bool isZoningPlayer)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE-0x20];
|
byte[] data = new byte[PACKET_SIZE-0x20];
|
||||||
|
|
||||||
|
@ -14,17 +14,25 @@ namespace FFXIVClassic_World_Server.DataObjects
|
|||||||
{
|
{
|
||||||
public readonly string zoneServerIp;
|
public readonly string zoneServerIp;
|
||||||
public readonly int zoneServerPort;
|
public readonly int zoneServerPort;
|
||||||
public readonly int[] ownedZoneIds;
|
public readonly List<uint> ownedZoneIds;
|
||||||
public bool isConnected = false;
|
public bool isConnected = false;
|
||||||
public Socket zoneServerConnection;
|
public Socket zoneServerConnection;
|
||||||
private ClientConnection conn;
|
private ClientConnection conn;
|
||||||
|
|
||||||
private byte[] buffer = new byte[0xFFFF];
|
private byte[] buffer = new byte[0xFFFF];
|
||||||
|
|
||||||
public ZoneServer(string ip, int port)
|
public ZoneServer(string ip, int port, uint firstId)
|
||||||
{
|
{
|
||||||
zoneServerIp = ip;
|
zoneServerIp = ip;
|
||||||
zoneServerPort = port;
|
zoneServerPort = port;
|
||||||
|
|
||||||
|
ownedZoneIds = new List<uint>();
|
||||||
|
ownedZoneIds.Add(firstId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddLoadedZone(uint id)
|
||||||
|
{
|
||||||
|
ownedZoneIds.Add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Connect()
|
public void Connect()
|
||||||
@ -135,14 +143,19 @@ namespace FFXIVClassic_World_Server.DataObjects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendGoodbye(Session session)
|
public void SendSessionStart(Session session)
|
||||||
|
{
|
||||||
|
SendPacket(SessionBeginPacket.BuildPacket(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendSessionEnd(Session session)
|
||||||
{
|
{
|
||||||
SendPacket(SessionEndPacket.BuildPacket(session));
|
SendPacket(SessionEndPacket.BuildPacket(session));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendSessionEnd(Session session, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
public void SendSessionEnd(Session session, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
{
|
{
|
||||||
SendPacket(SessionEndAndZonePacket.BuildPacket(session, destinationZoneId, destinationPrivateArea, spawnType, spawnX, spawnY, spawnZ, spawnRotation));
|
SendPacket(SessionEndPacket.BuildPacket(session, destinationZoneId, destinationPrivateArea, spawnType, spawnX, spawnY, spawnZ, spawnRotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
53
FFXIVClassic World Server/Database.cs
Normal file
53
FFXIVClassic World Server/Database.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using MySql.Data.MySqlClient;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_World_Server
|
||||||
|
{
|
||||||
|
class Database
|
||||||
|
{
|
||||||
|
public static uint GetCurrentZoneForSession(uint charId)
|
||||||
|
{
|
||||||
|
uint currentZone = 0;
|
||||||
|
uint destinationZone = 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();
|
||||||
|
MySqlCommand cmd = new MySqlCommand("SELECT currentZoneId, destinationZoneId FROM characters WHERE id = @charaId", conn);
|
||||||
|
cmd.Parameters.AddWithValue("@charaId", charId);
|
||||||
|
using (MySqlDataReader Reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (Reader.Read())
|
||||||
|
{
|
||||||
|
currentZone = Reader.GetUInt32("currentZoneId");
|
||||||
|
destinationZone = Reader.GetUInt32("destinationZoneId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (MySqlException e)
|
||||||
|
{
|
||||||
|
Program.Log.Error(e.ToString());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
conn.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentZone == 0 && destinationZone != 0)
|
||||||
|
return destinationZone;
|
||||||
|
if (currentZone != 0 && destinationZone == 0)
|
||||||
|
return currentZone;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,6 +65,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ConfigConstants.cs" />
|
<Compile Include="ConfigConstants.cs" />
|
||||||
|
<Compile Include="Database.cs" />
|
||||||
<Compile Include="DataObjects\ClientConnection.cs" />
|
<Compile Include="DataObjects\ClientConnection.cs" />
|
||||||
<Compile Include="DataObjects\ZoneServer.cs" />
|
<Compile Include="DataObjects\ZoneServer.cs" />
|
||||||
<Compile Include="DataObjects\Session.cs" />
|
<Compile Include="DataObjects\Session.cs" />
|
||||||
@ -73,8 +74,10 @@
|
|||||||
<Compile Include="Packets\Send\_0x2Packet.cs" />
|
<Compile Include="Packets\Send\_0x2Packet.cs" />
|
||||||
<Compile Include="Packets\Send\_0x7Packet.cs" />
|
<Compile Include="Packets\Send\_0x7Packet.cs" />
|
||||||
<Compile Include="Packets\Send\_0x8PingPacket.cs" />
|
<Compile Include="Packets\Send\_0x8PingPacket.cs" />
|
||||||
|
<Compile Include="Packets\WorldPackets\Receive\SessionBeginConfirmPacket.cs" />
|
||||||
|
<Compile Include="Packets\WorldPackets\Receive\WorldRequestZoneChangePacket.cs" />
|
||||||
|
<Compile Include="Packets\WorldPackets\Receive\SessionEndConfirmPacket.cs" />
|
||||||
<Compile Include="Packets\WorldPackets\Send\SessionBeginPacket.cs" />
|
<Compile Include="Packets\WorldPackets\Send\SessionBeginPacket.cs" />
|
||||||
<Compile Include="Packets\WorldPackets\Send\SessionEndZonePacket.cs" />
|
|
||||||
<Compile Include="Packets\WorldPackets\Send\SessionEndPacket.cs" />
|
<Compile Include="Packets\WorldPackets\Send\SessionEndPacket.cs" />
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
@ -3,6 +3,8 @@ using FFXIVClassic_World_Server.DataObjects;
|
|||||||
using FFXIVClassic_World_Server.Packets.Receive;
|
using FFXIVClassic_World_Server.Packets.Receive;
|
||||||
using FFXIVClassic_World_Server.Packets.Send;
|
using FFXIVClassic_World_Server.Packets.Send;
|
||||||
using FFXIVClassic_World_Server.Packets.Send.Login;
|
using FFXIVClassic_World_Server.Packets.Send.Login;
|
||||||
|
using FFXIVClassic_World_Server.Packets.WorldPackets.Receive;
|
||||||
|
using FFXIVClassic_World_Server.Packets.WorldPackets.Send;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -47,7 +49,10 @@ namespace FFXIVClassic_World_Server
|
|||||||
HelloPacket hello = new HelloPacket(packet.data);
|
HelloPacket hello = new HelloPacket(packet.data);
|
||||||
|
|
||||||
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
||||||
|
{
|
||||||
mServer.AddSession(client, Session.Channel.ZONE, hello.sessionId);
|
mServer.AddSession(client, Session.Channel.ZONE, hello.sessionId);
|
||||||
|
mServer.GetWorldManager().DoLogin(mServer.GetSession(hello.sessionId));
|
||||||
|
}
|
||||||
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
|
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
|
||||||
mServer.AddSession(client, Session.Channel.CHAT, hello.sessionId);
|
mServer.AddSession(client, Session.Channel.CHAT, hello.sessionId);
|
||||||
|
|
||||||
@ -73,7 +78,6 @@ namespace FFXIVClassic_World_Server
|
|||||||
{
|
{
|
||||||
//Send to the correct zone server
|
//Send to the correct zone server
|
||||||
uint targetSession = subpacket.header.targetId;
|
uint targetSession = subpacket.header.targetId;
|
||||||
mServer.GetSession(targetSession).routing1 = Server.GetServer().GetWorldManager().mZoneServerList["127.0.0.1:1989"];
|
|
||||||
|
|
||||||
if (mServer.GetSession(targetSession).routing1 != null)
|
if (mServer.GetSession(targetSession).routing1 != null)
|
||||||
mServer.GetSession(targetSession).routing1.SendPacket(subpacket);
|
mServer.GetSession(targetSession).routing1.SendPacket(subpacket);
|
||||||
@ -81,6 +85,57 @@ namespace FFXIVClassic_World_Server
|
|||||||
if (mServer.GetSession(targetSession).routing2 != null)
|
if (mServer.GetSession(targetSession).routing2 != null)
|
||||||
mServer.GetSession(targetSession).routing2.SendPacket(subpacket);
|
mServer.GetSession(targetSession).routing2.SendPacket(subpacket);
|
||||||
}
|
}
|
||||||
|
//World Server Type
|
||||||
|
else if (subpacket.header.type >= 0x1000)
|
||||||
|
{
|
||||||
|
uint targetSession = subpacket.header.targetId;
|
||||||
|
Session session = mServer.GetSession(targetSession);
|
||||||
|
|
||||||
|
switch (subpacket.header.type)
|
||||||
|
{
|
||||||
|
//Session Begin Confirm
|
||||||
|
case 0x1000:
|
||||||
|
SessionBeginConfirmPacket beginConfirmPacket = new SessionBeginConfirmPacket(packet.data);
|
||||||
|
|
||||||
|
if (beginConfirmPacket.invalidPacket || beginConfirmPacket.errorCode == 0)
|
||||||
|
Program.Log.Error("Session {0} had a error beginning session.", beginConfirmPacket.sessionId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Session End Confirm
|
||||||
|
case 0x1001:
|
||||||
|
SessionEndConfirmPacket endConfirmPacket = new SessionEndConfirmPacket(packet.data);
|
||||||
|
|
||||||
|
if (!endConfirmPacket.invalidPacket && endConfirmPacket.errorCode != 0)
|
||||||
|
{
|
||||||
|
//Check destination, if != 0, update route and start new session
|
||||||
|
if (endConfirmPacket.destinationZone != 0)
|
||||||
|
{
|
||||||
|
session.routing1 = Server.GetServer().GetWorldManager().GetZoneServer(endConfirmPacket.destinationZone);
|
||||||
|
session.routing1.SendSessionStart(session);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mServer.RemoveSession(Session.Channel.ZONE, endConfirmPacket.sessionId);
|
||||||
|
mServer.RemoveSession(Session.Channel.CHAT, endConfirmPacket.sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Program.Log.Error("Session {0} had an error ending session.", endConfirmPacket.sessionId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Zone Change Request
|
||||||
|
case 0x1002:
|
||||||
|
WorldRequestZoneChangePacket zoneChangePacket = new WorldRequestZoneChangePacket(packet.data);
|
||||||
|
|
||||||
|
if (!zoneChangePacket.invalidPacket)
|
||||||
|
{
|
||||||
|
mServer.GetWorldManager().DoZoneServerChange(session, zoneChangePacket.destinationZoneId, "", zoneChangePacket.destinationSpawnType, zoneChangePacket.destinationX, zoneChangePacket.destinationY, zoneChangePacket.destinationZ, zoneChangePacket.destinationRot);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
else
|
else
|
||||||
packet.DebugPrintPacket();
|
packet.DebugPrintPacket();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_World_Server.DataObjects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionBeginConfirmPacket
|
||||||
|
{
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
public uint sessionId;
|
||||||
|
public ushort errorCode;
|
||||||
|
|
||||||
|
public SessionBeginConfirmPacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sessionId = binReader.ReadUInt32();
|
||||||
|
errorCode = binReader.ReadUInt16();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_World_Server.DataObjects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class SessionEndConfirmPacket
|
||||||
|
{
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
public uint sessionId;
|
||||||
|
public ushort errorCode;
|
||||||
|
public uint destinationZone;
|
||||||
|
|
||||||
|
public SessionEndConfirmPacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sessionId = binReader.ReadUInt32();
|
||||||
|
errorCode = binReader.ReadUInt16();
|
||||||
|
destinationZone = binReader.ReadUInt32();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
using FFXIVClassic.Common;
|
||||||
|
using FFXIVClassic_World_Server.DataObjects;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Receive
|
||||||
|
{
|
||||||
|
class WorldRequestZoneChangePacket
|
||||||
|
{
|
||||||
|
public uint sessionId;
|
||||||
|
public uint destinationZoneId;
|
||||||
|
public byte destinationSpawnType;
|
||||||
|
public float destinationX;
|
||||||
|
public float destinationY;
|
||||||
|
public float destinationZ;
|
||||||
|
public float destinationRot;
|
||||||
|
|
||||||
|
public bool invalidPacket = false;
|
||||||
|
|
||||||
|
public WorldRequestZoneChangePacket(byte[] data)
|
||||||
|
{
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryReader binReader = new BinaryReader(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
sessionId = binReader.ReadUInt32();
|
||||||
|
destinationZoneId = binReader.ReadUInt32();
|
||||||
|
destinationSpawnType = (byte)binReader.ReadUInt16();
|
||||||
|
destinationX = binReader.ReadSingle();
|
||||||
|
destinationY = binReader.ReadSingle();
|
||||||
|
destinationZ = binReader.ReadSingle();
|
||||||
|
destinationRot = binReader.ReadSingle();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
invalidPacket = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,12 +12,51 @@ namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send
|
|||||||
class SessionEndPacket
|
class SessionEndPacket
|
||||||
{
|
{
|
||||||
public const ushort OPCODE = 0x1001;
|
public const ushort OPCODE = 0x1001;
|
||||||
public const uint PACKET_SIZE = 0x24;
|
public const uint PACKET_SIZE = 0x38;
|
||||||
|
|
||||||
public static SubPacket BuildPacket(Session session)
|
public static SubPacket BuildPacket(Session session)
|
||||||
{
|
{
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)0);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SubPacket(true, OPCODE, 0, session.sessionId, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SubPacket BuildPacket(Session session, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
||||||
|
{
|
||||||
|
byte[] data = new byte[PACKET_SIZE - 0x20];
|
||||||
|
|
||||||
|
using (MemoryStream mem = new MemoryStream(data))
|
||||||
|
{
|
||||||
|
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
binWriter.Write((UInt32)destinationZoneId);
|
||||||
|
binWriter.Write((UInt32)spawnType);
|
||||||
|
binWriter.Write((Single)spawnX);
|
||||||
|
binWriter.Write((Single)spawnY);
|
||||||
|
binWriter.Write((Single)spawnZ);
|
||||||
|
binWriter.Write((Single)spawnRotation);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new SubPacket(true, OPCODE, 0, session.sessionId, data);
|
return new SubPacket(true, OPCODE, 0, session.sessionId, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
using FFXIVClassic.Common;
|
|
||||||
using FFXIVClassic_World_Server.DataObjects;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace FFXIVClassic_World_Server.Packets.WorldPackets.Send
|
|
||||||
{
|
|
||||||
class SessionEndAndZonePacket
|
|
||||||
{
|
|
||||||
public const ushort OPCODE = 0x1002;
|
|
||||||
public const uint PACKET_SIZE = 0x48;
|
|
||||||
|
|
||||||
public static SubPacket BuildPacket(Session session, uint destinationZoneId, string destinationPrivateArea, byte spawnType, float spawnX, float spawnY, float spawnZ, float spawnRotation)
|
|
||||||
{
|
|
||||||
byte[] data = new byte[PACKET_SIZE - 0x20];
|
|
||||||
|
|
||||||
using (MemoryStream mem = new MemoryStream(data))
|
|
||||||
{
|
|
||||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
binWriter.Write((UInt32)destinationZoneId);
|
|
||||||
binWriter.Write((UInt32)destinationZoneId);
|
|
||||||
binWriter.Write((UInt32)spawnType);
|
|
||||||
binWriter.Write((Single)spawnX);
|
|
||||||
binWriter.Write((Single)spawnY);
|
|
||||||
binWriter.Write((Single)spawnZ);
|
|
||||||
binWriter.Write((Single)spawnRotation);
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new SubPacket(true, OPCODE, 0, session.sessionId, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
using FFXIVClassic.Common;
|
using FFXIVClassic.Common;
|
||||||
using FFXIVClassic_World_Server.DataObjects;
|
using FFXIVClassic_World_Server.DataObjects;
|
||||||
|
using FFXIVClassic_World_Server.Packets.WorldPackets.Receive;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@ -139,6 +140,57 @@ namespace FFXIVClassic_World_Server
|
|||||||
{
|
{
|
||||||
uint sessionId = subpacket.header.targetId;
|
uint sessionId = subpacket.header.targetId;
|
||||||
|
|
||||||
|
if (subpacket.gameMessage.opcode >= 0x1000)
|
||||||
|
{
|
||||||
|
subpacket.DebugPrintSubPacket();
|
||||||
|
uint targetSession = subpacket.header.targetId;
|
||||||
|
Session session = GetSession(targetSession);
|
||||||
|
|
||||||
|
switch (subpacket.gameMessage.opcode)
|
||||||
|
{
|
||||||
|
//Session Begin Confirm
|
||||||
|
case 0x1000:
|
||||||
|
SessionBeginConfirmPacket beginConfirmPacket = new SessionBeginConfirmPacket(subpacket.data);
|
||||||
|
|
||||||
|
if (beginConfirmPacket.invalidPacket || beginConfirmPacket.errorCode == 0)
|
||||||
|
Program.Log.Error("Session {0} had a error beginning session.", beginConfirmPacket.sessionId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Session End Confirm
|
||||||
|
case 0x1001:
|
||||||
|
SessionEndConfirmPacket endConfirmPacket = new SessionEndConfirmPacket(subpacket.data);
|
||||||
|
|
||||||
|
if (!endConfirmPacket.invalidPacket && endConfirmPacket.errorCode == 0)
|
||||||
|
{
|
||||||
|
//Check destination, if != 0, update route and start new session
|
||||||
|
if (endConfirmPacket.destinationZone != 0)
|
||||||
|
{
|
||||||
|
session.routing1 = Server.GetServer().GetWorldManager().GetZoneServer(endConfirmPacket.destinationZone);
|
||||||
|
session.routing1.SendSessionStart(session);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RemoveSession(Session.Channel.ZONE, endConfirmPacket.sessionId);
|
||||||
|
RemoveSession(Session.Channel.CHAT, endConfirmPacket.sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Program.Log.Error("Session {0} had an error ending session.", endConfirmPacket.sessionId);
|
||||||
|
|
||||||
|
break;
|
||||||
|
//Zone Change Request
|
||||||
|
case 0x1002:
|
||||||
|
WorldRequestZoneChangePacket zoneChangePacket = new WorldRequestZoneChangePacket(subpacket.data);
|
||||||
|
|
||||||
|
if (!zoneChangePacket.invalidPacket)
|
||||||
|
{
|
||||||
|
GetWorldManager().DoZoneServerChange(session, zoneChangePacket.destinationZoneId, "", zoneChangePacket.destinationSpawnType, zoneChangePacket.destinationX, zoneChangePacket.destinationY, zoneChangePacket.destinationZ, zoneChangePacket.destinationRot);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mZoneSessionList.ContainsKey(sessionId))
|
if (mZoneSessionList.ContainsKey(sessionId))
|
||||||
{
|
{
|
||||||
ClientConnection conn = mZoneSessionList[sessionId].clientConnection;
|
ClientConnection conn = mZoneSessionList[sessionId].clientConnection;
|
||||||
|
@ -34,6 +34,7 @@ namespace FFXIVClassic_World_Server
|
|||||||
|
|
||||||
string query = @"
|
string query = @"
|
||||||
SELECT
|
SELECT
|
||||||
|
id,
|
||||||
serverIp,
|
serverIp,
|
||||||
serverPort
|
serverPort
|
||||||
FROM server_zones
|
FROM server_zones
|
||||||
@ -45,15 +46,18 @@ namespace FFXIVClassic_World_Server
|
|||||||
{
|
{
|
||||||
while (reader.Read())
|
while (reader.Read())
|
||||||
{
|
{
|
||||||
string ip = reader.GetString(0);
|
uint id = reader.GetUInt32(0);
|
||||||
int port = reader.GetInt32(1);
|
string ip = reader.GetString(1);
|
||||||
|
int port = reader.GetInt32(2);
|
||||||
string address = ip + ":" + port;
|
string address = ip + ":" + port;
|
||||||
|
|
||||||
if (!mZoneServerList.ContainsKey(address))
|
if (!mZoneServerList.ContainsKey(address))
|
||||||
{
|
{
|
||||||
ZoneServer zone = new ZoneServer(ip, port);
|
ZoneServer zone = new ZoneServer(ip, port, id);
|
||||||
mZoneServerList.Add(address, zone);
|
mZoneServerList.Add(address, zone);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mZoneServerList[address].AddLoadedZone(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,6 +134,17 @@ namespace FFXIVClassic_World_Server
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ZoneServer GetZoneServer(uint zoneId)
|
||||||
|
{
|
||||||
|
foreach (ZoneServer zs in mZoneServerList.Values)
|
||||||
|
{
|
||||||
|
if (zs.ownedZoneIds.Contains(zoneId))
|
||||||
|
return zs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//Moves the actor to the new zone if exists. No packets are sent nor position changed.
|
//Moves the actor to the new zone if exists. No packets are sent nor position changed.
|
||||||
public void DoSeamlessZoneServerChange(Session session, uint destinationZoneId)
|
public void DoSeamlessZoneServerChange(Session session, uint destinationZoneId)
|
||||||
{
|
{
|
||||||
@ -158,12 +173,8 @@ namespace FFXIVClassic_World_Server
|
|||||||
//Login Zone In
|
//Login Zone In
|
||||||
public void DoLogin(Session session)
|
public void DoLogin(Session session)
|
||||||
{
|
{
|
||||||
/*
|
session.routing1 = GetZoneServer(Database.GetCurrentZoneForSession(session.sessionId));
|
||||||
->Update routing
|
session.routing1.SendSessionStart(session);
|
||||||
->Tell new server to load session info and add
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ZoneEntrance
|
public class ZoneEntrance
|
||||||
|
Loading…
Reference in New Issue
Block a user