Пример #1
0
        public static void WriteMessage(WebClient client, IMessage data, [Optional] Int32 tracker, [Optional] TrackerOrigin origin, bool useTracker = false)
        {
            var type = data.GetType();

            if (!ProtocolMap.ProtocolCache.Reverse.HasEntry(type))
            {
                TcpServer.WriteLogSafe($"{client.Session.Id} | WARNING: attempted to send invalid command. ignoring.");
                return;
            }

            var streamRaw = new MemoryStream();

            streamRaw.Write(BitConverter.GetBytes(ProtocolMap.ProtocolCache.Reverse[type]), 0, 4);
            streamRaw.Write(BitConverter.GetBytes(useTracker), 0, 1);

            if (useTracker)
            {
                streamRaw.Write(BitConverter.GetBytes(Convert.ToBoolean(origin)), 0, 1);
                streamRaw.Write(BitConverter.GetBytes(tracker), 0, 4);
            }

            streamRaw.Write(BitConverter.GetBytes(ProtocolMap.ProtocolAttributes[type].HasData), 0, 1);

            data.WriteTo(streamRaw);

            var res = streamRaw.ToArray();

            TcpServer.WriteLogSafe($"{client.Session.Id} | Sending: {BitConverter.ToString(res)}");
            client.Session.QueueMessage(res, true);
            streamRaw.Dispose();
        }
Пример #2
0
        private static SceneResponse GetScene()
        {
            TcpServer.WriteLogSafe("Get Scene");
            sceneResponse.Gameobjects.Clear();
            sceneResponse.Gameobjects.AddRange(SceneHandler.CurrentRootObjects.Select(item => new WebGameObject
            {
                Reference = 0,
                Enabled   = item.active,
                Name      = item.name
            }));

            return(sceneResponse);
        }
Пример #3
0
        private static void DecodeMessage(WebClient client, byte[] message)
        {
            int           commandId  = BitConverter.ToInt32(message, 0);
            bool          useTracker = BitConverter.ToBoolean(message, 4);
            TrackerOrigin origin     = useTracker && BitConverter.ToBoolean(message, 5) ? TrackerOrigin.Client : TrackerOrigin.Server;
            int           tracker    = useTracker ? BitConverter.ToInt32(message, 6) : 0;

            bool hasData    = BitConverter.ToBoolean(message, useTracker ? 10 : 5);
            int  headersLen = useTracker ? 11 : 6;

            if (!ProtocolMap.ProtocolCache.Forward.HasEntry(commandId))
            {
                TcpServer.WriteLogSafe($"{client.Session.Id} | WARNING: client sent invalid command. ignoring.");
                return;
            }

            TcpServer.WriteLogSafe($"{client.Session.Id} | Recieved [{BitConverter.ToString(message)}]");

            var command = hasData ? SignalReceived.BuildSignal(commandId, ref message, headersLen) : null;

            SignalReceived.OnSignalReceived(client, command, useTracker, tracker, origin);

            // if (origin != TrackerOrigin.Client)
            //     return;
            //
            // if (command == typeof(PingRequest))
            // {
            //     WriteMessage(session, new PingResponse
            //     {
            //         Message = session.Id
            //     }, tracker, origin);
            //
            //     WriteMessage(session, new PingRequest
            //     {
            //         Message = session.Id
            //     }, 0, TrackerOrigin.Server);
            // } else if (command == typeof(PingResponse))
            // {
            //     TcpServer.WriteLogSafe(headersLen);
            //     TcpServer.WriteLogSafe($"{session.Id} | PONG [{PingResponse.Parser.ParseFrom(message, headersLen, message.Length - headersLen)}]");
            // }
        }
Пример #4
0
        static void SendMessage(TcpClient client, byte[] payload, int opcode, bool masking, byte[] mask)
        {
            if (masking && mask == null)
            {
                throw new ArgumentException(nameof(mask));
            }

            using (var packet = new MemoryStream())
            {
                byte firstbyte = 0b0_0_0_0_0000; // fin | rsv1 | rsv2 | rsv3 | [ OPCODE | OPCODE | OPCODE | OPCODE ]

                firstbyte |= 0b1_0_0_0_0000;     // fin
                //firstbyte |= 0b0_1_0_0_0000; // rsv1
                //firstbyte |= 0b0_0_1_0_0000; // rsv2
                //firstbyte |= 0b0_0_0_1_0000; // rsv3

                firstbyte += (byte)opcode; // Text
                packet.WriteByte(firstbyte);

                // Set bit: bytes[byteIndex] |= mask;

                byte secondbyte = 0b0_0000000; // mask | [SIZE | SIZE  | SIZE  | SIZE  | SIZE  | SIZE | SIZE]

                if (masking)
                {
                    secondbyte |= 0b1_0000000;         // mask
                }
                if (payload.LongLength <= 0b0_1111101) // 125
                {
                    secondbyte |= (byte)payload.Length;
                    packet.WriteByte(secondbyte);
                }
                else if (payload.LongLength <= UInt16.MaxValue) // If length takes 2 bytes
                {
                    secondbyte |= 0b0_1111110;                  // 126
                    packet.WriteByte(secondbyte);

                    var len = BitConverter.GetBytes(payload.LongLength);
                    Array.Reverse(len, 0, 2);
                    packet.Write(len, 0, 2);
                }
                else // if (payload.LongLength <= Int64.MaxValue) // If length takes 8 bytes
                {
                    secondbyte |= 0b0_1111111; // 127
                    packet.WriteByte(secondbyte);

                    var len = BitConverter.GetBytes(payload.LongLength);
                    Array.Reverse(len, 0, 8);
                    packet.Write(len, 0, 8);
                }

                if (masking)
                {
                    packet.Write(mask, 0, 4);
                    payload = ApplyMask(payload, mask);
                }

                // Write all data to the packet
                packet.Write(payload, 0, payload.Length);

                // Get client's stream
                var stream = client.GetStream();

                var finalPacket = packet.ToArray();
                TcpServer.WriteLogSafe($@"SENT: {BitConverter.ToString(finalPacket)}");

                // Send the packet
                foreach (var b in finalPacket)
                {
                    stream.WriteByte(b);
                }
            }
        }
Пример #5
0
        private void MessageLoop()
        {
            var session = this;
            var client  = session.Client;
            var stream  = session.ClientStream;

            var packet = new List <byte>();

            var messageOpcode = 0x0;

            using (var messageBuffer = new MemoryStream())
                while (client.Connected)
                {
                    packet.Clear();

                    var ab = client.Available;
                    if (ab == 0)
                    {
                        MessageProcessQueue();
                        continue;
                    }

                    packet.Add((byte)stream.ReadByte());
                    var fin  = (packet[0] & (1 << 7)) != 0;
                    var rsv1 = (packet[0] & (1 << 6)) != 0;
                    var rsv2 = (packet[0] & (1 << 5)) != 0;
                    var rsv3 = (packet[0] & (1 << 4)) != 0;

                    // Must error if is set.
                    //if (rsv1 || rsv2 || rsv3)
                    //    return;

                    var opcode = packet[0] & ((1 << 4) - 1);

                    switch (opcode)
                    {
                    case 0x0:     // Continuation Frame
                        break;

                    case 0x1:     // Text
                    case 0x2:     // Binary
                    case 0x8:     // Connection Close
                        messageOpcode = opcode;
                        break;

                    case 0x9:
                        continue;     // Ping

                    case 0xA:
                        continue;     // Pong

                    default:
                        continue;     // Reserved
                    }

                    packet.Add((byte)stream.ReadByte());
                    var masked       = IsMasking = (packet[1] & (1 << 7)) != 0;
                    var pseudoLength = packet[1] - (masked ? 128 : 0);

                    ulong actualLength = 0;
                    if (pseudoLength > 0 && pseudoLength < 125)
                    {
                        actualLength = (ulong)pseudoLength;
                    }
                    else if (pseudoLength == 126)
                    {
                        var length = new byte[2];
                        stream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt16(length, 0);
                    }
                    else if (pseudoLength == 127)
                    {
                        var length = new byte[8];
                        stream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt64(length, 0);
                    }

                    var mask = new byte[4];
                    if (masked)
                    {
                        stream.Read(mask, 0, mask.Length);
                        packet.AddRange(mask);
                    }

                    if (actualLength > 0)
                    {
                        var data = new byte[actualLength];
                        stream.Read(data, 0, data.Length);
                        packet.AddRange(data);

                        if (masked)
                        {
                            data = ApplyMask(data, mask);
                        }

                        messageBuffer.Write(data, 0, data.Length);
                    }

                    TcpServer.WriteLogSafe($@"RECV: {BitConverter.ToString(packet.ToArray())}");

                    if (!fin)
                    {
                        continue;
                    }
                    var message = messageBuffer.ToArray();

                    switch (messageOpcode)
                    {
                    case 0x1:
                        AnyMessageReceived?.Invoke(session, message);
                        TextMessageReceived?.Invoke(session, Encoding.UTF8.GetString(message));
                        break;

                    case 0x2:
                        AnyMessageReceived?.Invoke(session, message);
                        BinaryMessageReceived?.Invoke(session, message);
                        break;

                    case 0x8:
                        Close();
                        break;

                    default:
                        throw new Exception("Invalid opcode: " + messageOpcode);
                    }

                    messageBuffer.SetLength(0);
                }
        }