1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-24 13:47:46 +00:00

Redid the initial handshake code to handle the found connection type field. Server should no longer create two player objects and code has been reduced. Removed instances of connection1/2 getters... server simply sends packets down zone connection. Fixed issue with world manager not zoning in player due to missing 0x2 packet.

This commit is contained in:
Filip Maj 2016-01-19 21:47:59 -05:00
parent 093d3b7c15
commit d90dc0cb80
7 changed files with 102 additions and 127 deletions

View file

@ -55,11 +55,7 @@ namespace FFXIVClassic_Lobby_Server
} }
public void processPacket(ClientConnection client, BasePacket packet) public void processPacket(ClientConnection client, BasePacket packet)
{ {
ConnectedPlayer player = null;
if (client.owner != 0 && mPlayers.ContainsKey(client.owner))
player = mPlayers[client.owner];
if (packet.header.isCompressed == 0x01) if (packet.header.isCompressed == 0x01)
BasePacket.decryptPacket(client.blowfish, ref packet); BasePacket.decryptPacket(client.blowfish, ref packet);
@ -80,6 +76,7 @@ namespace FFXIVClassic_Lobby_Server
BasePacket reply1 = new BasePacket(reply1Data); BasePacket reply1 = new BasePacket(reply1Data);
BasePacket reply2 = new BasePacket("./packets/login/login2.bin"); BasePacket reply2 = new BasePacket("./packets/login/login2.bin");
//Write Timestamp into Reply1
using (MemoryStream mem = new MemoryStream(reply1.data)) using (MemoryStream mem = new MemoryStream(reply1.data))
{ {
using (BinaryWriter binReader = new BinaryWriter(mem)) using (BinaryWriter binReader = new BinaryWriter(mem))
@ -87,25 +84,9 @@ namespace FFXIVClassic_Lobby_Server
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin); binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
binReader.Write((UInt32)Utils.UnixTimeStampUTC()); binReader.Write((UInt32)Utils.UnixTimeStampUTC());
} }
} }
//Already Handshaked
if (client.owner != 0)
{
using (MemoryStream mem = new MemoryStream(reply2.data))
{
using (BinaryWriter binReader = new BinaryWriter(mem))
{
binReader.BaseStream.Seek(0x10, SeekOrigin.Begin);
binReader.Write(player.actorID);
}
}
client.queuePacket(reply1);
client.queuePacket(reply2);
break;
}
//Read in Actor Id that owns this connection
uint actorID = 0; uint actorID = 0;
using (MemoryStream mem = new MemoryStream(packet.data)) using (MemoryStream mem = new MemoryStream(packet.data))
{ {
@ -123,9 +104,13 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
//Should never happen.... unless actor id IS 0!
if (actorID == 0) if (actorID == 0)
break; break;
client.owner = actorID;
//Write Actor ID into reply2
using (MemoryStream mem = new MemoryStream(reply2.data)) using (MemoryStream mem = new MemoryStream(reply2.data))
{ {
using (BinaryWriter binReader = new BinaryWriter(mem)) using (BinaryWriter binReader = new BinaryWriter(mem))
@ -135,23 +120,29 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
if (((IPEndPoint)client.socket.LocalEndPoint).Port == 54992) ConnectedPlayer player = null;
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
{ {
player = new ConnectedPlayer(actorID); while (!mPlayers.ContainsKey(client.owner))
mPlayers[actorID] = player; { }
client.owner = actorID; player = mPlayers[client.owner];
client.connType = 0;
player.setConnection1(client);
Log.debug(String.Format("Got actorID {0} for conn {1}.", actorID, client.getAddress()));
}
else
{
client.owner = actorID;
client.connType = 1;
player.setConnection2(client);
} }
//Get Character info //Create connected player if not created
if (player == null)
{
player = new ConnectedPlayer(actorID);
mPlayers[actorID] = player;
}
player.setConnection(packet.header.connectionType, client);
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
Log.debug(String.Format("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.getAddress()));
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
Log.debug(String.Format("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.getAddress()));
//Create player actor //Create player actor
reply1.debugPrintPacket(); reply1.debugPrintPacket();
client.queuePacket(reply1); client.queuePacket(reply1);
@ -172,6 +163,8 @@ namespace FFXIVClassic_Lobby_Server
} }
else if (subpacket.header.type == 0x03) else if (subpacket.header.type == 0x03)
{ {
ConnectedPlayer player = mPlayers[client.owner];
//Normal Game Opcode //Normal Game Opcode
switch (subpacket.gameMessage.opcode) switch (subpacket.gameMessage.opcode)
{ {
@ -357,17 +350,14 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
public void sendPacket(string path, int conn) public void sendPacket(string path)
{ {
BasePacket packet = new BasePacket(path); BasePacket packet = new BasePacket(path);
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mPlayers) foreach (KeyValuePair<uint, ConnectedPlayer> entry in mPlayers)
{ {
packet.replaceActorID(entry.Value.actorID); packet.replaceActorID(entry.Value.actorID);
if (conn == 1 || conn == 3) entry.Value.queuePacket(packet);
entry.Value.getConnection1().queuePacket(packet);
if (conn == 2 || conn == 3)
entry.Value.getConnection2().queuePacket(packet);
} }
} }
@ -438,10 +428,8 @@ namespace FFXIVClassic_Lobby_Server
packet.replaceActorID(entry.Value.actorID); packet.replaceActorID(entry.Value.actorID);
actorPacket.replaceActorID(entry.Value.actorID); actorPacket.replaceActorID(entry.Value.actorID);
entry.Value.getConnection1().queuePacket(packet); entry.Value.queuePacket(packet);
entry.Value.getConnection1().queuePacket(actorPacket); entry.Value.queuePacket(actorPacket);
} }
} }

View file

@ -74,19 +74,23 @@ namespace FFXIVClassic_Lobby_Server
String input = Console.ReadLine(); String input = Console.ReadLine();
String[] split = input.Split(' '); String[] split = input.Split(' ');
if (split.Length >= 3) if (split.Length >= 2)
{ {
if (split[0].Equals("sendpacket")) if (split[0].Equals("sendpacket"))
{ {
try{ try
server.sendPacket("./packets/" + split[1], Int32.Parse(split[2])); {
server.sendPacket("./packets/" + split[1]);
} }
catch (Exception e) catch (Exception e)
{ {
Log.error("Could not load packet: " + e); Log.error("Could not load packet: " + e);
} }
} }
else if (split[0].Equals("warp")) }
else if (split.Length >= 3)
{
if (split[0].Equals("warp"))
{ {
server.doWarp(split[1], split[2], split[3], split[4]); server.doWarp(split[1], split[2], split[3], split[4]);
} }

View file

@ -35,7 +35,7 @@ namespace FFXIVClassic_Lobby_Server
#region Socket Handling #region Socket Handling
public bool startServer() public bool startServer()
{ {
mWorldManager = new WorldManager(); mWorldManager = new WorldManager(this);
mWorldManager.LoadZoneList(); 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);
@ -226,9 +226,9 @@ namespace FFXIVClassic_Lobby_Server
#endregion #endregion
public void sendPacket(string path, int conn) public void sendPacket(string path)
{ {
mProcessor.sendPacket(path, conn); mProcessor.sendPacket(path);
} }
public void testCodePacket(uint id, uint value, string target) public void testCodePacket(uint id, uint value, string target)
@ -245,14 +245,8 @@ namespace FFXIVClassic_Lobby_Server
BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false); BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false);
packet.debugPrintPacket(); packet.debugPrintPacket();
if (entry.Value.getConnection1() != null)
entry.Value.getConnection1().queuePacket(packet); entry.Value.queuePacket(packet);
else
Log.error("Connection was null");
if (entry.Value.getConnection2() != null)
entry.Value.getConnection2().queuePacket(packet);
else
Log.error("Connection was null");
} }
} }
@ -268,8 +262,7 @@ namespace FFXIVClassic_Lobby_Server
SubPacket changePropertyPacket = changeProperty.buildPacket((entry.Value.actorID), (entry.Value.actorID)); SubPacket changePropertyPacket = changeProperty.buildPacket((entry.Value.actorID), (entry.Value.actorID));
BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false); BasePacket packet = BasePacket.createPacket(changePropertyPacket, true, false);
packet.debugPrintPacket(); packet.debugPrintPacket();
entry.Value.getConnection1().queuePacket(packet); entry.Value.queuePacket(packet);
entry.Value.getConnection2().queuePacket(packet);
} }
} }

View file

@ -6,6 +6,7 @@ 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.Actor.inventory; using FFXIVClassic_Map_Server.packets.send.Actor.inventory;
using FFXIVClassic_Map_Server.packets.send.list; using FFXIVClassic_Map_Server.packets.send.list;
using FFXIVClassic_Map_Server.packets.send.login;
using FFXIVClassic_Map_Server.packets.send.player; using FFXIVClassic_Map_Server.packets.send.player;
using FFXIVClassic_Map_Server.utils; using FFXIVClassic_Map_Server.utils;
using MySql.Data.MySqlClient; using MySql.Data.MySqlClient;
@ -61,8 +62,11 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
public PlayerWork playerWork = new PlayerWork(); public PlayerWork playerWork = new PlayerWork();
public Player(uint actorID) : base(actorID) public ConnectedPlayer playerSession;
public Player(ConnectedPlayer cp, uint actorID) : base(actorID)
{ {
playerSession = cp;
actorName = String.Format("_pc{0:00000000}", actorID); actorName = String.Format("_pc{0:00000000}", actorID);
className = "Player"; className = "Player";
currentSubState = SetActorStatePacket.SUB_STATE_PLAYER; currentSubState = SetActorStatePacket.SUB_STATE_PLAYER;
@ -360,14 +364,13 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
} }
public void sendZoneInPackets(WorldManager world) public void sendZoneInPackets(WorldManager world)
{ {
ClientConnection client; playerSession.queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId), true, false);
client.queuePacket(SetMapPacket.buildPacket(actorId, zone.regionId, zone.actorId), true, false); playerSession.queuePacket(_0x2Packet.buildPacket(actorId), true, false);
//client.queuePacket(_0x2Packet.buildPacket(player.actorID), true, false); playerSession.queuePacket(SetMusicPacket.buildPacket(actorId, 0x3D, 0x01), true, false);
client.queuePacket(SetMusicPacket.buildPacket(actorId, 0x3D, 0x01), true, false); playerSession.queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR), true, false);
client.queuePacket(SetWeatherPacket.buildPacket(actorId, SetWeatherPacket.WEATHER_CLEAR), true, false);
client.queuePacket(getSpawnPackets(actorId)); playerSession.queuePacket(getSpawnPackets(actorId));
#region grouptest #region grouptest
//Retainers //Retainers
@ -377,19 +380,19 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
retainerListEntries.Add(new ListEntry(0x24, 0x0, 0xFFFFFFFF, false, false, "TEST2")); retainerListEntries.Add(new ListEntry(0x24, 0x0, 0xFFFFFFFF, false, false, "TEST2"));
retainerListEntries.Add(new ListEntry(0x25, 0x0, 0xFFFFFFFF, false, false, "TEST3")); retainerListEntries.Add(new ListEntry(0x25, 0x0, 0xFFFFFFFF, false, false, "TEST3"));
BasePacket retainerListPacket = BasePacket.createPacket(ListUtils.createRetainerList(actorId, 0xF4, 1, 0x800000000004e639, retainerListEntries), true, false); BasePacket retainerListPacket = BasePacket.createPacket(ListUtils.createRetainerList(actorId, 0xF4, 1, 0x800000000004e639, retainerListEntries), true, false);
client.queuePacket(retainerListPacket); playerSession.queuePacket(retainerListPacket);
//Party //Party
List<ListEntry> partyListEntries = new List<ListEntry>(); List<ListEntry> partyListEntries = new List<ListEntry>();
partyListEntries.Add(new ListEntry(actorId, 0xFFFFFFFF, 0xFFFFFFFF, false, true, customDisplayName)); partyListEntries.Add(new ListEntry(actorId, 0xFFFFFFFF, 0xFFFFFFFF, false, true, customDisplayName));
partyListEntries.Add(new ListEntry(0x029B27D3, 0xFFFFFFFF, 0x195, false, true, "Valentine Bluefeather")); partyListEntries.Add(new ListEntry(0x029B27D3, 0xFFFFFFFF, 0x195, false, true, "Valentine Bluefeather"));
BasePacket partyListPacket = BasePacket.createPacket(ListUtils.createPartyList(actorId, 0xF4, 1, 0x8000000000696df2, partyListEntries), true, false); BasePacket partyListPacket = BasePacket.createPacket(ListUtils.createPartyList(actorId, 0xF4, 1, 0x8000000000696df2, partyListEntries), true, false);
client.queuePacket(partyListPacket); playerSession.queuePacket(partyListPacket);
#endregion #endregion
#region itemsetup #region itemsetup
////////ITEMS//////// ////////ITEMS////////
client.queuePacket(InventoryBeginChangePacket.buildPacket(actorId), true, false); playerSession.queuePacket(InventoryBeginChangePacket.buildPacket(actorId), true, false);
//TEST //TEST
@ -433,7 +436,7 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
#endregion #endregion
#region equipsetup #region equipsetup
client.queuePacket(BasePacket.createPacket(setinvPackets, true, false)); playerSession.queuePacket(BasePacket.createPacket(setinvPackets, true, false));
EquipmentSetupPacket initialEqupmentPacket = new EquipmentSetupPacket(); EquipmentSetupPacket initialEqupmentPacket = new EquipmentSetupPacket();
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_BODY, 5); initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_BODY, 5);
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_HEAD, 3); initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_HEAD, 3);
@ -443,23 +446,23 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_LEGS, 8); initialEqupmentPacket.setItem(EquipmentSetupPacket.SLOT_LEGS, 8);
//Equip Init //Equip Init
client.queuePacket(InventorySetBeginPacket.buildPacket(actorId, 0x23, InventorySetBeginPacket.CODE_EQUIPMENT), true, false); playerSession.queuePacket(InventorySetBeginPacket.buildPacket(actorId, 0x23, InventorySetBeginPacket.CODE_EQUIPMENT), true, false);
client.queuePacket(BasePacket.createPacket(initialEqupmentPacket.buildPackets(actorId), true, false)); playerSession.queuePacket(BasePacket.createPacket(initialEqupmentPacket.buildPackets(actorId), true, false));
client.queuePacket(InventorySetEndPacket.buildPacket(actorId), true, false); playerSession.queuePacket(InventorySetEndPacket.buildPacket(actorId), true, false);
client.queuePacket(InventoryEndChangePacket.buildPacket(actorId), true, false); playerSession.queuePacket(InventoryEndChangePacket.buildPacket(actorId), true, false);
////////ITEMS//////// ////////ITEMS////////
#endregion #endregion
client.queuePacket(getInitPackets(actorId)); playerSession.queuePacket(getInitPackets(actorId));
BasePacket innSpawn = zone.getSpawnPackets(actorId); BasePacket innSpawn = zone.getSpawnPackets(actorId);
BasePacket debugSpawn = world.GetDebugActor().getSpawnPackets(actorId); BasePacket debugSpawn = world.GetDebugActor().getSpawnPackets(actorId);
BasePacket worldMasterSpawn = world.GetActor().getSpawnPackets(actorId); BasePacket worldMasterSpawn = world.GetActor().getSpawnPackets(actorId);
client.queuePacket(innSpawn); playerSession.queuePacket(innSpawn);
client.queuePacket(debugSpawn); playerSession.queuePacket(debugSpawn);
client.queuePacket(worldMasterSpawn); playerSession.queuePacket(worldMasterSpawn);
#region hardcode #region hardcode
BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); //Bed, Book created BasePacket reply9 = new BasePacket("./packets/login/login9_zonesetup.bin"); //Bed, Book created
@ -468,9 +471,9 @@ namespace FFXIVClassic_Map_Server.dataobjects.chara
reply9.replaceActorID(actorId); reply9.replaceActorID(actorId);
reply10.replaceActorID(actorId); reply10.replaceActorID(actorId);
reply11.replaceActorID(actorId); reply11.replaceActorID(actorId);
client.queuePacket(reply9); playerSession.queuePacket(reply9);
client.queuePacket(reply10); playerSession.queuePacket(reply10);
client.queuePacket(reply11); playerSession.queuePacket(reply11);
#endregion #endregion
} }

View file

@ -19,68 +19,51 @@ namespace FFXIVClassic_Map_Server.dataobjects
public uint eventCurrentOwner = 0; public uint eventCurrentOwner = 0;
public string eventCurrentStarter = ""; public string eventCurrentStarter = "";
ClientConnection conn1; private ClientConnection zoneConnection;
ClientConnection conn2; private ClientConnection chatConnection;
bool isDisconnected; bool isDisconnected;
public ConnectedPlayer(uint actorId) public ConnectedPlayer(uint actorId)
{ {
this.actorID = actorId; this.actorID = actorId;
playerActor = new Player(actorId); playerActor = new Player(this, actorId);
actorInstanceList.Add(playerActor); actorInstanceList.Add(playerActor);
} }
public void addConnection(ClientConnection conn) public void setConnection(int type, ClientConnection conn)
{ {
if (conn1 == null && conn2 != null) switch (type)
conn1 = conn; {
else if (conn2 == null && conn1 != null) case BasePacket.TYPE_ZONE:
conn2 = conn; zoneConnection = conn;
else break;
conn1 = conn; case BasePacket.TYPE_CHAT:
chatConnection = conn;
break;
}
} }
public bool isClientConnectionsReady() public bool isClientConnectionsReady()
{ {
return (conn1 != null && conn2 != null); return (zoneConnection != null && chatConnection != null);
} }
public void disconnect() public void disconnect()
{ {
isDisconnected = true; isDisconnected = true;
conn1.disconnect(); zoneConnection.disconnect();
conn2.disconnect(); chatConnection.disconnect();
} }
public void setConnection1(ClientConnection conn)
{
conn1 = conn;
}
public void setConnection2(ClientConnection conn)
{
conn2 = conn;
}
public ClientConnection getConnection1()
{
return conn1;
}
public ClientConnection getConnection2()
{
return conn2;
}
public void queuePacket(BasePacket basePacket) public void queuePacket(BasePacket basePacket)
{ {
conn1.queuePacket(basePacket); zoneConnection.queuePacket(basePacket);
} }
public void queuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted) public void queuePacket(SubPacket subPacket, bool isAuthed, bool isEncrypted)
{ {
conn1.queuePacket(subPacket, isAuthed, isEncrypted); zoneConnection.queuePacket(subPacket, isAuthed, isEncrypted);
} }
public Player getActor() public Player getActor()

View file

@ -62,12 +62,12 @@ namespace FFXIVClassic_Map_Server.lua
public void runEvent(string functionName, params object[] parameters) public void runEvent(string functionName, params object[] parameters)
{ {
List<LuaParam> lParams = LuaUtils.createLuaParamList(parameters); List<LuaParam> lParams = LuaUtils.createLuaParamList(parameters);
player.getConnection1().queuePacket(RunEventFunctionPacket.buildPacket(player.actorID, player.eventCurrentOwner, player.eventCurrentStarter, functionName, lParams), true, false); player.queuePacket(RunEventFunctionPacket.buildPacket(player.actorID, player.eventCurrentOwner, player.eventCurrentStarter, functionName, lParams), true, false);
} }
public void endEvent() public void endEvent()
{ {
player.getConnection1().queuePacket(EndEventPacket.buildPacket(player.actorID, player.eventCurrentOwner, player.eventCurrentStarter), true, false); player.queuePacket(EndEventPacket.buildPacket(player.actorID, player.eventCurrentOwner, player.eventCurrentStarter), true, false);
} }
} }

View file

@ -10,18 +10,22 @@ using System.IO;
namespace FFXIVClassic_Lobby_Server.packets namespace FFXIVClassic_Lobby_Server.packets
{ {
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct BasePacketHeader public struct BasePacketHeader
{ {
public byte isAuthenticated; public byte isAuthenticated;
public byte isCompressed; public byte isCompressed;
public ushort reserved; public ushort connectionType;
public ushort packetSize; public ushort packetSize;
public ushort numSubpackets; public ushort numSubpackets;
public ulong timestamp; //Miliseconds public ulong timestamp; //Miliseconds
} }
public class BasePacket{ public class BasePacket{
public const int TYPE_ZONE = 1;
public const int TYPE_CHAT = 2;
public const int BASEPACKET_SIZE = 0x10; public const int BASEPACKET_SIZE = 0x10;
public BasePacketHeader header; public BasePacketHeader header;