private void OnServerDisconnected(NetWorker sender) { MainThreadManager.Run(() => { BMSLog.Log("steamP2PServer.disconnected called"); }); }
private void OnServerPlayerAccepted(NetworkingPlayer player, NetWorker sender) { MainThreadManager.Run(() => { BMSLog.Log("Player " + player.NetworkId + " connected"); }); }
/// <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; } }
private void OnServerPlayerTimeout(NetworkingPlayer player, NetWorker sender) { MainThreadManager.Run(() => { BMSLog.Log("Player " + player.NetworkId + " timed out"); }); }
private void Start() { if (LogToFile) { BMSLog.Log("========= START RUN ========="); } }
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); } }
private void OnClientDisconnected(NetWorker server) { MainThreadManager.Run(() => { BMSLog.Log("Client disconnected"); CancelGame(true); }); }
private void OnServerPlayerDisconnected(NetworkingPlayer player, NetWorker sender) { MainThreadManager.Run(() => { BMSLog.Log("Player " + player.NetworkId + " disconnected."); HandlePlayerDisconnect(player, sender); }); }
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); } }
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?"); } }
public void StartGame() { BMSLog.Log("StartGame called. IsHosting = " + isHosting); if (isHosting) { LevelManager.StartGameLevel(); } else { BMSLog.Log("Only the host can start the game"); } }
/// <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); }
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; * }*/ }); }
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); }
/// <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); }
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; * }*/ }); }
/// <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); } } } }
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);
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(); }
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(); } }
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); } }
/// <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); } } }
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(); }
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); }
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); } }
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(); }
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"); }
/// <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); } } }
/// <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); } }
public void LoadGameAsClient() { BMSLog.Log("LoadGameAsClient"); }