static PacketFactory() { PACKETS[0x01] = new OkPacket(); PACKETS[0x02] = new MatchInfoPacket(); PACKETS[0x04] = new BulkEntityStatePacket(); PACKETS[0x06] = new MatchStatusPacket(); PACKETS[0x07] = new MatchEndPacket(); PACKETS[0x09] = new PingPongPacket(); PACKETS[0x10] = new SpawnEntityPacket(); PACKETS[0x11] = new DespawnEntityPacket(); PACKETS[0x12] = new PlayerStatePacket(); //DEPRECATED 0X19 PING PACKETS[0x26] = new MatchRedirectPacket(); PACKETS[0x29] = new UpdateSessionPacket(); //DEPRECATED 0X30 OVER EVENT API //PACKETS[0x30] = new SpawnEffectPacket(); PACKETS[0x31] = new StatsUpdatePacket(); PACKETS[0x32] = new ItemActivatedEffect(); PACKETS[0x33] = new ItemDeactivatedPackets(); PACKETS[0x35] = new MapSettingsPacket(); PACKETS[0x37] = new SpawnLightPacket(); PACKETS[0x38] = new UpdateInventoryPacket(); PACKETS[0x40] = new EventPacket(); PACKETS[0x42] = new DisconnectReasonPacket(); PACKETS[0x43] = new DisplayTextPacket(); PACKETS[0x44] = new RemoveTextPacket(); }
public override void OnUpdate() { base.OnUpdate(); if (Time.time - lastPingTime > 5) { var ping = new PingPongPacket(); ping.WritePacket(Client); lastPingTime = Time.time; } }
protected virtual void HandlePayload(IOTaskCompleteEventArgs <SocketReceiveTask> e) { int mask_length = 0; if (IsWebSocket) { var state = (WebSocketReceiveState)e.Task.UserToken; if (state.IsMasking) { mask_length = 4; //+1 for not copying the buffer to do the unmasking! for (int i = 4; i < e.Task.Transferred; i++) { e.Buffer.Buffer[e.Buffer.Offset + i] ^= e.Buffer.Buffer[e.Buffer.Offset + (i % 4)]; } } switch (state.OpCode) { case WebSocketOpCode.Text: { using var s = new MemoryStream(e.Buffer.Buffer, e.Buffer.Offset + mask_length, e.Task.Transferred - mask_length); using var reader = new PacketReader(s); string tmp = reader.ReadString(); Match match = Regex.Match(tmp, "[a-z]+?:", RegexOptions.Singleline | RegexOptions.IgnoreCase); if (match.Success) { //is ib0t message Isib0tSocket = true; MessageType = WebSocketMessageType.Text; Handleib0tMessage(tmp, e.Task.Transferred); ReceiveAsyncInternal(e.Task); return; } else { int id = tmp.ExtractId(); if (id > -1) { MessageType = WebSocketMessageType.Text; OnTextPacketReceived((byte)id, tmp, e.Task.Transferred); ReceiveAsyncInternal(e.Task); return; } } //this is a message type we don't recongnize. Disconnect(WebSocketCloseStatus.InvalidPayloadData); return; } case WebSocketOpCode.Ping: //PingPongPacket was initially a private item and handled internally //however I decided that it can eventually get checked by AresServer for IO monitoring and flood inspecting byte[] buffer = new byte[e.Task.Transferred - mask_length]; Array.Copy(e.Buffer.Buffer, e.Buffer.Offset, buffer, 0, buffer.Length); var ping = new PingPongPacket(buffer); OnBinaryPacketReceived(ping, e.Task.Transferred); SendAsync(ping); ReceiveAsyncInternal(e.Task); return; case WebSocketOpCode.Pong: ReceiveAsyncInternal(e.Task); return; case WebSocketOpCode.Binary: MessageType = WebSocketMessageType.Binary; break; //let binary fall through below default: //don't handle any of the other opcodes right now Disconnect(WebSocketCloseStatus.InvalidMessageType); return; } } OnBinaryPacketReceived( e.Buffer.Buffer[e.Buffer.Offset + mask_length], e.Buffer.Buffer, e.Buffer.Offset + mask_length + 1, e.Task.Transferred - mask_length - 1 ); ReceiveAsyncInternal(e.Task); }
protected virtual bool ReadWebSocket(PacketReader reader) { byte first = reader.ReadByte(); var opcode = (WebSocketOpCode)(first & ((1 << 4) - 1)); if (opcode == WebSocketOpCode.Close) { Disconnect(); return(false); } byte second = reader.ReadByte(); int length = second & 127; bool masked = (second & (1 << 7)) != 0; if (!masked && should_mask) { //MASKED BIT NOT SET Disconnect(WebSocketCloseStatus.ProtocolError); return(false); } int count; if (length == 126) { if (reader.Remaining < 2) { return(false); } count = BitConverter.ToUInt16(reader.ReadBytes(2).EnsureEndian()); } else if (length == 127) { if (reader.Remaining < 8) { return(false); } count = (int)BitConverter.ToUInt64(reader.ReadBytes(8).EnsureEndian()); } else { count = length; } count = masked ? count + 4 : count; if (reader.Remaining < count) { return(false); } byte[] payload; if (masked) { byte[] mask = reader.ReadBytes(4); payload = reader.ReadBytes(count - 4); for (int i = 0; i < payload.Length; i++) { payload[i] ^= mask[i % 4]; } } else { payload = reader.ReadBytes(count); } switch (opcode) { case WebSocketOpCode.Text: { string tmp = Encoding.UTF8.GetString(payload); Match match = Regex.Match(tmp, "[a-z]+?:", RegexOptions.Singleline | RegexOptions.IgnoreCase); if (match.Success) { //is ib0t message Isib0tSocket = true; MessageType = WebSocketMessageType.Text; Handleib0tMessage(tmp, payload.Length); return(true); } else { int id = tmp.ExtractId(); if (id > -1) { MessageType = WebSocketMessageType.Text; OnTextPacketReceived((byte)id, tmp, payload.Length); return(true); } } //this is a message type we don't recongnize. Disconnect(WebSocketCloseStatus.InvalidPayloadData); return(false); } case WebSocketOpCode.Ping: var ping = new PingPongPacket(payload) { IsPing = true }; OnBinaryPacketReceived(ping, payload.Length); SendAsync(ping); return(true); case WebSocketOpCode.Pong: return(true); case WebSocketOpCode.Binary: MessageType = WebSocketMessageType.Binary; OnBinaryPacketReceived(payload[0], payload, 1, payload.Length - 1); return(true); default: //don't handle any of the other opcodes right now Disconnect(WebSocketCloseStatus.InvalidMessageType); return(false); } }