/// <summary> /// Searches an assembly for packet handlers /// </summary> /// <param name="version">namespace of packethandlers to search eg. 'v167'</param> /// <param name="assembly">Assembly to search</param> /// <returns>The number of handlers loaded</returns> protected static int SearchPacketHandlers(string version, Assembly assembly) { int count = 0; // Walk through each type in the assembly foreach (Type type in assembly.GetTypes()) { // Pick up a class if (type.IsClass != true) { continue; } if (type.GetInterface("DOL.GS.PacketHandler.IPacketHandler") == null) { continue; } if (!type.Namespace.ToLower().EndsWith(version.ToLower())) { continue; } var packethandlerattribs = (PacketHandlerAttribute[])type.GetCustomAttributes(typeof(PacketHandlerAttribute), true); if (packethandlerattribs.Length > 0) { count++; RegisterPacketHandler(packethandlerattribs[0].Code, (IPacketHandler)Activator.CreateInstance(type)); PacketPreprocessing.RegisterPacketDefinition(packethandlerattribs[0].Code, packethandlerattribs[0].PreprocessorID); } } return(count); }
/// <summary> /// Constructs a new PacketProcessor /// </summary> /// <param name="client">The processor client</param> public PacketProcessor(GameClient client) { _client = client ?? throw new ArgumentNullException(nameof(client)); _packetPreprocessor = new PacketPreprocessing(); LoadPacketHandlers(client); _udpCounter = 0; // TODO set encoding based on client version in the future :) Encoding = new PacketEncoding168(); _asyncUdpCallback = AsyncUdpSendCallback; _tcpSendBuffer = client.Server.AcquirePacketBuffer(); _udpSendBuffer = client.Server.AcquirePacketBuffer(); }
/// <summary> /// Constructs a new PacketProcessor /// </summary> /// <param name="client">The processor client</param> public PacketProcessor(GameClient client) { if (client == null) { throw new ArgumentNullException("client"); } m_client = client; m_packetPreprocessor = new PacketPreprocessing(); LoadPacketHandlers(client); m_udpCounter = 0; //TODO set encoding based on client version in the future :) m_encoding = new PacketEncoding168(); m_asyncUdpCallback = new AsyncCallback(AsyncUdpSendCallback); m_tcpSendBuffer = client.Server.AcquirePacketBuffer(); m_udpSendBuffer = client.Server.AcquirePacketBuffer(); }
/// <summary> /// Constructs a new PacketProcessor /// </summary> /// <param name="client">The processor client</param> public PacketProcessor(GameClient client) { if (client == null) throw new ArgumentNullException("client"); m_client = client; m_packetPreprocessor = new PacketPreprocessing(); LoadPacketHandlers(client); m_udpCounter = 0; //TODO set encoding based on client version in the future :) if (client.Version < GameClient.eClientVersion.Version1110) m_encoding = new PacketEncoding168(); else m_encoding = new PacketEncoding1110(); m_asyncUdpCallback = new AsyncCallback(AsyncUdpSendCallback); m_tcpSendBuffer = client.Server.AcquirePacketBuffer(); m_udpSendBuffer = new byte[512]; // we want a smaller maximum size packet for UDP }
public void HandlePacket(GSPacketIn packet) { if (packet == null || m_client == null) { return; } int code = packet.ID; Statistics.BytesIn += packet.PacketSize; Statistics.PacketsIn++; SavePacket(packet); IPacketHandler packetHandler = null; if (code < m_packetHandlers.Length) { packetHandler = m_packetHandlers[code]; } else if (log.IsErrorEnabled) { log.ErrorFormat("Received packet code is outside of m_packetHandlers array bounds! " + m_client); log.Error(Marshal.ToHexDump( String.Format("===> <{2}> Packet 0x{0:X2} (0x{1:X2}) length: {3} (ThreadId={4})", code, code ^ 168, (m_client.Account != null) ? m_client.Account.Name : m_client.TcpEndpoint, packet.PacketSize, Thread.CurrentThread.ManagedThreadId), packet.ToArray())); } // make sure we can handle this packet at this stage var preprocess = PacketPreprocessing.CanProcessPacket(m_client, packet); if (!preprocess) { // this packet can't be processed by this client right now, for whatever reason return; } if (packetHandler != null) { Timer monitorTimer = null; if (log.IsDebugEnabled) { try { monitorTimer = new Timer(10000); m_activePacketHandler = packetHandler; m_handlerThreadID = Thread.CurrentThread.ManagedThreadId; monitorTimer.Elapsed += HandlePacketTimeout; monitorTimer.Start(); } catch (Exception e) { if (log.IsErrorEnabled) { log.Error("Starting packet monitor timer", e); } if (monitorTimer != null) { monitorTimer.Stop(); monitorTimer.Close(); monitorTimer = null; } } } #if LOGACTIVESTACKS //Put the current thread into the active thread list! //No need to lock the hashtable since we created it //synchronized! One reader, multiple writers supported! m_activePacketThreads.Add(Thread.CurrentThread, m_client); #endif long start = Environment.TickCount; try { packetHandler.HandlePacket(m_client, packet); } catch (Exception e) { if (log.IsErrorEnabled) { string client = (m_client == null ? "null" : m_client.ToString()); log.Error( "Error while processing packet (handler=" + packetHandler.GetType().FullName + " client: " + client + ")", e); } } #if LOGACTIVESTACKS finally { //Remove the thread from the active list after execution //No need to lock the hashtable since we created it //synchronized! One reader, multiple writers supported! m_activePacketThreads.Remove(Thread.CurrentThread); } #endif long timeUsed = Environment.TickCount - start; if (monitorTimer != null) { monitorTimer.Stop(); monitorTimer.Close(); } m_activePacketHandler = null; if (timeUsed > 1000) { string source = ((m_client.Account != null) ? m_client.Account.Name : m_client.TcpEndpoint); if (log.IsWarnEnabled) { log.Warn("(" + source + ") Handle packet Thread " + Thread.CurrentThread.ManagedThreadId + " " + packetHandler + " took " + timeUsed + "ms!"); } } } }
/// <summary> /// Constructs a new PacketProcessor /// </summary> /// <param name="client">The processor client</param> public PacketProcessor(GameClient client) { if (client == null) throw new ArgumentNullException("client"); m_client = client; m_packetPreprocessor = new PacketPreprocessing(); LoadPacketHandlers(client); m_udpCounter = 0; //TODO set encoding based on client version in the future :) m_encoding = new PacketEncoding168(); m_asyncUdpCallback = new AsyncCallback(AsyncUdpSendCallback); m_tcpSendBuffer = client.Server.AcquirePacketBuffer(); m_udpSendBuffer = client.Server.AcquirePacketBuffer(); }