示例#1
0
        /// <summary>
        /// Establishes a connection to the given UNIX socket file
        /// </summary>
        /// <param name="initMessage">Init message to send to the server</param>
        /// <param name="socketPath">Path to the UNIX socket file</param>
        /// <param name="cancellationToken">Optional cancellation token</param>
        /// <returns>Asynchronous task</returns>
        /// <exception cref="IncompatibleVersionException">API level is incompatible</exception>
        /// <exception cref="IOException">Connection mode is unavailable</exception>
        /// <exception cref="OperationCanceledException">Operation has been cancelled</exception>
        /// <exception cref="SocketException">Connection has been closed</exception>
        protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken)
        {
            // Create a new connection
            UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath);

            _unixSocket.Connect(endPoint);

            // Verify server init message
            ServerInitMessage ownMessage    = new ServerInitMessage();
            ServerInitMessage serverMessage = await Receive <ServerInitMessage>(cancellationToken);

            if (serverMessage.Version < ownMessage.Version)
            {
                throw new IncompatibleVersionException($"Incompatible API version (need {ownMessage.Version}, got {serverMessage.Version}");
            }
            Id = serverMessage.Id;

            // Switch mode
            await Send(initMessage, cancellationToken);

            BaseResponse response = await ReceiveResponse(cancellationToken);

            if (!response.Success)
            {
                ErrorResponse errorResponse = (ErrorResponse)response;
                throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})");
            }
        }
        /// <summary>
        /// Establishes a connection to the given UNIX socket file
        /// </summary>
        /// <param name="initMessage">Init message to send to the server</param>
        /// <param name="socketPath">Path to the UNIX socket file</param>
        /// <param name="cancellationToken">Optional cancellation token</param>
        /// <returns>Asynchronous task</returns>
        /// <exception cref="IncompatibleVersionException">API level is incompatible</exception>
        /// <exception cref="IOException">Connection mode is unavailable</exception>
        /// <exception cref="OperationCanceledException">Operation has been cancelled</exception>
        /// <exception cref="SocketException">Connection has been closed</exception>
        protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken)
        {
            // Create a new connection
            UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath);

            _unixSocket.Connect(endPoint);

            // Read the server init message
            ServerInitMessage ownMessage    = new ServerInitMessage();
            ServerInitMessage serverMessage = await Receive <ServerInitMessage>(cancellationToken);

            Id = serverMessage.Id;

            // Switch mode
            initMessage.Version = Defaults.ProtocolVersion;
            await Send(initMessage, cancellationToken);

            // Check the result
            BaseResponse response = await ReceiveResponse(cancellationToken);

            if (!response.Success)
            {
                ErrorResponse errorResponse = (ErrorResponse)response;
                if (errorResponse.ErrorType == nameof(IncompatibleVersionException))
                {
                    throw new IncompatibleVersionException(errorResponse.ErrorMessage);
                }
                throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})");
            }
        }
示例#3
0
        /// <summary>
        /// Establishes a connection to the given UNIX socket file
        /// </summary>
        /// <param name="initMessage">Init message to send to the server</param>
        /// <param name="socketPath">Path to the UNIX socket file</param>
        /// <param name="cancellationToken">Optional cancellation token</param>
        /// <returns>Asynchronous task</returns>
        /// <exception cref="IncompatibleVersionException">API level is incompatible</exception>
        /// <exception cref="IOException">Connection mode is unavailable</exception>
        protected async Task Connect(ClientInitMessage initMessage, string socketPath, CancellationToken cancellationToken)
        {
            // Create a new connection
            UnixDomainSocketEndPoint endPoint = new UnixDomainSocketEndPoint(socketPath);

            _unixSocket = new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified);
            _unixSocket.Connect(endPoint);

            // Make sure we can deserialize incoming data
            _networkStream = new NetworkStream(_unixSocket);
            _streamReader  = new StreamReader(_networkStream);
            InitReader();

            // Verify server init message
            ServerInitMessage expectedMessage = new ServerInitMessage();
            ServerInitMessage serverMessage   = await Receive <ServerInitMessage>(cancellationToken);

            if (serverMessage.Version < expectedMessage.Version)
            {
                throw new IncompatibleVersionException($"Incompatible API version (expected {expectedMessage.Version}, got {serverMessage.Version}");
            }
            Id = serverMessage.Id;

            // Switch mode
            await Send(initMessage);

            BaseResponse response = await ReceiveResponse <object>(cancellationToken);

            if (!response.Success)
            {
                ErrorResponse errorResponse = (ErrorResponse)response;
                throw new IOException($"Could not set connection type {_connectionMode} ({errorResponse.ErrorType}: {errorResponse.ErrorMessage})");
            }
        }
示例#4
0
        protected override void StateUpdate()
        {
            if (m_awaitedInitMessage != null)
            {
                m_simulationBuffer = m_awaitedInitMessage.SimulationBuffer.Value;
                m_playerIDs        = new List <int>();

                foreach (int id in m_awaitedInitMessage.PlayerCharacters.Value.Keys)
                {
                    m_playerIDs.Add(id);
                }

#if DEBUG_LOG
                Debug.Log("Client received confirmation that server is about to start game with " + m_playerIDs.Count + " players and " + m_simulationBuffer + " simulation buffer ticks");
#endif // DEBUG_LOG

#if DEBUG_LOG
                Debug.Log("Starting to load world.");
#endif // DEBUG_LOG

                StartCoroutine(LoadWorldCoroutine(m_awaitedInitMessage.CellInfo2DArray.Value));
                m_awaitedInitMessage = null;
            }

            if (m_serverSentSignal)
            {
                m_TCPClient.Unsubscribe(this);
                m_serverSentSignal = false;
                OnGameStart?.Invoke();
                ClientSyncState.m_playState.Init(m_simulationBuffer.Value, m_playerIDs, new ClientGameInfo(m_clientCharacters.Values));
                m_currentState = ClientSyncState.m_playState;
            }
        }
示例#5
0
 protected override void StateAwake()
 {
     ClientListUpdate             = new ClientListUpdateEvent();
     m_awaitedInitMessage         = null;
     ClientSyncState.m_lobbyState = this;
     m_serverSentSignal           = false;
     LoadPercentage     = 0;
     m_clientCharacters = new Dictionary <int, CharacterData>();
 }
示例#6
0
 public RfbConnection(TcpClient client, Pipe pipe, ServerInitMessage serverInitMessage, MonitorSnippet?section)
 {
     Tcp = client;
     IncomingPacketsPipe = pipe;
     FramebufferWidth    = serverInitMessage.FramebufferWidth;
     FramebufferHeight   = serverInitMessage.FramebufferHeight;
     PixelFormat         = serverInitMessage.PixelFormat;
     Name    = serverInitMessage.Name;
     Section = section;
 }
示例#7
0
        public void ReceivePacket(tcp.TCPToolkit.Packet packet)
        {
            ServerStartsMessage ready = common.serialization.IConvertible.CreateFromBytes <ServerStartsMessage>(packet.Data.ArraySegment());

            if (ready != null)
            {
#if DEBUG_LOG
                Debug.Log("Received server start message.");
#endif // DEBUG_LOG
                m_serverSentSignal = true;
                return;
            }

            // loads other players in lobby, receives message from server indicating a new player joined
            CharacterListMessage clientList = common.serialization.IConvertible.CreateFromBytes <CharacterListMessage>(packet.Data.ArraySegment());
            if (clientList != null)
            {
                Debug.Log("Received " + clientList.PlayerCharacters.Value.Count + " characters from server");
                foreach (common.serialization.types.String id in clientList.PlayerCharacters.Value.Values)
                {
                    Debug.Log("Fetching character " + id.Value + " from microservice");
                    // fetch character data from microservice
                    string strID = id.Value;
                    m_characterService.GetCharacter(strID, (CharacterData character) =>
                    {
                        Debug.Log("Got character from " + character.PlayerID + " : " + character.Name);
                        m_clientCharacters[character.PlayerID.GetHashCode()] = character;
                        ClientListUpdate.Invoke(new List <CharacterData>(m_clientCharacters.Values));
                    });
                }
                return;
            }

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();
            ServerInitMessage start = common.serialization.IConvertible.CreateFromBytes <ServerInitMessage>(packet.Data.ArraySegment());
            watch.Stop();
            if (start != null)
            {
#if DEBUG_LOG
                Debug.Log("Time elapsed for world deserialization : " + watch.ElapsedMilliseconds + " ms");
#endif // DEBUG_LOG
                m_awaitedInitMessage = start;
                return;
            }
        }
示例#8
0
        protected override void StateUpdate()
        {
            lock (m_lock)
            {
                if (EveryoneIsReady() && !m_awaitingClientLoadWorld)
                {
                    m_UDPServer.Unsubscribe(this);

                    common.world.cellType.CellInfo[,] cellInfoArray = m_worldGenerator.GetCellInfoArray();

                    ServerInitMessage message = new ServerInitMessage(m_simulationBuffer, m_clientCharacters, cellInfoArray);

                    foreach (int id in m_clientCharacters.Keys)
                    {
                        m_TCPServer.Send(message.GetBytes(), id);
                    }

                    Debug.Log("Waiting for clients to load their worlds");
                    m_awaitingClientLoadWorld = true;
                }

                if (EveryoneIsWorldLoaded())
                {
                    m_readyToStartGame        = true;
                    m_awaitingClientLoadWorld = false;
                }
            }

            if (m_readyToStartGame)
            {
                m_readyToStartGame = false;
                ServerStartsMessage message = new ServerStartsMessage();

                Debug.Log("Starting game.");
                foreach (int id in m_clientCharacters.Keys)
                {
                    m_TCPServer.Send(message.GetBytes(), id);
                }

                m_TCPServer.Unsubscribe(this);

                m_gameplayState.Init(m_clientCharacters, m_simulationBuffer);
                m_currentState = m_gameplayState;
            }
        }