Esempio n. 1
0
        /// <summary>
        /// Writes the messages from the specified stream to the matching storage stream in this store.
        /// </summary>
        /// <typeparam name="T">The type of messages in the stream.</typeparam>
        /// <param name="source">The source stream to write.</param>
        /// <param name="name">The name of the storage stream.</param>
        /// <param name="largeMessages">Indicates whether the stream contains large messages (typically >4k). If true, the messages will be written to the large message file.</param>
        /// <param name="deliveryPolicy">An optional delivery policy.</param>
        public void Write <T>(Emitter <T> source, string name, bool largeMessages = false, DeliveryPolicy deliveryPolicy = null)
        {
            // make sure we can serialize this type
            var handler = this.serializers.GetHandler <T>();

            // add another input to the merger to hook up the serializer to
            // and check for duplicate names in the process
            var mergeInput = this.merger.Add(name);

            // name the stream if it's not already named
            var connector = new MessageConnector <T>(source.Pipeline, this, null);

            source.PipeTo(connector);
            source.Name        = source.Name ?? name;
            connector.Out.Name = name;

            // tell the writer to write the serialized stream
            var meta = this.writer.OpenStream(source.Id, name, largeMessages, handler.Name);

            // register this stream with the store catalog
            this.pipeline.ConfigurationStore.Set(Store.StreamMetadataNamespace, name, meta);

            // hook up the serializer
            var serializer = new SerializerComponent <T>(this, this.serializers);

            serializer.PipeTo(mergeInput, true, DeliveryPolicy.Unlimited); // allows connections in running pipelines
            connector.PipeTo(serializer, true, deliveryPolicy);
        }
Esempio n. 2
0
        /// <summary>
        /// Writes the messages from the specified stream to the matching stream in this store.
        /// </summary>
        /// <typeparam name="TMessage">The type of messages in the stream.</typeparam>
        /// <param name="source">The source stream to write.</param>
        /// <param name="name">The name of the stream.</param>
        /// <param name="largeMessages">Indicates whether the stream contains large messages (typically >4k). If true, the messages will be written to the large message file.</param>
        /// <param name="deliveryPolicy">An optional delivery policy.</param>
        /// <returns>Stream metadata.</returns>
        private PsiStreamMetadata WriteToStorage <TMessage>(Emitter <TMessage> source, string name, bool largeMessages = false, DeliveryPolicy <TMessage> deliveryPolicy = null)
        {
            // make sure we can serialize this type
            var handler = this.serializers.GetHandler <TMessage>();

            // add another input to the merger to hook up the serializer to
            // and check for duplicate names in the process
            var mergeInput = this.merger.Add(name);

            // name the stream if it's not already named
            var connector = new MessageConnector <TMessage>(source.Pipeline, this, null);

            // defaults to lossless delivery policy unless otherwise specified
            source.PipeTo(connector, deliveryPolicy ?? DeliveryPolicy.Unlimited);
            source.Name    = connector.Out.Name = name;
            source.Closed += closeTime => this.writer.CloseStream(source.Id, closeTime);

            // tell the writer to write the serialized stream
            var meta = this.writer.OpenStream(source.Id, name, largeMessages, handler.Name);

            // register this stream with the store catalog
            this.pipeline.ConfigurationStore.Set(Exporter.StreamMetadataNamespace, name, meta);

            // hook up the serializer
            var serializer = new SerializerComponent <TMessage>(this, this.serializers);

            // The serializer and merger will act synchronously and throttle the connector for as long as
            // the merger is busy writing data. This will cause messages to be queued or dropped at the input
            // to the connector (per the user-supplied deliveryPolicy) until the merger is able to accept
            // the next serialized data message.
            serializer.PipeTo(mergeInput, allowWhileRunning: true, DeliveryPolicy.SynchronousOrThrottle);
            connector.PipeTo(serializer, allowWhileRunning: true, DeliveryPolicy.SynchronousOrThrottle);

            return(meta);
        }
        public void MessageConnector_SendMessageTest()
        {
            var    messageConnector        = new MessageConnector();
            string receivedFromSource      = string.Empty;
            string receivedFromDestination = string.Empty;

            messageConnector.Destination.MessageReceived += (sender, @event) => receivedFromSource = @event.Message;
            messageConnector.Source.MessageReceived      += (sender, @event) => receivedFromDestination = @event.Message;
            messageConnector.Source.Send("testMessageFromSource");
            messageConnector.Destination.Send("testMessageFromDestination");

            Assert.AreEqual("testMessageFromSource", receivedFromSource);
            Assert.AreEqual("testMessageFromDestination", receivedFromDestination);
        }
Esempio n. 4
0
        private void HandleConnection(System.Net.Sockets.Socket s)
        {
            User currentuser = null;

            try
            {
                s.ReceiveTimeout = 0;
                s.SendTimeout    = 0;
                s.NoDelay        = true;
                string ipr = s.RemoteEndPoint.ToString().Split(':')[0];

                NetworkStream stream = new NetworkStream(s);
                SslStream     ssl    = new SslStream(stream, false);

                ssl.AuthenticateAsServer(Certificate, false, SslProtocols.Tls12 | SslProtocols.Tls13, true);
                while (s.Connected)
                {
                    if (!ssl.CanRead && !stream.DataAvailable)
                    {
                        Thread.Sleep(100);
                        continue;
                    }

                    byte[] leng = new byte[4];
                    int    k2   = 0;
                    try
                    {
                        k2 = ssl.Read(leng, 0, leng.Length);
                    }
                    catch (Exception ex)
                    {
                        if (ex.ToString()
                            .Contains("An established connection was aborted by the software in your host machine"))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (ex.ToString().Contains("System.NullReferenceException"))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        Logger.Log("[Communication Error] General error. " + ipr + " " + ex);
                    }

                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(leng);
                    }

                    int upcominglength = (BitConverter.ToInt32(leng, 0));
                    if (upcominglength > 15000000 || upcominglength <= 0)
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    byte[] b = ByteReader(upcominglength, ssl, s);
                    if (b == null || k2 == 0)
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    b = LZ4Compresser.Decompress(b);

                    string message = Encoding.UTF8.GetString(b, 0, b.Length);
                    if (string.IsNullOrEmpty(message) || !message.Contains(Constants.MainSeparator))
                    {
                        ssl.Flush();
                        s.Close();
                        return;
                    }

                    string[] split = message.Split(Constants.MainSeparator);
                    if (split.Length != 2 || string.IsNullOrEmpty(split[1]) || string.IsNullOrEmpty(split[0]))
                    {
                        s.Close();
                        return;
                    }

                    Codes code = Codes.Unknown;
                    int   intp = -1;
                    bool  bbbb = int.TryParse(split[0], out intp);
                    if (!bbbb || intp == -1)
                    {
                        s.Close();
                        return;
                    }

                    if (!Enum.IsDefined(typeof(Codes), intp))
                    {
                        s.Close();
                        return;
                    }

                    code = (Codes)intp;

                    string[] otherdata = split[1].Split(Constants.AssistantSeparator);
                    string   bmsg      = "";
                    switch (code)
                    {
                    case Codes.Login:
                    {
                        try
                        {
                            if (otherdata.Length != 3)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }

                                return;
                            }

                            string name     = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));
                            string password = otherdata[1].Substring(0, Math.Min(otherdata[1].Length, 50));
                            string version  = otherdata[2].Substring(0, Math.Min(otherdata[2].Length, 10));

                            if (string.IsNullOrEmpty(name) ||
                                string.IsNullOrEmpty(password) ||
                                string.IsNullOrEmpty(version))
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }

                                return;
                            }

                            bmsg = MessageConnector.FormMessage(Codes.Login, "InvalidNameOrPassword");

                            currentuser = PermissionLoader.GetUser(name);
                            if (currentuser != null && !currentuser.IsLoggedIn &&
                                currentuser.PasswordCheck(password) && version == Program.Version)
                            {
                                currentuser.Token      = TokenHandler.AddNewToken(currentuser.UserName);
                                currentuser.IsLoggedIn = true;
                                // TODO: Only send authorized servers.
                                bmsg = (int)Codes.Login + Constants.MainSeparator + "Success" + Constants.AssistantSeparator + currentuser.Token + Constants.AssistantSeparator +
                                       string.Join(Constants.AssistantSeparator, SquadServerLoader.AllServers.Keys);
                                Logger.Log("[TCPServer] Authentication from " + ipr + " Name: " + name);
                            }
                            else
                            {
                                Logger.Log("[TCPServer] Authentication failure from " + ipr + " Name: " + name);
                            }

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                                if (bmsg.Contains("InvalidNameOrPassword"))
                                {
                                    s.Close();
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.LogError("[Authentication] Error: " + ex);
                        }

                        break;
                    }

                    case Codes.RequestPlayers:
                    {
                        if (otherdata.Length != 2)
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        string token      = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));
                        string servername = otherdata[1].Substring(0, Math.Min(otherdata[1].Length, 50));

                        if (string.IsNullOrEmpty(token) ||
                            string.IsNullOrEmpty(servername))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (currentuser != null)
                        {
                            // If token is no longer valid, or doesn't equal with the current one something is wrong.
                            if (currentuser.Token != token || !TokenHandler.HasValidToken(currentuser.UserName) || !currentuser.IsLoggedIn)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }
                                return;
                            }

                            bmsg = MessageConnector.FormMessage(Codes.RequestPlayers, "Unknown");
                            if (ValidServers.ContainsKey(servername))
                            {
                                string response = ValidServers[servername].GetPlayerList();
                                try
                                {
                                    PlayerListProcesser x      = new PlayerListProcesser(response);
                                    string players             = JsonParser.Serialize(x.Players);
                                    string disconnectedplayers = JsonParser.Serialize(x.DisconnectedPlayers);
                                    bmsg = MessageConnector.FormMessage(Codes.RequestPlayers, players,
                                                                        disconnectedplayers);
                                }
                                catch (InvalidSquadPlayerListException ex)
                                {
                                    Logger.LogError("[PlayerListRequest Error] " + ex.Message);
                                }
                            }

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                            }
                        }
                        else
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        break;
                    }

                    case Codes.Disconnect:
                    {
                        if (otherdata.Length != 1)
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        string token = otherdata[0].Substring(0, Math.Min(otherdata[0].Length, 50));

                        if (string.IsNullOrEmpty(token))
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        if (currentuser != null)
                        {
                            // If token is no longer valid, or doesn't equal with the current one something is wrong.
                            if (currentuser.Token != token || !TokenHandler.HasValidToken(currentuser.UserName) || !currentuser.IsLoggedIn)
                            {
                                if (s.Connected)
                                {
                                    s.Close();
                                }
                                return;
                            }

                            if (currentuser.Token != null)
                            {
                                TokenHandler.RemoveToken(currentuser.Token);
                            }

                            currentuser.IsLoggedIn = false;
                            currentuser.Token      = null;

                            bmsg = (int)Codes.RequestPlayers + Constants.MainSeparator + "Ok";

                            if (s.Connected)
                            {
                                byte[] messagebyte = asen.GetBytes(bmsg);
                                byte[] intBytes    = BitConverter.GetBytes(messagebyte.Length);
                                if (BitConverter.IsLittleEndian)
                                {
                                    Array.Reverse(intBytes);
                                }
                                ssl.Write(intBytes);
                                ssl.Write(messagebyte);
                                s.Close();
                            }
                        }
                        else
                        {
                            if (s.Connected)
                            {
                                s.Close();
                            }

                            return;
                        }

                        break;
                    }
                    }
                }
            }
            catch (Exception ex)
            {
                if (ex is ObjectDisposedException)
                {
                    return;
                }

                Logger.LogError("[HandleConnection] General Error: " + ex);
            }
            finally
            {
                if (currentuser != null)
                {
                    if (currentuser.Token != null)
                    {
                        TokenHandler.RemoveToken(currentuser.Token);
                    }

                    currentuser.IsLoggedIn = false;
                    currentuser.Token      = null;
                }
            }
        }