public int Bind(NetworkEndPoint endpoint)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.IPC || endpoint.nbo_port == 0)
            {
                throw new InvalidOperationException();
            }
#endif
            IPCManager.Instance.ReleaseEndPoint(m_LocalEndPoint[0]);
            m_LocalEndPoint[0] = endpoint;
            return(0);
        }
예제 #2
0
        Connection GetNewConnection(NetworkEndPoint address, ushort sessionId)
        {
            for (int i = 0; i < m_ConnectionList.Length; i++)
            {
                if (address == m_ConnectionList[i].Address && m_ConnectionList[i].SendToken == sessionId)
                {
                    return(m_ConnectionList[i]);
                }
            }

            return(Connection.Null);
        }
예제 #3
0
        public unsafe bool TryGetEndPointByHandle(int handle, out NetworkEndPoint endpoint)
        {
            var temp = new NetworkEndPoint();

            temp.Family     = NetworkFamily.IPC;
            temp.ipc_handle = handle;

            temp.Port       = m_IPCEndPoints[handle];
            endpoint        = temp;
            endpoint.length = 6;
            return(true);
        }
예제 #4
0
        private void Close()
        {
            if (m_SocketHandle < 0)
            {
                return;
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AllSockets.OpenSockets.Remove(m_SocketHandle);
#endif
            NativeBindings.network_close(ref m_SocketHandle);
            m_RemoteEndPoint = default(NetworkEndPoint);
            m_SocketHandle   = -1;
        }
예제 #5
0
        public int CreateInterfaceEndPoint(NetworkEndPoint address, out NetworkInterfaceEndPoint endpoint)
        {
            if (!address.IsLoopback && !address.IsAny)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                throw new ArgumentException("IPC network driver can only handle loopback addresses");
#else
                endpoint = default(NetworkInterfaceEndPoint);
                return((int)Error.StatusCode.NetworkArgumentMismatch);
#endif
            }

            endpoint = IPCManager.Instance.CreateEndPoint(address.Port);
            return((int)Error.StatusCode.Success);
        }
예제 #6
0
        public unsafe int ReceiveMessageEx(NetworkEndPoint local, network_iovec *iov, int iov_len, ref NetworkEndPoint remote)
        {
            IPCData data;

            if (!m_IPCQueue.Peek(local.ipc_handle, out data))
            {
                return(0);
            }
            NetworkEndPoint endpoint;

            if (!TryGetEndPointByHandle(data.from, out endpoint))
            {
                return(-1);
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.IPC)
            {
                throw new InvalidDataException("An incorrect message was pushed to the IPC message queue");
            }
#endif

#if (UNITY_EDITOR_OSX || ((UNITY_STANDALONE_OSX || UNITY_IOS) && !UNITY_EDITOR))
            remote.family.sa_family = (byte)NetworkFamily.IPC;
#else
            remote.family.sa_family = (ushort)NetworkFamily.IPC;
#endif
            remote.ipc_handle = endpoint.ipc_handle;
            remote.nbo_port   = endpoint.nbo_port;
            remote.length     = 6;

            int totalLength = 0;
            for (int i = 0; i < iov_len; i++)
            {
                var curLength = Math.Min(iov[i].len, data.length - totalLength);
                UnsafeUtility.MemCpy(iov[i].buf, data.data + totalLength, curLength);
                totalLength += curLength;
                iov[i].len   = curLength;
            }

            if (totalLength < data.length)
            {
                return(-1);
            }
            m_IPCQueue.Dequeue(local.ipc_handle, out data);

            return(totalLength);
        }
예제 #7
0
        public unsafe bool TryGetEndPointByHandle(int handle, out NetworkEndPoint endpoint)
        {
            endpoint = default(NetworkEndPoint);
            if (handle >= m_IPCEndPoints.Length)
            {
                return(false);
            }

            var temp = new NetworkEndPoint();

            temp.Family     = NetworkFamily.IPC;
            temp.ipc_handle = handle;

            temp.nbo_port   = m_IPCEndPoints[handle];
            endpoint        = temp;
            endpoint.length = 6;
            return(true);
        }
예제 #8
0
        public unsafe void ReleaseEndPoint(NetworkEndPoint endpoint)
        {
            ManagerAccessHandle.Complete();
            if (endpoint.Family == NetworkFamily.IPC)
            {
                int handle = endpoint.ipc_handle;
                m_IPCQueue.Clear(handle);
                // Bump the version of the endpoint
                ushort version = m_IPCEndPoints[handle];
                ++version;
                if (version == 0)
                {
                    version = 1;
                }
                m_IPCEndPoints[handle] = version;

                m_FreeList.Enqueue(handle);
            }
        }
예제 #9
0
        private static unsafe NetworkInterfaceEndPoint ParseNetworkAddress(NetworkEndPoint endPoint)
        {
            NetworkInterfaceEndPoint ep = default(NetworkInterfaceEndPoint);
            var addr = (network_address *)ep.data;
            var sai  = (sockaddr_in *)addr->data;

#if (UNITY_EDITOR_OSX || ((UNITY_STANDALONE_OSX || UNITY_IOS) && !UNITY_EDITOR))
            sai->sin_family.sa_family = (byte)NetworkFamily.Ipv4;
            sai->sin_family.sa_len    = (byte)sizeof(sockaddr_in);
#else
            sai->sin_family.sa_family = (ushort)NetworkFamily.Ipv4;
#endif
            sai->sin_port = endPoint.RawPort;
            var bytes = endPoint.GetRawAddressBytes();
            sai->sin_addr.s_addr = *(uint *)bytes.GetUnsafeReadOnlyPtr();

            addr->length  = sizeof(sockaddr_in);
            ep.dataLength = sizeof(network_address);
            return(ep);
        }
예제 #10
0
        /// <summary>
        /// Create a NetworkEndPoint for IPC. If the EndPoint is passed to Bind the driver will assume ownership,
        /// otherwise the EndPoint must be destroyed by calling ReleaseEndPoint.
        /// </summary>
        public unsafe NetworkEndPoint CreateEndPoint(string name = null)
        {
            ManagerAccessHandle.Complete();
            int id;

            if (!m_FreeList.TryDequeue(out id))
            {
                id = m_IPCEndPoints.Length;
                m_IPCEndPoints.Add(1);
            }

            var endpoint = new NetworkEndPoint
            {
                Family     = NetworkFamily.IPC,
                ipc_handle = id,
                length     = 6,
                nbo_port   = m_IPCEndPoints[id]
            };

            return(endpoint);
        }
예제 #11
0
        public NetworkConnection Connect(NetworkEndPoint endpoint)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (!m_InternalState.IsCreated)
            {
                throw new InvalidOperationException(
                          "Driver must be constructed with a populated or empty INetworkParameter params list");
            }
#endif
            int id;
            if (!m_FreeList.TryDequeue(out id))
            {
                id = m_ConnectionList.Length;
                m_ConnectionList.Add(new Connection {
                    Id = id, Version = 1
                });
            }

            int ver = m_ConnectionList[id].Version;
            var c   = new Connection
            {
                Id           = id,
                Version      = ver,
                State        = NetworkConnection.State.Connecting,
                Address      = endpoint,
                Attempts     = 1,
                LastAttempt  = m_updateTime,
                SendToken    = 0,
                ReceiveToken = m_SessionIdCounter[0]
            };
            m_SessionIdCounter[0] = (ushort)(m_SessionIdCounter[0] + 1);

            m_ConnectionList[id] = c;
            var netcon = new NetworkConnection {
                m_NetworkId = id, m_NetworkVersion = ver
            };
            SendConnectionRequest(c);

            return(netcon);
        }
            public unsafe void Execute()
            {
                var address = new NetworkEndPoint {
                    length = sizeof(NetworkEndPoint)
                };
                var header = new UdpCHeader();
                var stream = receiver.GetDataStream();

                receiver.ReceiveCount     = 0;
                receiver.ReceiveErrorCode = 0;

                while (true)
                {
                    if (receiver.DynamicDataStreamSize())
                    {
                        while (stream.Length + NetworkParameterConstants.MTU >= stream.Capacity)
                        {
                            stream.Capacity *= 2;
                        }
                    }
                    else if (stream.Length >= stream.Capacity)
                    {
                        return;
                    }
                    var sliceOffset = stream.Length;
                    var result      = NativeReceive(ref header, stream.GetUnsafePtr() + sliceOffset,
                                                    Math.Min(NetworkParameterConstants.MTU, stream.Capacity - stream.Length), ref address);
                    if (result <= 0)
                    {
                        // FIXME: handle error
                        if (result < 0)
                        {
                            receiver.ReceiveErrorCode = 10040;
                        }
                        return;
                    }

                    receiver.ReceiveCount += receiver.AppendPacket(address, header, result);
                }
            }
        public unsafe NetworkInterfaceEndPoint CreateInterfaceEndPoint(NetworkEndPoint address)
        {
            var             slice = m_LocalAndTempEndpoint.AtIndexAsSlice(0, (uint)Binding.Baselib_RegisteredNetwork_Endpoint_MaxSize);
            var             error = default(ErrorState);
            NetworkEndpoint local;

            local = Binding.Baselib_RegisteredNetwork_Endpoint_Create(
                (Binding.Baselib_NetworkAddress *) & address.rawNetworkAddress,
                slice,
                error.NativeErrorStatePtr
                );
            if (error.ErrorCode != ErrorCode.Success)
            {
                return(default(NetworkInterfaceEndPoint));
            }

            var endpoint = default(NetworkInterfaceEndPoint);

            endpoint.dataLength = (int)local.slice.size;
            UnsafeUtility.MemCpy(endpoint.data, (void *)local.slice.data, endpoint.dataLength);
            return(endpoint);
        }
        int CreateAndBindSocket(out long socket, NetworkEndPoint address)
        {
            socket = -1;
            int errorcode = 0;
            int ret       = NativeBindings.network_create_and_bind(ref socket, ref address, ref errorcode);

            if (ret != 0)
            {
                return(errorcode);
            }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            AllSockets.OpenSockets.Add(socket);
#endif
            NativeBindings.network_set_nonblocking(socket);
            NativeBindings.network_set_send_buffer_size(socket, ushort.MaxValue);
            NativeBindings.network_set_receive_buffer_size(socket, ushort.MaxValue);
#if (UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN)
            // Avoid WSAECONNRESET errors when sending to an endpoint which isn't open yet (unclean connect/disconnects)
            NativeBindings.network_set_connection_reset(socket, 0);
#endif
            return(0);
        }
        public int Bind(NetworkEndPoint endpoint)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (endpoint.Family != NetworkFamily.UdpIpv4)
            {
                throw new InvalidOperationException();
            }
#endif

            long newSocket;
            int  ret = CreateAndBindSocket(out newSocket, endpoint);
            if (ret != 0)
            {
                return(ret);
            }
            Close();

            m_RemoteEndPoint = endpoint;
            m_SocketHandle   = newSocket;

            return(0);
        }
        public unsafe int SendMessage(network_iovec *iov, int iov_len, ref NetworkEndPoint address)
        {
            int errorcode = 0;

            return(NativeBindings.network_sendmsg(m_SocketHandle, iov, iov_len, ref address, ref errorcode));
        }
예제 #17
0
        public unsafe int AppendPacket(NetworkEndPoint address, UdpCHeader header, int dataLen)
        {
            int count = 0;

            switch ((UdpCProtocol)header.Type)
            {
            case UdpCProtocol.ConnectionRequest:
            {
                if (!Listening)
                {
                    return(0);
                }

                Connection c;
                if ((c = GetNewConnection(address, header.SessionToken)) == Connection.Null || c.State == NetworkConnection.State.Disconnected)
                {
                    int id;
                    var sessionId = m_SessionIdCounter[0];
                    m_SessionIdCounter[0] = (ushort)(m_SessionIdCounter[0] + 1);
                    if (!m_FreeList.TryDequeue(out id))
                    {
                        id = m_ConnectionList.Length;
                        m_ConnectionList.Add(new Connection {
                                Id = id, Version = 1
                            });
                    }

                    int ver = m_ConnectionList[id].Version;
                    c = new Connection
                    {
                        Id           = id,
                        Version      = ver,
                        ReceiveToken = sessionId,
                        SendToken    = header.SessionToken,
                        State        = NetworkConnection.State.Connected,
                        Address      = address,
                        Attempts     = 1,
                        LastAttempt  = m_updateTime
                    };
                    SetConnection(c);
                    m_NetworkAcceptQueue.Enqueue(id);
                    count++;
                }
                else
                {
                    c.Attempts++;
                    c.LastAttempt = m_updateTime;
                    SetConnection(c);
                }

                SendPacket(UdpCProtocol.ConnectionAccept,
                           new NetworkConnection {
                        m_NetworkId = c.Id, m_NetworkVersion = c.Version
                    });
            }
            break;

            case UdpCProtocol.ConnectionReject:
            {
                // m_EventQ.Enqueue(Id, (int)NetworkEvent.Connect);
            }
            break;

            case UdpCProtocol.ConnectionAccept:
            {
                if (header.Flags != 1)
                {
                    UnityEngine.Debug.LogError("Accept message received without flag set");
                    return(0);
                }

                Connection c = GetConnection(address, header.SessionToken);
                if (c != Connection.Null)
                {
                    c.DidReceiveData = 1;

                    if (c.State == NetworkConnection.State.Connected)
                    {
                        //DebugLog("Dropping connect request for an already connected endpoint [" + address + "]");
                        return(0);
                    }

                    if (c.State == NetworkConnection.State.Connecting)
                    {
                        var sliceOffset = m_DataStream.Length;
                        m_DataStream.WriteBytesWithUnsafePointer(2);
                        var dataStreamReader = new DataStreamReader(m_DataStream, sliceOffset, 2);
                        var context          = default(DataStreamReader.Context);
                        c.SendToken = dataStreamReader.ReadUShort(ref context);
                        m_DataStream.WriteBytesWithUnsafePointer(-2);

                        c.State = NetworkConnection.State.Connected;
                        UpdateConnection(c);
                        AddConnection(c.Id);
                        count++;
                    }
                }
            }
            break;

            case UdpCProtocol.Disconnect:
            {
                Connection c = GetConnection(address, header.SessionToken);
                if (c != Connection.Null)
                {
                    if (RemoveConnection(c))
                    {
                        AddDisconnection(c.Id);
                    }
                    count++;
                }
            }
            break;

            case UdpCProtocol.Data:
            {
                Connection c = GetConnection(address, header.SessionToken);
                if (c == Connection.Null)
                {
                    return(0);
                }

                c.DidReceiveData = 1;
                c.LastAttempt    = m_updateTime;
                UpdateConnection(c);

                var length = dataLen - UdpCHeader.Length;

                if (c.State == NetworkConnection.State.Connecting)
                {
                    if (header.Flags != 1)
                    {
                        UnityEngine.Debug.LogError("Received data without connection (no send token)");
                        return(0);
                    }

                    var tokenOffset = m_DataStream.Length + length - 2;
                    m_DataStream.WriteBytesWithUnsafePointer(length);
                    var dataStreamReader = new DataStreamReader(m_DataStream, tokenOffset, 2);
                    var context          = default(DataStreamReader.Context);
                    c.SendToken = dataStreamReader.ReadUShort(ref context);
                    m_DataStream.WriteBytesWithUnsafePointer(-length);

                    c.State = NetworkConnection.State.Connected;
                    UpdateConnection(c);
                    Assert.IsTrue(!Listening);
                    AddConnection(c.Id);
                    count++;
                }

                if (header.Flags == 1)
                {
                    length -= 2;
                }

                var sliceOffset = m_DataStream.Length;
                m_DataStream.WriteBytesWithUnsafePointer(length);

                m_EventQueue.PushEvent(new NetworkEvent
                    {
                        connectionId = c.Id,
                        type         = NetworkEvent.Type.Data,
                        offset       = sliceOffset,
                        size         = length
                    });
                count++;
            } break;
            }

            return(count);
        }
예제 #18
0
    public bool Init(string[] args)
    {
        ReplicatedPrefabMgr.Initialize();

        ClientServerSystemManager.InitServerSystems();
        World.Active.GetExistingSystem <TickServerSimulationSystem>().Enabled = true;
        Unity.Networking.Transport.NetworkEndPoint ep = Unity.Networking.Transport.NetworkEndPoint.AnyIpv4;
        ep.Port = (ushort)NetworkConfig.netcodeServerPort;
        World serverWorld = ClientServerSystemManager.serverWorld;

        serverWorld.GetExistingSystem <NetworkStreamReceiveSystem>().Listen(ep);

        // Set up statemachine for ServerGame
        m_StateMachine = new StateMachine <ServerState>();
        m_StateMachine.Add(ServerState.Idle, null, UpdateIdleState, null);
        m_StateMachine.Add(ServerState.Loading, null, UpdateLoadingState, null);
        m_StateMachine.Add(ServerState.Active, EnterActiveState, UpdateActiveState, LeaveActiveState);

        m_StateMachine.SwitchTo(ServerState.Idle);

        m_NetworkTransport = new SocketTransport(NetworkConfig.serverPort.IntValue, serverMaxClients.IntValue);
        var listenAddresses = NetworkUtils.GetLocalInterfaceAddresses();

        if (listenAddresses.Count > 0)
        {
            Console.SetPrompt(listenAddresses[0] + ":" + NetworkConfig.serverPort.Value + "> ");
        }
        GameDebug.Log("Listening on " + string.Join(", ", NetworkUtils.GetLocalInterfaceAddresses()) + " on port " + NetworkConfig.serverPort.IntValue);
        m_NetworkServer = new NetworkServer(m_NetworkTransport);

        if (Game.game.clientFrontend != null)
        {
            var serverPanel = Game.game.clientFrontend.serverPanel;
            serverPanel.SetPanelActive(true);
            serverPanel.serverInfo.text += "Listening on:\n";
            foreach (var a in NetworkUtils.GetLocalInterfaceAddresses())
            {
                serverPanel.serverInfo.text += a + ":" + NetworkConfig.serverPort.IntValue + "\n";
            }
        }

        m_NetworkServer.UpdateClientInfo();
        m_NetworkServer.serverInfo.compressionModel = m_Model;

        if (serverServerName.Value == "")
        {
            serverServerName.Value = MakeServername();
        }

#if false
        m_ServerQueryProtocolServer = new SQP.SQPServer(NetworkConfig.serverSQPPort.IntValue > 0? NetworkConfig.serverSQPPort.IntValue : NetworkConfig.serverPort.IntValue + NetworkConfig.sqpPortOffset);
#endif


#if UNITY_EDITOR
        Game.game.levelManager.UnloadLevel();
#endif
        m_GameWorld = new GameWorld("ServerWorld");

        m_NetworkStatistics = new NetworkStatisticsServer(m_NetworkServer);

        m_ChatSystem = new ChatSystemServer(m_Clients, m_NetworkServer);

        GameDebug.Log("Network server initialized");

        Console.AddCommand("load", CmdLoad, "Load a named scene", this.GetHashCode());
        Console.AddCommand("unload", CmdUnload, "Unload current scene", this.GetHashCode());
        Console.AddCommand("respawn", CmdRespawn, "Respawn character (usage : respawn playername|playerId)", this.GetHashCode());
        Console.AddCommand("servername", CmdSetServerName, "Set name of the server", this.GetHashCode());
        Console.AddCommand("beginnetworkprofile", CmdBeginNetworkProfile, "begins a network profile", this.GetHashCode());
        Console.AddCommand("endnetworkprofile", CmdEndNetworkProfile, "Ends a network profile and analyzes. [optional] filepath for model data", this.GetHashCode());
        Console.AddCommand("loadcompressionmodel", CmdLoadNetworkCompressionModel, "Loads a network compression model from a filepath", this.GetHashCode());
        Console.AddCommand("list", CmdList, "List clients", this.GetHashCode());

        CmdLoad(args);
        Game.SetMousePointerLock(false);

        m_ServerStartTime = Time.time;

        GameDebug.Log("Server initialized");
        Console.SetOpen(false);
        return(true);
    }
예제 #19
0
 public int Bind(NetworkEndPoint endpoint)
 {
     return(m_genericDriver.Bind(endpoint));
 }
예제 #20
0
 public NetworkConnection Connect(NetworkEndPoint endpoint)
 {
     return(m_genericDriver.Connect(endpoint));
 }
예제 #21
0
        static internal unsafe int SendMessageEx(NativeQueue <IPCQueuedMessage> .Concurrent queue, NetworkEndPoint local,
                                                 network_iovec *iov, int iov_len, ref NetworkEndPoint address)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (address.Family != NetworkFamily.IPC || local.Family != NetworkFamily.IPC ||
                address.nbo_port == 0 || local.nbo_port == 0)
            {
                throw new InvalidOperationException("Sending data over IPC requires both local and remote EndPoint to be valid IPC EndPoints");
            }
#endif

            var data = new IPCData();
            data.from   = local.ipc_handle;
            data.length = 0;

            for (int i = 0; i < iov_len; i++)
            {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (data.length + iov[i].len >= NetworkParameterConstants.MTU)
                {
                    throw new ArgumentOutOfRangeException("Cannot send more data than an MTU");
                }
#endif
                UnsafeUtility.MemCpy(data.data + data.length, iov[i].buf, iov[i].len);
                data.length += iov[i].len;
            }
            queue.Enqueue(new IPCQueuedMessage {
                dest = address.ipc_handle, data = data
            });
            return(data.length);
        }
예제 #22
0
        public unsafe int PeekNext(NetworkEndPoint local, void *slice, out int length, out NetworkEndPoint from)
        {
            ManagerAccessHandle.Complete();
            IPCData data;

            from   = default(NetworkEndPoint);
            length = 0;

            if (m_IPCQueue.Peek(local.ipc_handle, out data))
            {
                ushort version = m_IPCEndPoints[data.from];

                UnsafeUtility.MemCpy(slice, data.data, data.length);

                length = data.length;
            }

            NetworkEndPoint endpoint;

            if (!TryGetEndPointByHandle(data.from, out endpoint))
            {
                return(-1);
            }
            from = endpoint;

            return(length);
        }
예제 #23
0
    public bool Init(string[] args)
    {
        m_StateMachine = new StateMachine <ClientState>();
        m_StateMachine.Add(ClientState.Browsing, EnterBrowsingState, UpdateBrowsingState, LeaveBrowsingState);
        m_StateMachine.Add(ClientState.Connecting, EnterConnectingState, UpdateConnectingState, null);
        m_StateMachine.Add(ClientState.Loading, EnterLoadingState, UpdateLoadingState, null);
        m_StateMachine.Add(ClientState.Playing, EnterPlayingState, UpdatePlayingState, LeavePlayingState);

#if UNITY_EDITOR
        Game.game.levelManager.UnloadLevel();
#endif
        m_GameWorld = new GameWorld("ClientWorld");

        m_NetworkTransport = new SocketTransport();
        m_NetworkClient    = new NetworkClient(m_NetworkTransport);

        if (Application.isEditor || Game.game.buildId == "AutoBuild")
        {
            NetworkClient.clientVerifyProtocol.Value = "0";
        }

        m_NetworkClient.UpdateClientConfig();
        m_NetworkStatistics = new NetworkStatisticsClient(m_NetworkClient);
        m_ChatSystem        = new ChatSystemClient(m_NetworkClient);

        GameDebug.Log("Network client initialized");

        m_requestedPlayerSettings.playerName = clientPlayerName.Value;
        m_requestedPlayerSettings.teamId     = -1;

        Console.AddCommand("disconnect", CmdDisconnect, "Disconnect from server if connected", this.GetHashCode());
        Console.AddCommand("prediction", CmdTogglePrediction, "Toggle prediction", this.GetHashCode());
        Console.AddCommand("runatserver", CmdRunAtServer, "Run command at server", this.GetHashCode());
        Console.AddCommand("respawn", CmdRespawn, "Force a respawn", this.GetHashCode());
        Console.AddCommand("nextchar", CmdNextChar, "Select next character", this.GetHashCode());
        Console.AddCommand("nextteam", CmdNextTeam, "Select next character", this.GetHashCode());
        Console.AddCommand("spectator", CmdSpectator, "Select spectator cam", this.GetHashCode());
        Console.AddCommand("matchmake", CmdMatchmake, "matchmake <hostname[:port]/{projectid}>: Find and join a server", this.GetHashCode());

        if (args.Length > 0)
        {
            targetServer = args[0];
            m_StateMachine.SwitchTo(ClientState.Connecting);
        }
        else
        {
            m_StateMachine.SwitchTo(ClientState.Browsing);
        }

        ReplicatedPrefabMgr.Initialize();

        ClientServerSystemManager.InitClientSystems();
        World.Active.GetExistingSystem <TickClientSimulationSystem>().Enabled   = true;
        World.Active.GetExistingSystem <TickClientPresentationSystem>().Enabled = true;
        Unity.Networking.Transport.NetworkEndPoint ep = Unity.Networking.Transport.NetworkEndPoint.Parse(targetServer, (ushort)NetworkConfig.netcodeServerPort);
        World         clientWorld = ClientServerSystemManager.clientWorld;
        EntityManager em          = clientWorld.EntityManager;
        Entity        ent         = clientWorld.GetExistingSystem <NetworkStreamReceiveSystem>().Connect(ep);
        em.AddComponentData(ent, new NetworkStreamInGame());

        GameDebug.Log("Client initialized");

        return(true);
    }