/// <summary> /// Raises the <see cref="PacketProcessing"/> event for the specified packet data, if possible asynchronously. /// </summary> /// <param name="packet">The packet data to include for the raised event.</param> /// <returns> /// <see langword="false"/> if the data was handled synchronously and another call can be made; if there was a fatal error or the asynchronous call was successfully made, <see langword="false"/>.</returns> private bool TryPushAsync(byte[] packet) { var reader = new PacketReader(packet); ushort packetCode; if (!reader.TryReadUInt16(out packetCode)) { Close(@"Could not read packet code."); // Bad packet. We kill the session and stop pushing. return(true); } // If this returns null, it's an unknown code and has no label. string label; _packetCodeTable.TryGetIncomingLabel(packetCode, out label); // Invoke event asynchronously. var args = new PacketProcessingEventArgs(packetCode, label, reader); var handler = PacketProcessing; AsyncCallback callback = ContinuePushAsynchronous; var asyncResult = handler.BeginInvoke(this, args, callback, null); // If we completed synchronously, we'll take another one right away. // Otherwise, leave it to the asynchronous continuation. return(asyncResult.CompletedSynchronously); }
private void HandlePacket(PacketProcessingEventArgs e) { try { ProcessPacket(e); } catch (IllegalPacketException) { // TODO: Use IllegalPacketException for penalizing naughty clients. Logger.Info("Received illegal packet. Client disconnected."); Disconnect("Illegal packet."); } catch (PacketReadingException) { Logger.Info("Received incomplete packet. Client disconnected."); Disconnect("Incomplete packet."); } }
private void OnPacketProcessing(object sender, PacketProcessingEventArgs e) { if (e.Label == "Pong") { HandlePong(); } else if (e.Label != null) { Logger.Debug("Received packet '{0}'", e.Label); HandlePacket(e); } else { var packetCode = e.PacketCode; var packetData = e.Reader.ReadFully().ToHex(true); Logger.Debug(@"Unrecognized packet code: 0x{0:X4}. Packet buffer: {1}", packetCode, packetData); } }
/// <inheritdoc/> protected override void ProcessPacket(PacketProcessingEventArgs args) { var reader = args.Reader; switch (args.Label) { case "Authenticate": HandleAuthentication(reader); break; case "ValidatePin": HandlePinValidation(reader); break; case "AssignPin": HandlePinAssignment(reader); break; case "WorldListRequest": case "WorldListRefresh": HandleWorldListRequest(reader); break; case "ChannelSelect": HandleChannelSelect(reader); break; case "CharacterListRequest": HandleCharacterListRequest(reader); break; case "CharacterSelect": HandleCharacterSelect(reader); break; } }
/// <summary> /// When implemented in a derived class, processes the provided packet data. /// </summary> /// <param name="args">The packet to be processed.</param> protected abstract void ProcessPacket(PacketProcessingEventArgs args);
/// <inheritdoc/> protected override void ProcessPacket(PacketProcessingEventArgs args) { // TODO: Channel packet handling, hello? }