void OnClientSessionCallback(CClientSocket ClientSocket, int ConnectionIndex, byte[] arguments)
        {
            SSessionPacket SessionPacket = CSerialization.Deserialize <SSessionPacket>(arguments);

            //Relay the session to the appropriate controller
            foreach (SConnection Connection in Connections)
            {
                if (Connection.ConnectionType != EConnectionType.Controller)
                {
                    continue;
                }

                if (Connection.Information == null)
                {
                    continue;
                }

                SControllerInformation ControllerInformation = (SControllerInformation)Connection.Information;

                if (ControllerInformation.IsAuthorized && ControllerInformation.Key == SessionPacket.ControllerKey)
                {
                    ClientSocket.SendPacket <SSessionPacket>((byte)EControllerPackets.Session, SessionPacket);
                    break;
                }
            }
        }
        private void ServerSocket_OnClientReceivedBuffer(CClientSocket ClientSocket, byte[] buffer)
        {
            lock (Connections)
            {
                for (int i = 0; i < Connections.Count; i++)
                {
                    if (Connections[i].ClientSocket == ClientSocket)
                    {
                        if (Connections[i].ConnectionType == EConnectionType.Unknown)
                        {
                            bool IsConnectionTypeParsed = false;

                            if (buffer.Length >= 4)
                            {
                                int ConnectionType = BitConverter.ToInt32(buffer, 0);

                                if (ConnectionType == (int)EConnectionType.Client || ConnectionType == (int)EConnectionType.Controller)
                                {
                                    SConnection Connection = Connections[i];
                                    Connection.ConnectionType = (EConnectionType)ConnectionType;

                                    if (Connection.ConnectionType == EConnectionType.Controller)
                                    {
                                        SControllerInformation ControllerInformation = new SControllerInformation
                                        {
                                            Clients = new List <SClient>()
                                        };

                                        Connection.Information = ControllerInformation;
                                    }

                                    Connections[i]         = Connection;
                                    IsConnectionTypeParsed = true;
                                }
                            }

                            if (!IsConnectionTypeParsed)
                            {
                                //At this point we have received an invalid buffer
                                ClientSocket.Disconnect();
                            }
                            else if (IsConnectionTypeParsed && buffer.Length > 4)
                            {
                                //Initial parsing for understanding what kind of connection it is is complete but there is more data available
                                byte[] NextBuffer = new byte[buffer.Length - 4];
                                Buffer.BlockCopy(buffer, 4, NextBuffer, 0, NextBuffer.Length);
                                HandleReceivedBuffer(ClientSocket, i, Connections[i].ConnectionType, NextBuffer);
                            }
                        }
                        else
                        {
                            HandleReceivedBuffer(ClientSocket, i, Connections[i].ConnectionType, buffer);
                        }

                        break;
                    }
                }
            }
        }
        static public void Execute(List <SConnection> Connections)
        {
            List <SClient> clients = new List <SClient>();

            for (int ClientIndex = 0; ClientIndex < Connections.Count; ClientIndex++)
            {
                if (Connections[ClientIndex].ConnectionType != EConnectionType.Client)
                {
                    continue;
                }

                if (Connections[ClientIndex].Information == null)
                {
                    continue;
                }

                SClient ClientInfo = GetClientStructFromConnection(Connections[ClientIndex]);

                clients.Add(ClientInfo);
            }

            for (int ConnectionIndex = 0; ConnectionIndex < Connections.Count; ConnectionIndex++)
            {
                if (Connections[ConnectionIndex].ConnectionType != EConnectionType.Controller)
                {
                    continue;
                }

                SConnection            ControllerConnection  = Connections[ConnectionIndex];
                SControllerInformation ControllerInformation = (SControllerInformation)ControllerConnection.Information;

                if (!ControllerInformation.IsAuthorized)
                {
                    continue;
                }

                SynchronizeStructArray <SClient>(ESyncList.Clients, clients, ref ControllerInformation.Clients, ControllerConnection.ClientSocket);

                ControllerConnection.Information = ControllerInformation;
                Connections[ConnectionIndex]     = ControllerConnection;
            }
        }
        void OnControllerIntroductionCallback(CClientSocket ClientSocket, int ConnectionIndex, byte[] arguments)
        {
            SControllerIntroduction ControllerIntroduction = (SControllerIntroduction)CSerialization.Deserialize <SControllerIntroduction>(arguments);

            SControllerAnswer ControllerAnswer = new SControllerAnswer
            {
                IsAuthorized = false,
                key          = -1
            };

            SConnection Connection = Connections[ConnectionIndex];

            if (ControllerIntroduction.Password != Program.ControllerPassword)
            {
                //Tell the controller that password was not accepted
                Connection.ClientSocket.SendPacket <SControllerAnswer>((byte)EControllerPackets.Introduction, ControllerAnswer);

                //At this stage the password is not valid, so we disconnect the invalid controller
                ClientSocket.Disconnect();
                return;
            }

            int key = GenerateKeyForController();

            //Authorize connection
            SControllerInformation ControllerInformation = (SControllerInformation)Connection.Information;

            ControllerInformation.IsAuthorized = true;
            ControllerInformation.Key          = key;
            Connection.Information             = (object)ControllerInformation;
            Connections[ConnectionIndex]       = Connection;

            //Key for controlling clients
            ControllerAnswer.key          = key;
            ControllerAnswer.IsAuthorized = true;

            //Tell the controller that he is authorized
            Connection.ClientSocket.SendPacket <SControllerAnswer>((byte)EControllerPackets.Introduction, ControllerAnswer);
        }
        int GenerateKeyForController()
        {
            bool generated = false;

            int key = -1;

            while (!generated)
            {
                key = RandomInstance.Next();

                bool exists = false;

                foreach (SConnection c in Connections)
                {
                    if (c.ConnectionType != EConnectionType.Controller)
                    {
                        continue;
                    }

                    SControllerInformation information = (SControllerInformation)c.Information;

                    if (information.Key == key)
                    {
                        exists = true;
                        break;
                    }
                }

                if (!exists)
                {
                    generated = true;
                }
            }

            return(key);
        }