2019-06-18 22:55:32 -04:00
|
|
|
|
/*
|
|
|
|
|
===========================================================================
|
|
|
|
|
Copyright (C) 2015-2019 Project Meteor Dev Team
|
|
|
|
|
|
|
|
|
|
This file is part of Project Meteor Server.
|
|
|
|
|
|
|
|
|
|
Project Meteor Server is free software: you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
Project Meteor Server is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
along with Project Meteor Server. If not, see <https:www.gnu.org/licenses/>.
|
|
|
|
|
===========================================================================
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
using FFXIVClassic.Common;
|
2016-08-24 14:18:37 -04:00
|
|
|
|
using FFXIVClassic_World_Server.DataObjects;
|
2017-01-02 14:35:11 -05:00
|
|
|
|
using FFXIVClassic_World_Server.DataObjects.Group;
|
2016-08-24 14:18:37 -04:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.Receive;
|
2016-12-18 09:50:23 -05:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.Receive.Subpackets;
|
2016-08-24 15:41:54 -04:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.Send;
|
2016-08-23 16:57:24 -04:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.Send.Login;
|
2017-01-02 14:35:11 -05:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.Send.Subpackets;
|
2016-12-03 12:19:59 -05:00
|
|
|
|
using FFXIVClassic_World_Server.Packets.WorldPackets.Receive;
|
2016-08-23 16:57:24 -04:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
public PacketProcessor(Server server)
|
|
|
|
|
{
|
|
|
|
|
mServer = server;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ProcessPacket(ClientConnection client, BasePacket packet)
|
|
|
|
|
{
|
2016-08-24 15:41:54 -04:00
|
|
|
|
if (packet.header.isCompressed == 0x01)
|
|
|
|
|
BasePacket.DecompressPacket(ref packet);
|
2016-12-03 12:19:59 -05:00
|
|
|
|
|
2016-08-23 16:57:24 -04:00
|
|
|
|
List<SubPacket> subPackets = packet.GetSubpackets();
|
|
|
|
|
foreach (SubPacket subpacket in subPackets)
|
|
|
|
|
{
|
|
|
|
|
//Initial Connect Packet, Create session
|
|
|
|
|
if (subpacket.header.type == 0x01)
|
2016-08-24 15:41:54 -04:00
|
|
|
|
{
|
2016-08-24 14:18:37 -04:00
|
|
|
|
HelloPacket hello = new HelloPacket(packet.data);
|
2016-08-23 16:57:24 -04:00
|
|
|
|
|
|
|
|
|
if (packet.header.connectionType == BasePacket.TYPE_ZONE)
|
2016-12-03 12:19:59 -05:00
|
|
|
|
{
|
2016-08-24 14:18:37 -04:00
|
|
|
|
mServer.AddSession(client, Session.Channel.ZONE, hello.sessionId);
|
2016-12-18 09:50:23 -05:00
|
|
|
|
Session session = mServer.GetSession(hello.sessionId);
|
|
|
|
|
session.routing1 = mServer.GetWorldManager().GetZoneServer(session.currentZoneId);
|
2017-06-19 16:30:04 -04:00
|
|
|
|
session.routing1.SendSessionStart(session, true);
|
2016-12-03 12:19:59 -05:00
|
|
|
|
}
|
2016-08-23 16:57:24 -04:00
|
|
|
|
else if (packet.header.connectionType == BasePacket.TYPE_CHAT)
|
2016-08-24 15:41:54 -04:00
|
|
|
|
mServer.AddSession(client, Session.Channel.CHAT, hello.sessionId);
|
|
|
|
|
|
2017-06-27 17:31:17 -04:00
|
|
|
|
client.QueuePacket(_0x7Packet.BuildPacket(0x0E016EE5));
|
|
|
|
|
client.QueuePacket(_0x2Packet.BuildPacket(hello.sessionId));
|
2016-08-23 16:57:24 -04:00
|
|
|
|
}
|
|
|
|
|
//Ping from World Server
|
|
|
|
|
else if (subpacket.header.type == 0x07)
|
|
|
|
|
{
|
2016-08-24 15:41:54 -04:00
|
|
|
|
SubPacket init = _0x8PingPacket.BuildPacket(client.owner.sessionId);
|
2016-08-23 16:57:24 -04:00
|
|
|
|
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)
|
2016-12-18 09:50:23 -05:00
|
|
|
|
{
|
2016-08-23 16:57:24 -04:00
|
|
|
|
//Send to the correct zone server
|
|
|
|
|
uint targetSession = subpacket.header.targetId;
|
|
|
|
|
|
2016-12-18 09:50:23 -05:00
|
|
|
|
InterceptProcess(mServer.GetSession(targetSession), subpacket);
|
|
|
|
|
|
2016-08-23 16:57:24 -04:00
|
|
|
|
if (mServer.GetSession(targetSession).routing1 != null)
|
|
|
|
|
mServer.GetSession(targetSession).routing1.SendPacket(subpacket);
|
|
|
|
|
|
|
|
|
|
if (mServer.GetSession(targetSession).routing2 != null)
|
|
|
|
|
mServer.GetSession(targetSession).routing2.SendPacket(subpacket);
|
|
|
|
|
}
|
2016-12-03 12:19:59 -05:00
|
|
|
|
//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)
|
|
|
|
|
{
|
2016-12-13 15:02:28 -05:00
|
|
|
|
session.currentZoneId = endConfirmPacket.destinationZone;
|
2016-12-03 12:19:59 -05:00
|
|
|
|
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);
|
|
|
|
|
|
2016-12-13 15:02:28 -05:00
|
|
|
|
break;
|
2016-12-03 12:19:59 -05:00
|
|
|
|
//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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2016-08-23 16:57:24 -04:00
|
|
|
|
else
|
|
|
|
|
packet.DebugPrintPacket();
|
|
|
|
|
}
|
2016-08-29 08:17:14 -04:00
|
|
|
|
}
|
2016-08-23 16:57:24 -04:00
|
|
|
|
|
2016-12-18 09:50:23 -05:00
|
|
|
|
public void InterceptProcess(Session session, SubPacket subpacket)
|
|
|
|
|
{
|
|
|
|
|
switch (subpacket.gameMessage.opcode)
|
|
|
|
|
{
|
2017-01-02 14:35:11 -05:00
|
|
|
|
case 0x00C9:
|
|
|
|
|
subpacket.DebugPrintSubPacket();
|
|
|
|
|
PartyChatMessagePacket partyChatMessagePacket = new PartyChatMessagePacket(subpacket.data);
|
|
|
|
|
Party playerParty = mServer.GetWorldManager().GetPartyManager().GetParty(session.sessionId);
|
|
|
|
|
for (int i = 0; i < playerParty.members.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
Session thatSession = mServer.GetSession(playerParty.members[i]);
|
|
|
|
|
if (thatSession != null && !session.Equals(thatSession))
|
|
|
|
|
{
|
2017-06-27 17:31:17 -04:00
|
|
|
|
thatSession.clientConnection.QueuePacket(SendMessagePacket.BuildPacket(session.sessionId, thatSession.sessionId, SendMessagePacket.MESSAGE_TYPE_PARTY, mServer.GetNameForId(session.sessionId), partyChatMessagePacket.message));
|
2017-01-02 14:35:11 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2016-12-18 09:50:23 -05:00
|
|
|
|
case 0x6:
|
|
|
|
|
mServer.GetWorldManager().DoLogin(session);
|
|
|
|
|
break;
|
|
|
|
|
//Special case for groups. If it's a world group, send values, else send to zone server
|
|
|
|
|
case 0x133:
|
|
|
|
|
GroupCreatedPacket groupCreatedPacket = new GroupCreatedPacket(subpacket.data);
|
|
|
|
|
if (!mServer.GetWorldManager().SendGroupInit(session, groupCreatedPacket.groupId))
|
2017-06-27 17:31:17 -04:00
|
|
|
|
session.clientConnection.QueuePacket(subpacket);
|
2016-12-18 09:50:23 -05:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-08-23 16:57:24 -04:00
|
|
|
|
}
|
|
|
|
|
}
|