mirror of
https://bitbucket.org/Ioncannon/project-meteor-server.git
synced 2025-04-02 19:42:05 -04:00
More work on the world server.
This commit is contained in:
parent
e24a6f99cb
commit
a1ca960543
@ -72,26 +72,38 @@ namespace FFXIVClassic.Common
|
||||
offset += header.subpacketSize;
|
||||
}
|
||||
|
||||
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data)
|
||||
public SubPacket(ushort opcode, uint sourceId, uint targetId, byte[] data) : this(true, opcode, sourceId, targetId, data) { }
|
||||
|
||||
public SubPacket(bool isGameMessage, ushort opcode, uint sourceId, uint targetId, byte[] data)
|
||||
{
|
||||
header = new SubPacketHeader();
|
||||
|
||||
if (isGameMessage)
|
||||
{
|
||||
gameMessage = new GameMessageHeader();
|
||||
|
||||
gameMessage.opcode = opcode;
|
||||
header.sourceId = sourceId;
|
||||
header.targetId = targetId;
|
||||
|
||||
gameMessage.timestamp = Utils.UnixTimeStampUTC();
|
||||
|
||||
header.type = 0x03;
|
||||
header.unknown1 = 0x00;
|
||||
gameMessage.unknown4 = 0x14;
|
||||
gameMessage.unknown5 = 0x00;
|
||||
gameMessage.unknown6 = 0x00;
|
||||
}
|
||||
|
||||
header.sourceId = sourceId;
|
||||
header.targetId = targetId;
|
||||
|
||||
if (isGameMessage)
|
||||
header.type = 0x03;
|
||||
else
|
||||
header.type = opcode;
|
||||
|
||||
header.unknown1 = 0x00;
|
||||
|
||||
this.data = data;
|
||||
|
||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + GAMEMESSAGE_SIZE + data.Length);
|
||||
header.subpacketSize = (ushort) (SUBPACKET_SIZE + data.Length);
|
||||
|
||||
if (isGameMessage)
|
||||
header.subpacketSize += GAMEMESSAGE_SIZE;
|
||||
}
|
||||
|
||||
public SubPacket(SubPacket original, uint newTargetId)
|
||||
|
@ -5,6 +5,7 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using FFXIVClassic.Common;
|
||||
|
||||
namespace FFXIVClassic_World_Server.DataObjects
|
||||
{
|
||||
@ -12,6 +13,7 @@ namespace FFXIVClassic_World_Server.DataObjects
|
||||
{
|
||||
public readonly string zoneServerIp;
|
||||
public readonly int zoneServerPort;
|
||||
public readonly int[] ownedZoneIds;
|
||||
public bool isConnected = false;
|
||||
public Socket zoneServerConnection;
|
||||
|
||||
@ -36,5 +38,21 @@ namespace FFXIVClassic_World_Server.DataObjects
|
||||
catch (Exception e)
|
||||
{ Program.Log.Error("Failed to connect"); return; }
|
||||
}
|
||||
|
||||
public void SendPacket(SubPacket subpacket)
|
||||
{
|
||||
if (isConnected)
|
||||
{
|
||||
byte[] packetBytes = subpacket.GetBytes();
|
||||
|
||||
try
|
||||
{
|
||||
zoneServerConnection.Send(packetBytes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{ Program.Log.Error("Weird case, socket was d/ced: {0}", e); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,10 @@
|
||||
<HintPath>..\packages\NLog.4.3.5\lib\net45\NLog.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="RabbitMQ.Client, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89e7d7c5feba84ce, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\RabbitMQ.Client.4.0.0\lib\net451\RabbitMQ.Client.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
|
133
FFXIVClassic Proxy Server/PacketProcessor.cs
Normal file
133
FFXIVClassic Proxy Server/PacketProcessor.cs
Normal file
@ -0,0 +1,133 @@
|
||||
using FFXIVClassic.Common;
|
||||
using FFXIVClassic_World_Server.Packets.Send.Login;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace FFXIVClassic_World_Server
|
||||
{
|
||||
class PacketProcessor
|
||||
{
|
||||
/*
|
||||
Session Creation:
|
||||
|
||||
Get 0x1 from server
|
||||
Send 0x7
|
||||
Send 0x2
|
||||
|
||||
Zone Change:
|
||||
|
||||
Send 0x7
|
||||
Get 0x8 - Wait??
|
||||
Send 0x2
|
||||
*/
|
||||
|
||||
|
||||
Server mServer;
|
||||
List<ClientConnection> mConnections;
|
||||
|
||||
public PacketProcessor(Server server)
|
||||
{
|
||||
mServer = server;
|
||||
}
|
||||
|
||||
public void ProcessPacket(ClientConnection client, BasePacket packet)
|
||||
{
|
||||
//if (packet.header.isCompressed == 0x01)
|
||||
// BasePacket.DecryptPacket(client.blowfish, ref packet);
|
||||
|
||||
List<SubPacket> subPackets = packet.GetSubpackets();
|
||||
foreach (SubPacket subpacket in subPackets)
|
||||
{
|
||||
//Initial Connect Packet, Create session
|
||||
if (subpacket.header.type == 0x01)
|
||||
{
|
||||
packet.DebugPrintPacket();
|
||||
byte[] reply1Data = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFD, 0xFF, 0xFF,
|
||||
0xE5, 0x6E, 0x01, 0xE0, 0x00, 0x00, 0x00, 0x0
|
||||
};
|
||||
|
||||
byte[] reply2Data = {
|
||||
0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2B, 0x5F, 0x26,
|
||||
0x66, 0x00, 0x00, 0x00, 0xC8, 0xD6, 0xAF, 0x2B, 0x38, 0x2B, 0x5F, 0x26, 0xB8, 0x8D, 0xF0, 0x2B,
|
||||
0xC8, 0xFD, 0x85, 0xFE, 0xA8, 0x7C, 0x5B, 0x09, 0x38, 0x2B, 0x5F, 0x26, 0xC8, 0xD6, 0xAF, 0x2B,
|
||||
0xB8, 0x8D, 0xF0, 0x2B, 0x88, 0xAF, 0x5E, 0x26
|
||||
};
|
||||
|
||||
BasePacket reply1 = new BasePacket(reply1Data);
|
||||
BasePacket reply2 = new BasePacket(reply2Data);
|
||||
|
||||
//Write Timestamp into Reply1
|
||||
using (MemoryStream mem = new MemoryStream(reply1.data))
|
||||
{
|
||||
using (BinaryWriter binReader = new BinaryWriter(mem))
|
||||
{
|
||||
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
|
||||
binReader.Write((UInt32)Utils.UnixTimeStampUTC());
|
||||
}
|
||||
}
|
||||
|
||||
//Read in Actor Id that owns this connection
|
||||
uint actorID = 0;
|
||||
using (MemoryStream mem = new MemoryStream(packet.data))
|
||||
{
|
||||
using (BinaryReader binReader = new BinaryReader(mem))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] readIn = new byte[12];
|
||||
binReader.BaseStream.Seek(0x14, SeekOrigin.Begin);
|
||||
binReader.Read(readIn, 0, 12);
|
||||
actorID = UInt32.Parse(Encoding.ASCII.GetString(readIn));
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
mServer.AddSession(actorID);
|
||||
|
||||
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
||||
Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "zone", actorID, client.GetAddress());
|
||||
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
|
||||
Program.Log.Info("Got {0} connection for ActorID {1} @ {2}.", "chat", actorID, client.GetAddress());
|
||||
|
||||
break;
|
||||
}
|
||||
//Ping from World Server
|
||||
else if (subpacket.header.type == 0x07)
|
||||
{
|
||||
SubPacket init = Login0x7ResponsePacket.BuildPacket(0x50);
|
||||
client.QueuePacket(BasePacket.CreatePacket(init, true, false));
|
||||
}
|
||||
//Zoning Related
|
||||
else if (subpacket.header.type == 0x08)
|
||||
{
|
||||
//Response, client's current [actorID][time]
|
||||
//BasePacket init = Login0x7ResponsePacket.BuildPacket(BitConverter.ToUInt32(packet.data, 0x10), Utils.UnixTimeStampUTC(), 0x07);
|
||||
//client.QueuePacket(init);
|
||||
packet.DebugPrintPacket();
|
||||
}
|
||||
//Game Message
|
||||
else if (subpacket.header.type == 0x03)
|
||||
{
|
||||
//Send to the correct zone server
|
||||
uint targetSession = subpacket.header.targetId;
|
||||
|
||||
if (mServer.GetSession(targetSession).routing1 != null)
|
||||
mServer.GetSession(targetSession).routing1.SendPacket(subpacket);
|
||||
|
||||
if (mServer.GetSession(targetSession).routing2 != null)
|
||||
mServer.GetSession(targetSession).routing2.SendPacket(subpacket);
|
||||
}
|
||||
else
|
||||
packet.DebugPrintPacket();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
31
FFXIVClassic Proxy Server/Packets/Send/0x7ResponsePacket.cs
Normal file
31
FFXIVClassic Proxy Server/Packets/Send/0x7ResponsePacket.cs
Normal file
@ -0,0 +1,31 @@
|
||||
using FFXIVClassic.Common;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace FFXIVClassic_World_Server.Packets.Send.Login
|
||||
{
|
||||
class Login0x7ResponsePacket
|
||||
{
|
||||
public static SubPacket BuildPacket(uint actorID)
|
||||
{
|
||||
byte[] data = new byte[0x18];
|
||||
|
||||
using (MemoryStream mem = new MemoryStream(data))
|
||||
{
|
||||
using (BinaryWriter binWriter = new BinaryWriter(mem))
|
||||
{
|
||||
try
|
||||
{
|
||||
binWriter.Write((UInt32)actorID);
|
||||
binWriter.Write((UInt32)type);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BasePacket.CreatePacket(data, false, false);
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,8 @@ namespace FFXIVClassic_World_Server
|
||||
WorldManager worldManager;
|
||||
|
||||
private List<ClientConnection> mConnectionList = new List<ClientConnection>();
|
||||
private Dictionary<uint, Session> mSessionList = new Dictionary<uint, Session>();
|
||||
private Dictionary<uint, Session> mZoneSessionList = new Dictionary<uint, Session>();
|
||||
private Dictionary<uint, Session> mChatSessionList = new Dictionary<uint, Session>();
|
||||
|
||||
public Server()
|
||||
{
|
||||
@ -122,6 +123,35 @@ namespace FFXIVClassic_World_Server
|
||||
}
|
||||
}
|
||||
|
||||
public void AddSession(uint id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void RemoveSession(uint id)
|
||||
{
|
||||
if (mChatSessionList.ContainsKey(id)) {
|
||||
mChatSessionList[id].clientSocket.Disconnect();
|
||||
mConnectionList.Remove(mChatSessionList[id].clientSocket);
|
||||
mChatSessionList.Remove(id);
|
||||
}
|
||||
|
||||
if (mZoneSessionList.ContainsKey(id))
|
||||
{
|
||||
mZoneSessionList[id].clientSocket.Disconnect();
|
||||
mConnectionList.Remove(mZoneSessionList[id].clientSocket);
|
||||
mZoneSessionList.Remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
public Session GetSession(uint targetSession)
|
||||
{
|
||||
if (mZoneSessionList.ContainsKey(targetSession))
|
||||
return mZoneSessionList[targetSession];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Receive Callback. Reads in incoming data, converting them to base packets. Base packets are sent to be parsed. If not enough data at the end to build a basepacket, move to the beginning and prepend.
|
||||
/// </summary>
|
||||
@ -242,5 +272,10 @@ namespace FFXIVClassic_World_Server
|
||||
#endregion
|
||||
|
||||
|
||||
public WorldManager GetWorldManager()
|
||||
{
|
||||
return worldManager;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ namespace FFXIVClassic_World_Server
|
||||
public void DoZoneServerChange(Session session, uint zoneEntrance)
|
||||
{
|
||||
/*
|
||||
->Tell old server to save session info and remove
|
||||
->Tell old server to save session info and remove session. Start zone packets.
|
||||
->Update the position to zoneEntrance
|
||||
->Update routing
|
||||
->Tell new server to load session info and add
|
||||
->Tell new server to load session info and add session. Send end zone packets.
|
||||
*/
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user