From c767c626a37f34748fb1f5258eff3beaa06cb119 Mon Sep 17 00:00:00 2001 From: Filip Maj Date: Thu, 15 Oct 2015 16:55:01 -0400 Subject: [PATCH] Changed how packets are received. No longer have incoming stream and just parse as they come in onAccept. --- FFXIVClassic Map Server/PacketProcessor.cs | 53 +------------ FFXIVClassic Map Server/Server.cs | 88 ++++++++++++++-------- 2 files changed, 58 insertions(+), 83 deletions(-) diff --git a/FFXIVClassic Map Server/PacketProcessor.cs b/FFXIVClassic Map Server/PacketProcessor.cs index 1c71ebe9..e0cb7421 100644 --- a/FFXIVClassic Map Server/PacketProcessor.cs +++ b/FFXIVClassic Map Server/PacketProcessor.cs @@ -25,7 +25,6 @@ namespace FFXIVClassic_Lobby_Server { Dictionary mPlayers; List mConnections; - Boolean isAlive = true; Zone inn = new Zone(); @@ -33,54 +32,9 @@ namespace FFXIVClassic_Lobby_Server { mPlayers = playerList; mConnections = connectionList; - } + } - public void update() - { - Console.WriteLine("Packet processing thread has started"); - while (isAlive) - { - lock (mConnections) - { - foreach (ClientConnection conn in mConnections) - { - //Receive conn1 packets - while (true) - { - if (conn == null || conn.incomingStream.Size < BasePacket.BASEPACKET_SIZE) - break; - - try { - if (conn.incomingStream.Size < BasePacket.BASEPACKET_SIZE) - break; - BasePacketHeader header = BasePacket.getHeader(conn.incomingStream.Peek(BasePacket.BASEPACKET_SIZE)); - - if (conn.incomingStream.Size < header.packetSize) - break; - - BasePacket packet = new BasePacket(conn.incomingStream.Get(header.packetSize)); - processPacket(conn, packet); - - } - catch(OverflowException) - { break; } - } - - //Send packets - if (conn != null) - conn.flushQueuedSendPackets(); - } - } - - //Don't waste CPU if isn't needed - if (mConnections.Count == 0) - Thread.Sleep(2000); - else - Thread.Sleep(100); - } - } - - private void processPacket(ClientConnection client, BasePacket packet) + public void processPacket(ClientConnection client, BasePacket packet) { Player player = null; if (client.owner != 0 && mPlayers.ContainsKey(client.owner)) @@ -149,8 +103,6 @@ namespace FFXIVClassic_Lobby_Server } } - Log.debug(String.Format("Got actorID {0} for conn {1}.", actorID, client.getAddress())); - if (player == null) { player = new Player(actorID); @@ -158,6 +110,7 @@ namespace FFXIVClassic_Lobby_Server client.owner = actorID; client.connType = 0; player.setConnection1(client); + Log.debug(String.Format("Got actorID {0} for conn {1}.", actorID, client.getAddress())); } else { diff --git a/FFXIVClassic Map Server/Server.cs b/FFXIVClassic Map Server/Server.cs index 8c268bc6..009305d6 100644 --- a/FFXIVClassic Map Server/Server.cs +++ b/FFXIVClassic Map Server/Server.cs @@ -9,6 +9,7 @@ using System.Threading; using FFXIVClassic_Lobby_Server.common; using FFXIVClassic_Map_Server.dataobjects; using FFXIVClassic_Lobby_Server.packets; +using System.IO; namespace FFXIVClassic_Lobby_Server { @@ -61,9 +62,6 @@ namespace FFXIVClassic_Lobby_Server Console.WriteLine("{0}:{1}", (mServerSocket.LocalEndPoint as IPEndPoint).Address, (mServerSocket.LocalEndPoint as IPEndPoint).Port); Console.ForegroundColor = ConsoleColor.Gray; - mProcessor = new PacketProcessor(mConnectedPlayerList, mConnectionList); - mProcessorThread = new Thread(new ThreadStart(mProcessor.update)); - mProcessorThread.Start(); //mGameThread = new Thread(new ThreadStart(mProcessor.update)); //mGameThread.Start(); return true; @@ -117,32 +115,10 @@ namespace FFXIVClassic_Lobby_Server } } - private Player findPlayerBySocket(Socket s) - { - lock (mConnectedPlayerList) - { - foreach (KeyValuePair p in mConnectedPlayerList) - { - if ((p.Value.getConnection1().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) - { - return p.Value; - } - - if ((p.Value.getConnection2().socket.RemoteEndPoint as IPEndPoint).Address.Equals((s.RemoteEndPoint as IPEndPoint).Address)) - { - return p.Value; - } - } - } - - return null; - } - - private Player findPlayerByClientConnection(ClientConnection conn) - { - throw new NotImplementedException(); - } - + /// + /// 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. + /// + /// private void receiveCallback(IAsyncResult result) { ClientConnection conn = (ClientConnection)result.AsyncState; @@ -152,10 +128,32 @@ namespace FFXIVClassic_Lobby_Server int bytesRead = conn.socket.EndReceive(result); if (bytesRead > 0) { - conn.processIncoming(bytesRead); + int offset = 0; - //Queue the next receive - conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn); + //Build packets until can no longer or out of data + while(true) + { + BasePacket basePacket = buildPacket(ref offset, conn.buffer); + //If can't build packet, break, else process another + if (basePacket == null) + break; + else + mProcessor.processPacket(conn, basePacket); + } + + //Not all bytes consumed, transfer leftover to beginning + if (offset <= bytesRead) + Array.Copy(conn.buffer, offset, conn.buffer, 0, bytesRead - offset); + + //Build any queued subpackets into basepackets and send + conn.flushQueuedSendPackets(); + + if (offset <= bytesRead) + //Need offset since not all bytes consumed + conn.socket.BeginReceive(conn.buffer, bytesRead - offset, conn.buffer.Length - (bytesRead - offset), SocketFlags.None, new AsyncCallback(receiveCallback), conn); + else + //All bytes consumed, full buffer available + conn.socket.BeginReceive(conn.buffer, 0, conn.buffer.Length, SocketFlags.None, new AsyncCallback(receiveCallback), conn); } else { @@ -181,8 +179,32 @@ namespace FFXIVClassic_Lobby_Server } } - #endregion + /// + /// Builds a packet from the incoming buffer + offset. If a packet can be built, it is returned else null. + /// + /// Current offset in buffer. + /// Incoming buffer. + /// Returns either a BasePacket or null if not enough data. + public BasePacket buildPacket(ref int offset, byte[] buffer) + { + BasePacket newPacket = null; + //Too small to even get length + if (buffer.Length <= offset + 1) + return null; + + ushort packetSize = BitConverter.ToUInt16(buffer, offset); + + //Too small to whole packet + if (buffer.Length <= offset + packetSize) + return null; + + newPacket = new BasePacket(buffer, ref offset); + + return newPacket; + } + + #endregion public void sendPacket(string path, int conn) {