コード例 #1
0
 private void OnServerDisconnected(NetWorker sender)
 {
     MainThreadManager.Run(() =>
     {
         BMSLog.Log("steamP2PServer.disconnected called");
     });
 }
コード例 #2
0
 private void OnServerPlayerAccepted(NetworkingPlayer player, NetWorker sender)
 {
     MainThreadManager.Run(() =>
     {
         BMSLog.Log("Player " + player.NetworkId + " connected");
     });
 }
コード例 #3
0
    /// <summary>
    /// Connected is called whenever we set up a new server or client
    /// </summary>
    /// <param name="networker"></param>
    public void Connected(NetWorker networker, UnityEngine.UI.Text connectionText = null)
    {
        string info = "Networker is bound";

        if (!networker.IsBound)
        {
            BMSLog.LogWarning("NetWorker failed to bind");
            //return;
        }
        else
        {
            BMSLog.Log(info);
            if (connectionText != null)
            {
                connectionText.text = info;
            }
        }

        if (!haveNetworkManager)
        {
            BMSLog.LogWarning("Network Manager could not be found. This should never happen!");
            if (networkManagerGO != null)
            {
                Destroy(networkManagerGO);
            }
            networkManager = GetNetworkManager();
            networkManager.Initialize(networker);
        }
        info = "Networker Connection Complete";
        BMSLog.Log(info);
        if (connectionText != null)
        {
            connectionText.text = info;
        }
    }
コード例 #4
0
 private void OnServerPlayerTimeout(NetworkingPlayer player, NetWorker sender)
 {
     MainThreadManager.Run(() =>
     {
         BMSLog.Log("Player " + player.NetworkId + " timed out");
     });
 }
コード例 #5
0
 private void Start()
 {
     if (LogToFile)
     {
         BMSLog.Log("========= START RUN =========");
     }
 }
コード例 #6
0
        private void ReadAsync()
        {
            try
            {
                while (IsBound)
                {
                    switch (Read())
                    {
                    case ReadState.Void:
                        break;

                    case ReadState.Continue:
                        Thread.Sleep(10);
                        break;

                    case ReadState.Disconnect:
                        return;
                    }
                }
            }
            catch (Exception e)
            {
                // There was in issue reading or executing from the network so disconnect
                // TODO:  Add more logging here and an exception with an inner exception being
                // the exception that was thrown
                BMSLog.LogException(e);
                //Console.WriteLine("CRASH: " + e.Message);
                Disconnect(true);
            }
        }
コード例 #7
0
 private void OnClientDisconnected(NetWorker server)
 {
     MainThreadManager.Run(() =>
     {
         BMSLog.Log("Client disconnected");
         CancelGame(true);
     });
 }
コード例 #8
0
 private void OnServerPlayerDisconnected(NetworkingPlayer player, NetWorker sender)
 {
     MainThreadManager.Run(() =>
     {
         BMSLog.Log("Player " + player.NetworkId + " disconnected.");
         HandlePlayerDisconnect(player, sender);
     });
 }
コード例 #9
0
 private void OnLobbyDataChanged(Steamworks.Data.Lobby lobby)
 {
     BMSLog.Log("Lobby data changed, new data:");
     foreach (KeyValuePair <string, string> data in lobby.Data)
     {
         BMSLog.Log(data.Key + "; " + data.Value);
     }
 }
コード例 #10
0
 public void InviteFriends()
 {
     if (lobby.Id.Value > 0)
     {
         SteamFriends.OpenGameInviteOverlay(lobby.Id);
     }
     else
     {
         BMSLog.Log("lobby id value is not set, is the lobby created yet?");
     }
 }
コード例 #11
0
 public void StartGame()
 {
     BMSLog.Log("StartGame called. IsHosting = " + isHosting);
     if (isHosting)
     {
         LevelManager.StartGameLevel();
     }
     else
     {
         BMSLog.Log("Only the host can start the game");
     }
 }
コード例 #12
0
    /// <summary>
    /// Connect to the selected steam lobby
    /// On successful connection, starts a new FacepunchP2PClient for connection to the lobby owner's FacepunchP2PServer
    /// </summary>
    private async Task ConnectToLobby()
    {
        RoomEnter roomEnter = await lobbyToJoin.Join();

        if (roomEnter != RoomEnter.Success)
        {
            BMSLog.Log("Error connecting to lobby returned: " + roomEnter.ToString());
            return;
        }

        this.lobby = lobbyToJoin;
        ConnectToServer(lobbyToJoin.Owner.Id);
    }
コード例 #13
0
    private void OnClientServerAccepted(NetWorker server)
    {
        MainThreadManager.Run(() =>
        {
            string info = "Server accepted the connection, loading server scene";
            BMSLog.Log(info);

            /*if (connectionText != null)
             * {
             *      connectionText.text = info;
             * }*/
        });
    }
コード例 #14
0
    private async Task JoinLobby(Steamworks.Data.Lobby lobbyToJoin)
    {
        RoomEnter roomEnter = await lobbyToJoin.Join();

        if (roomEnter != RoomEnter.Success)
        {
            BMSLog.Log("Error connecting to lobby returned: " + roomEnter.ToString());
            return;
        }
        this.lobby = lobbyToJoin;
        BMSLog.Log("Connected to lobby, owner.Id = " + lobbyToJoin.Owner.Id.Value);
        ConnectToHost(lobbyToJoin.Owner.Id, null);
    }
コード例 #15
0
    /// <summary>
    /// Create new FacepunchP2PServer
    /// </summary>
    private void CreateFacepunchP2PServer()
    {
        server = new FacepunchP2PServer(MAXIMUM_SERVER_SLOTS);
        ((FacepunchP2PServer)server).Host();

        server.playerTimeout += (player, sender) =>
        {
            BMSLog.Log("Player " + player.NetworkId + " timed out");
        };

        // TODO:  Add in server callbacks here as required

        Connected(server);
    }
コード例 #16
0
    private void OnClientBindSuccessful(NetWorker server)
    {
        MainThreadManager.Run(() =>
        {
            isHosting = false;
            //Connected(steamP2PClient);
            string info = "Networker bound, connecting to server...";
            BMSLog.Log(info);

            /*if (connectionText != null)
             * {
             *      connectionText.text = info;
             * }*/
        });
    }
コード例 #17
0
    /// <summary>
    /// When we return to the main menu, delete everything from the game and reset to initial state.
    /// </summary>
    ///     /// NEEDS TO BE REFACTORED OUT
    public void ResetGame()
    {
        BMSLog.Log("GameController.ResetGame called");

        for (int i = 0; i < allControllers.Count; i++)
        {
            if (allControllers[i] != null)
            {
                if (allControllers[i].GetControllerType() != typeof(LevelManager) && allControllers[i].GetControllerType() != typeof(NetworkController))
                {
                    Destroy(allControllers[i].gameObject);
                }
            }
        }
    }
コード例 #18
0
 private Steamworks.Data.Lobby GetLobby()
 {
     if (lobby.Id.Value > 0)
     {
         return(lobby);
     }
     else
     {
         lobby = networkController.GetLobby();
         if (lobby.Id.Value > 0)
         {
             return(lobby);
         }
         else
         {
             BMSLog.LogWarning("Could not find this lobby");
             return(default);
コード例 #19
0
    private void Start()
    {
        var gC = FindObjectOfType <GameController>();

        networkController = (NetworkController)gC.GetController(typeof(NetworkController)) as NetworkController;
        if (!networkController)
        {
            BMSLog.LogWarning("Could not find networkController - should not see me");
        }

        // Init the MainThreadManager
        MainThreadManager.Create();

        connectButton.enabled         = false;
        serverListEntryTemplateHeight = ((RectTransform)serverListEntryTemplate.transform).rect.height;
        RefreshLobbiesAsync();
    }
コード例 #20
0
    public void CancelGame(bool loadMenu = true)
    {
        BMSLog.Log("Cancelling game start and reloading main menu");
        UnsubscribeP2PClientEvents();
        UnsubscribeP2PServerEvents();
        lobby.Leave();
        lobby = default;
        if (haveNetworkManager)
        {
            BMSLog.Log("Calling networkManager.Disconnect()");
            networkManager.Disconnect();
            haveNetworkManager = false;
        }

        if (loadMenu)
        {
            LevelManager.LoadMainMenu();
        }
    }
コード例 #21
0
        private void Setup(string hostAddress, ushort port)
        {
            Socket.binaryMessageReceived += Read;

            if (Socket.IsServer)
            {
                ((UDPServer)Socket).Connect(hostAddress, port);
                Socket.playerConnected    += (player, sender) => { BMSLog.Log("PLAYER CONNECTED " + player.IPEndPointHandle.Address); };
                Socket.playerAccepted     += (player, sender) => { BMSLog.Log("PLAYER ACCEPTED " + player.IPEndPointHandle.Address); };
                Socket.playerRejected     += (player, sender) => { BMSLog.Log("PLAYER REJECTED " + player.IPEndPointHandle.Address); };
                Socket.playerDisconnected += (player, sender) => { BMSLog.Log("PLAYER DISCONNECTED " + player.IPEndPointHandle.Address); };
                StartWar(Socket);
            }
            else
            {
                Socket.serverAccepted += StartWar;
                ((UDPClient)Socket).Connect(hostAddress, port);
            }
        }
コード例 #22
0
    /// <summary>
    /// Finalize networker creation
    /// </summary>
    /// <param name="networker">The FacepunchP2PServer or FacepunchP2PClient just created</param>
    public void Connected(NetWorker networker)
    {
        if (!networker.IsBound)
        {
            BMSLog.LogWarning("NetWorker failed to bind");
            return;
        }

        if (mgr == null && networkManager == null)
        {
            BMSLog.LogWarning("A network manager was not provided, generating a new one instead");
            networkManager = new GameObject("Network Manager");
            mgr            = networkManager.AddComponent <NetworkManager>();
        }
        else if (mgr == null)
        {
            mgr = Instantiate(networkManager).GetComponent <NetworkManager>();
        }

        mgr.Initialize(networker);

        if (useInlineChat && networker.IsServer)
        {
            SceneManager.sceneLoaded += CreateInlineChat;
        }

        if (networker is IServer)
        {
            if (!dontChangeSceneOnConnect)
            {
                SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1);
            }
            else
            {
                NetworkObject.Flush(networker);
            }
        }
    }
コード例 #23
0
        private void OnDisconnect(NetWorker sender)
        {
            MainThreadManager.Run(() =>
            {
                foreach (var netObject in sender.NetworkObjectList)
                {
                    if (netObject.Owner.IsHost)
                    {
                        BMSLog.Log("Server disconnected");
                        // Go back to the multiplayer menu
                        SceneManager.LoadScene(1);
                    }
                }
            });

            if (NetworkManager.Instance == null)
            {
                return;
            }

            NetworkManager.Instance.Networker.disconnected -= OnDisconnect;
            NetworkManager.Instance.Disconnect();
        }
コード例 #24
0
    public void ConnectToHost(SteamId hostSteamId, UnityEngine.UI.Text connectionText)
    {
        string info = "Starting Client connection to lobby owner (host): " + hostSteamId.Value.ToString();

        BMSLog.Log(info);
        if (connectionText != null)
        {
            connectionText.text = info;
        }

        networkManager = GetNetworkManager();
        steamP2PClient = new FacepunchP2PClient();
        networkManager.Initialize(steamP2PClient);
        ((FacepunchP2PClient)steamP2PClient).bindSuccessful += OnClientBindSuccessful;
        ((FacepunchP2PClient)steamP2PClient).serverAccepted += OnClientServerAccepted;
        ((FacepunchP2PClient)steamP2PClient).disconnected   += OnClientDisconnected;
        ((FacepunchP2PClient)steamP2PClient).Connect(hostSteamId);

        // Moved initialize after Connect() call and callbacks and this along with the 1 cycle delay on setting up the ReadNetwork thread seems to stop the
        // SteamNetworking NRE problems.
        //networkManager.Initialize(steamP2PClient);
        Connected(steamP2PClient);
    }
コード例 #25
0
    private async Task RefreshLobbies()
    {
        var lobbyQuery = new Steamworks.Data.LobbyQuery();
        var lobbyList  = await lobbyQuery.RequestAsync();

        if (lobbyList == null)
        {
            BMSLog.Log("Lobbylist is null!");
            return;
        }

        var serversToKeep = new HashSet <Steamworks.Data.Lobby>();

        foreach (var lobby in lobbyList)
        {
            if (lobby.GetData("FNR-FP") == "blob")
            {
                AddServer(lobby);
                serversToKeep.Add(lobby);
            }
        }

        var serversToRemove = new HashSet <FacepunchServerListItemData>();

        foreach (var entry in serverList)
        {
            if (!serversToKeep.Contains(entry.lobby))
            {
                serversToRemove.Add(entry);
            }
        }

        foreach (var entry in serversToRemove)
        {
            RemoveServer(entry);
        }
    }
コード例 #26
0
    private void Start()
    {
        var gC = FindObjectOfType <GameController>();

        networkController = (NetworkController)gC.GetController(typeof(NetworkController)) as NetworkController;
        if (!networkController)
        {
            BMSLog.LogWarning("Could not find networkController - should not see me");
        }

        // Init the MainThreadManager
        MainThreadManager.Create();

        playButton.enabled            = false;
        playerListEntryTemplateHeight = ((RectTransform)playerListEntryTemplate.transform).rect.height;
        RefreshPlayers();
        SetLobbyEvents();
        if (!networkController.GetIsHost())
        {
            LoadedAsClient();
        }

        GetLobby();
    }
コード例 #27
0
    private async Task CreateLobby()
    {
        Steamworks.Data.Lobby?lobbyCreated = await SteamMatchmaking.CreateLobbyAsync(64);

        if (!lobbyCreated.HasValue)
        {
            BMSLog.Log("Error creating lobby");
            return;
        }

        BMSLog.Log("Created Lobby Async: lobby Id = " + lobbyCreated.Value.Id);
        var lobbyVal = lobbyCreated.Value;

        lobbyVal.SetPublic();
        lobbyVal.SetData("FNR-FP", "blob");
        this.lobby = lobbyVal;

        BMSLog.Log("Starting Host fuction");
        ((FacepunchP2PServer)steamP2PServer).Host();
        Connected(steamP2PServer);

        //Load 02aLobbyHost scene
        levelManager.LoadLevel("02aLobbyHost");
    }
コード例 #28
0
        /// <summary>
        /// 无限循环在单独的线程上监听来自所有连接客户端的新数据。
        /// readThreadCancel设置为true时,此循环会中断
        ///
        /// Infinite loop listening for new data from all connected clients on a separate thread.
        /// This loop breaks when readThreadCancel is set to true
        /// </summary>
        private void ReadClients()
        {
            //故意无限循环
            // Intentional infinite loop
            while (IsBound && !NetWorker.EndingSession)
            {
                try
                {
                    //如果读取已被标记为取消,则从此循环中断开
                    // If the read has been flagged to be canceled then break from this loop
                    if (readThreadCancel)
                    {
                        return;
                    }

                    //这将遍历所有玩家,因此请确保将锁设置为
                    //防止来自其他线程的任何更改
                    // This will loop through all of the players, so make sure to set the lock to
                    // prevent any changes from other threads
                    lock (Players)
                    {
                        for (int i = 0; i < Players.Count; i++)
                        {
                            //如果读取已被标记为取消,则从此循环中断开
                            // If the read has been flagged to be canceled then break from this loop
                            if (readThreadCancel)
                            {
                                return;
                            }

                            NetworkStream playerStream = null;

                            if (Players[i].IsHost)
                            {
                                continue;
                            }

                            try
                            {
                                lock (Players[i].MutexLock)
                                {
                                    //尝试获取客户端流,如果它仍然可用
                                    // Try to get the client stream if it is still available
                                    playerStream = Players[i].TcpClientHandle.GetStream();
                                }
                            }
                            catch
                            {
                                //无法获取客户端的流,因此强制断开连接
                                //Console.WriteLine("Exception异常:无法为客户端获取流(强制断开连接)“);

                                // Failed to get the stream for the client so forcefully disconnect it
                                //Console.WriteLine("Exception: Failed to get stream for client (Forcefully disconnecting)");
                                Disconnect(Players[i], true);
                                continue;
                            }

                            //如果播放器不再连接,请确保正确断开连接
                            // If the player is no longer connected, then make sure to disconnect it properly
                            if (!Players[i].TcpClientHandle.Connected)
                            {
                                Disconnect(Players[i], false);
                                continue;
                            }

                            //如果有任何数据可用,则只有继续阅读此客户端
                            // Only continue to read for this client if there is any data available for it
                            if (!playerStream.DataAvailable)
                            {
                                continue;
                            }

                            int available = Players[i].TcpClientHandle.Available;

                            try
                            {
                                lock (Players[i].MutexLock)
                                {
                                    // 设置消息ping时间
                                    Players[i].Ping();

                                    // 读取消息
                                    ProtoMsg protoMsg = GetNextBytes(playerStream, available, false);


                                    //客户端已经告诉服务器它正在断开连接
                                    if (protoMsg.protoId == ProtoId.ConnectionClose)
                                    {
                                        //确认连接关闭
                                        protoServer.SendConnectionClose(Players[i].TcpClientHandle);
                                        Disconnect(Players[i], false);
                                        continue;
                                    }

                                    protoServer.OnMessage(protoMsg, Players[i]);
                                }
                            }
                            catch
                            {
                                //播放器发送无效数据,请断开连接
                                Disconnect(Players[i], true);
                            }
                        }
                    }

                    //检查所有挂起的断开连接并清理它们
                    //完成并确定断开连接
                    CleanupDisconnections();

                    //睡眠,这样我们就可以从这个线程释放一些CPU
                    Thread.Sleep(10);
                }
                catch (Exception ex)
                {
                    BMSLog.LogException(ex);
                }
            }
        }
コード例 #29
0
        /// <summary>
        /// This will begin the connection for TCP, this is a thread blocking operation until the connection
        /// is either established or has failed
        /// </summary>
        /// <param name="hostAddress">[127.0.0.1] Ip Address to host from</param>
        /// <param name="port">[15937] Port to allow connections from</param>
        public void Connect(string hostAddress = "0.0.0.0", ushort port = DEFAULT_PORT)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("TCPServer", "This object has been disposed and can not be used to connect, please use a new TCPServer");
            }

            if (string.IsNullOrEmpty(hostAddress))
            {
                throw new BaseNetworkException("An ip address must be specified to bind to. If you are unsure, you can set to 127.0.0.1");
            }

            // Check to see if this server is being bound to a "loopback" address, if so then bind to any, otherwise bind to specified address
            if (hostAddress == "0.0.0.0" || hostAddress == "localhost")
            {
                ipAddress = IPAddress.Any;
            }
            else
            {
                ipAddress = IPAddress.Parse(hostAddress);
            }

            try
            {
                // Setup and start the base C# TcpListner
                listener = new TcpListener(ipAddress, port);
                //listener.Start();

                Me = new NetworkingPlayer(ServerPlayerCounter++, "0.0.0.0", true, listener, this);
                Me.InstanceGuid = InstanceGuid.ToString();

                // Create the thread that will be listening for clients and start its execution
                //Thread connectionThread = new Thread(new ThreadStart(ListenForConnections));
                //connectionThread.Start();
                //Task.Queue(ListenForConnections);
                listener.Start();
                listener.BeginAcceptTcpClient(ListenForConnections, listener);

                //在成功绑定的结果中执行任何通用初始化
                // Do any generic initialization in result of the successful bind
                OnBindSuccessful();

                //创建将监听来自连接客户端的新数据并开始执行的线程
                // Create the thread that will be listening for new data from connected clients and start its execution
                Task.Queue(ReadClients);

                // 创建将检查播放器超时的线程
                // Create the thread that will check for player timeouts
                Task.Queue(() =>
                {
                    // TODO ZF 关闭检测超时
                    //commonServerLogic.CheckClientTimeout((player) =>
                    //{
                    //    Disconnect(player, true);
                    //    OnPlayerTimeout(player);
                    //    CleanupDisconnections();
                    //});
                });

                //让我知道我连接成功
                //Let myself know I connected successfully
                OnPlayerConnected(Me);
                //将自己设置为连接的客户端
                // Set myself as a connected client
                Me.Connected = true;

                //设置端口
                //Set the port
                SetPort((ushort)((IPEndPoint)listener.LocalEndpoint).Port);
            }
            catch (Exception e)
            {
                BMSLog.LogException(e);
                // Do any generic initialization in result of the binding failure
                OnBindFailure();

                throw new FailedBindingException("Failed to bind to host/port, see inner exception", e);
            }
        }
コード例 #30
0
 public void LoadGameAsClient()
 {
     BMSLog.Log("LoadGameAsClient");
 }