1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-20 19:57:46 +00:00

Fixed an error in the netcode that would cause the client to d/c on partial packets. Set buffer size to 0xFFFF due to disconnect on really large packets (ie gm packet). Implemented support ticket packets.

This commit is contained in:
Filip Maj 2016-02-16 22:53:53 -05:00
parent cb4171f1fd
commit c6ac8b2f14
8 changed files with 131 additions and 7 deletions

View file

@ -19,12 +19,13 @@ namespace FFXIVClassic_Lobby_Server
//Connection stuff //Connection stuff
public Blowfish blowfish; public Blowfish blowfish;
public Socket socket; public Socket socket;
public byte[] buffer = new byte[0xfffff]; public byte[] buffer;
private BlockingCollection<BasePacket> sendPacketQueue = new BlockingCollection<BasePacket>(1000); private BlockingCollection<BasePacket> sendPacketQueue = new BlockingCollection<BasePacket>(1000);
public int lastPartialSize = 0;
//Instance Stuff //Instance Stuff
public uint owner = 0; public uint owner = 0;
public uint connType = 0; public int connType = 0;
public void queuePacket(BasePacket packet) public void queuePacket(BasePacket packet)
{ {
@ -46,7 +47,7 @@ namespace FFXIVClassic_Lobby_Server
BasePacket packet = sendPacketQueue.Take(); BasePacket packet = sendPacketQueue.Take();
byte[] packetBytes = packet.getPacketBytes(); byte[] packetBytes = packet.getPacketBytes();
byte[] buffer = new byte[0xfffff]; byte[] buffer = new byte[0xFFFF];
Array.Copy(packetBytes, buffer, packetBytes.Length); Array.Copy(packetBytes, buffer, packetBytes.Length);
try try
{ {

View file

@ -455,6 +455,9 @@ namespace FFXIVClassic_Lobby_Server
player.inventories[Inventory.NORMAL].initList(getInventory(player, 0, Inventory.NORMAL)); player.inventories[Inventory.NORMAL].initList(getInventory(player, 0, Inventory.NORMAL));
player.inventories[Inventory.KEYITEMS].initList(getInventory(player, 0, Inventory.KEYITEMS)); player.inventories[Inventory.KEYITEMS].initList(getInventory(player, 0, Inventory.KEYITEMS));
player.inventories[Inventory.CURRANCY].initList(getInventory(player, 0, Inventory.CURRANCY)); player.inventories[Inventory.CURRANCY].initList(getInventory(player, 0, Inventory.CURRANCY));
player.inventories[Inventory.BAZAAR].initList(getInventory(player, 0, Inventory.BAZAAR));
player.inventories[Inventory.MELDREQUEST].initList(getInventory(player, 0, Inventory.MELDREQUEST));
player.inventories[Inventory.LOOT].initList(getInventory(player, 0, Inventory.LOOT));
} }
catch (MySqlException e) catch (MySqlException e)

View file

@ -121,6 +121,7 @@
<Compile Include="packets\receive\social\FriendlistRequestPacket.cs" /> <Compile Include="packets\receive\social\FriendlistRequestPacket.cs" />
<Compile Include="packets\receive\supportdesk\FaqBodyRequestPacket.cs" /> <Compile Include="packets\receive\supportdesk\FaqBodyRequestPacket.cs" />
<Compile Include="packets\receive\supportdesk\FaqListRequestPacket.cs" /> <Compile Include="packets\receive\supportdesk\FaqListRequestPacket.cs" />
<Compile Include="packets\receive\supportdesk\GMSupportTicketPacket.cs" />
<Compile Include="packets\receive\supportdesk\GMTicketIssuesRequestPacket.cs" /> <Compile Include="packets\receive\supportdesk\GMTicketIssuesRequestPacket.cs" />
<Compile Include="packets\send\actor\ActorDoEmotePacket.cs" /> <Compile Include="packets\send\actor\ActorDoEmotePacket.cs" />
<Compile Include="packets\send\actor\ActorInstantiatePacket.cs" /> <Compile Include="packets\send\actor\ActorInstantiatePacket.cs" />

View file

@ -353,6 +353,12 @@ namespace FFXIVClassic_Lobby_Server
case 0x01D4: case 0x01D4:
client.queuePacket(BasePacket.createPacket(GMTicketPacket.buildPacket(player.actorID, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false)); client.queuePacket(BasePacket.createPacket(GMTicketPacket.buildPacket(player.actorID, "This is a GM Ticket Title", "This is a GM Ticket Body."), true, false));
break; break;
//GM Ticket Sent
case 0x01D5:
GMSupportTicketPacket gmTicket = new GMSupportTicketPacket(subpacket.data);
Log.info("Got GM Ticket: \n" + gmTicket.ticketTitle + "\n" + gmTicket.ticketBody);
client.queuePacket(BasePacket.createPacket(GMTicketSentResponsePacket.buildPacket(player.actorID, true), true, false));
break;
//Request to end ticket //Request to end ticket
case 0x01D6: case 0x01D6:
client.queuePacket(BasePacket.createPacket(EndGMTicketPacket.buildPacket(player.actorID), true, false)); client.queuePacket(BasePacket.createPacket(EndGMTicketPacket.buildPacket(player.actorID), true, false));

View file

@ -23,7 +23,7 @@ namespace FFXIVClassic_Lobby_Server
class Server class Server
{ {
public const int FFXIV_MAP_PORT = 54992; public const int FFXIV_MAP_PORT = 54992;
public const int BUFFER_SIZE = 0x400; public const int BUFFER_SIZE = 0xFFFF; //Max basepacket size is 0xFFFF
public const int BACKLOG = 100; public const int BACKLOG = 100;
public const string STATIC_ACTORS_PATH = "./staticactors.bin"; public const string STATIC_ACTORS_PATH = "./staticactors.bin";
@ -165,10 +165,27 @@ namespace FFXIVClassic_Lobby_Server
{ {
ClientConnection conn = (ClientConnection)result.AsyncState; ClientConnection conn = (ClientConnection)result.AsyncState;
//Check if disconnected
if ((conn.socket.Poll(1, SelectMode.SelectRead) && conn.socket.Available == 0))
{
if (mConnectedPlayerList.ContainsKey(conn.owner))
mConnectedPlayerList.Remove(conn.owner);
lock (mConnectionList)
{
mConnectionList.Remove(conn);
}
if (conn.connType == BasePacket.TYPE_ZONE)
Log.conn(String.Format("{0} has disconnected.", conn.owner == 0 ? conn.getAddress() : "User " + conn.owner));
return;
}
try try
{ {
int bytesRead = conn.socket.EndReceive(result); int bytesRead = conn.socket.EndReceive(result);
if (bytesRead > 0)
bytesRead += conn.lastPartialSize;
if (bytesRead >= 0)
{ {
int offset = 0; int offset = 0;
@ -176,6 +193,7 @@ namespace FFXIVClassic_Lobby_Server
while(true) while(true)
{ {
BasePacket basePacket = buildPacket(ref offset, conn.buffer, bytesRead); BasePacket basePacket = buildPacket(ref offset, conn.buffer, bytesRead);
//If can't build packet, break, else process another //If can't build packet, break, else process another
if (basePacket == null) if (basePacket == null)
break; break;
@ -187,6 +205,10 @@ namespace FFXIVClassic_Lobby_Server
if (offset < bytesRead) if (offset < bytesRead)
Array.Copy(conn.buffer, offset, conn.buffer, 0, bytesRead - offset); Array.Copy(conn.buffer, offset, conn.buffer, 0, bytesRead - offset);
Array.Clear(conn.buffer, bytesRead - offset, conn.buffer.Length - (bytesRead - offset));
conn.lastPartialSize = bytesRead - offset;
//Build any queued subpackets into basepackets and send //Build any queued subpackets into basepackets and send
conn.flushQueuedSendPackets(); conn.flushQueuedSendPackets();
@ -424,6 +446,27 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
private void giveItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.inventories.ContainsKey(type))
p.inventories[type].addItem(itemId, quantity, 1);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.inventories.ContainsKey(type))
p.inventories[type].addItem(itemId, quantity, 1);
}
}
}
private void removeItem(ConnectedPlayer client, uint itemId, int quantity) private void removeItem(ConnectedPlayer client, uint itemId, int quantity)
{ {
if (client != null) if (client != null)
@ -441,6 +484,27 @@ namespace FFXIVClassic_Lobby_Server
} }
} }
private void removeItem(ConnectedPlayer client, uint itemId, int quantity, ushort type)
{
if (client != null)
{
Player p = client.getActor();
if (p.inventories.ContainsKey(type))
p.inventories[type].removeItem(itemId, quantity);
}
else
{
foreach (KeyValuePair<uint, ConnectedPlayer> entry in mConnectedPlayerList)
{
Player p = entry.Value.getActor();
if (p.inventories.ContainsKey(type))
p.inventories[type].removeItem(itemId, quantity);
}
}
}
private void giveCurrancy(ConnectedPlayer client, uint itemId, int quantity) private void giveCurrancy(ConnectedPlayer client, uint itemId, int quantity)
{ {
if (client != null) if (client != null)
@ -562,6 +626,8 @@ namespace FFXIVClassic_Lobby_Server
giveItem(client, UInt32.Parse(split[1]), 1); giveItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3) else if (split.Length == 3)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
giveItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
} }
catch (Exception e) catch (Exception e)
{ {
@ -579,6 +645,8 @@ namespace FFXIVClassic_Lobby_Server
removeItem(client, UInt32.Parse(split[1]), 1); removeItem(client, UInt32.Parse(split[1]), 1);
else if (split.Length == 3) else if (split.Length == 3)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2])); removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]));
else if (split.Length == 4)
removeItem(client, UInt32.Parse(split[1]), Int32.Parse(split[2]), UInt16.Parse(split[3]));
} }
catch (Exception e) catch (Exception e)
{ {

View file

@ -98,6 +98,9 @@ namespace FFXIVClassic_Map_Server.Actors
inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL); inventories[Inventory.NORMAL] = new Inventory(this, MAXSIZE_INVENTORY_NORMAL, Inventory.NORMAL);
inventories[Inventory.KEYITEMS] = new Inventory(this, MAXSIZE_INVENTORY_KEYITEMS, Inventory.KEYITEMS); inventories[Inventory.KEYITEMS] = new Inventory(this, MAXSIZE_INVENTORY_KEYITEMS, Inventory.KEYITEMS);
inventories[Inventory.CURRANCY] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRANCY); inventories[Inventory.CURRANCY] = new Inventory(this, MAXSIZE_INVENTORY_CURRANCY, Inventory.CURRANCY);
inventories[Inventory.MELDREQUEST] = new Inventory(this, MAXSIZE_INVENTORY_MELDREQUEST, Inventory.MELDREQUEST);
inventories[Inventory.BAZAAR] = new Inventory(this, MAXSIZE_INVENTORY_BAZAAR, Inventory.BAZAAR);
inventories[Inventory.LOOT] = new Inventory(this, MAXSIZE_INVENTORY_LOOT, Inventory.LOOT);
charaWork.property[0] = 1; charaWork.property[0] = 1;
charaWork.property[1] = 1; charaWork.property[1] = 1;
@ -433,6 +436,9 @@ namespace FFXIVClassic_Map_Server.Actors
inventories[Inventory.NORMAL].sendFullInventory(); inventories[Inventory.NORMAL].sendFullInventory();
inventories[Inventory.CURRANCY].sendFullInventory(); inventories[Inventory.CURRANCY].sendFullInventory();
inventories[Inventory.KEYITEMS].sendFullInventory(); inventories[Inventory.KEYITEMS].sendFullInventory();
inventories[Inventory.BAZAAR].sendFullInventory();
inventories[Inventory.MELDREQUEST].sendFullInventory();
inventories[Inventory.LOOT].sendFullInventory();
#region equipsetup #region equipsetup
// EquipmentListX08Packet initialEqupmentPacket = new EquipmentListX08Packet(); // EquipmentListX08Packet initialEqupmentPacket = new EquipmentListX08Packet();
// initialEqupmentPacket.setItem(EquipmentListX08Packet.SLOT_BODY, 5); // initialEqupmentPacket.setItem(EquipmentListX08Packet.SLOT_BODY, 5);

View file

@ -32,6 +32,7 @@ namespace FFXIVClassic_Map_Server.dataobjects
public void setConnection(int type, ClientConnection conn) public void setConnection(int type, ClientConnection conn)
{ {
conn.connType = type;
switch (type) switch (type)
{ {
case BasePacket.TYPE_ZONE: case BasePacket.TYPE_ZONE:

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Map_Server.packets.receive.supportdesk
{
class GMSupportTicketPacket
{
public bool invalidPacket = false;
public string ticketTitle, ticketBody;
public uint ticketIssueIndex;
public uint langCode;
public GMSupportTicketPacket(byte[] data)
{
using (MemoryStream mem = new MemoryStream(data))
{
using (BinaryReader binReader = new BinaryReader(mem))
{
try
{
langCode = binReader.ReadUInt32();
ticketIssueIndex = binReader.ReadUInt32();
ticketTitle = Encoding.ASCII.GetString(binReader.ReadBytes(0x80)).Trim(new[] { '\0' });
ticketBody = Encoding.ASCII.GetString(binReader.ReadBytes(0x800)).Trim(new[] { '\0' });
}
catch (Exception){
invalidPacket = true;
}
}
}
}
}
}