private async Task DoLocalUpdate() { try { foreach (var registration in this._serverRegistrations) { ServerStatusUpdate statusUpdate = new ServerStatusUpdate(); try { Logger.Debug("Start: {0}", registration.LocalEndpoint); statusUpdate = await GenerateServerStatusUpdateAsync(registration); PostServerStatusUpdate(registration, registration.UpdateCallback, statusUpdate); } catch (Exception ex) { // We don't want to stop other registration queries or break the ActionBlock Logger.Debug("Exception in local update: {0} \n {1}", ex.Message, ex.StackTrace); Debugger.Break(); } finally { Logger.Debug("End: {0}: {1}", registration.LocalEndpoint, statusUpdate.Status); } } } finally { Task.Delay(LOCAL_STATUS_QUERY_DELAY).ContinueWith(_ => _eventQueue.Post(DoLocalUpdate)).DoNotWait(); } }
private async Task <ServerStatusUpdate> GenerateServerStatusUpdateAsync(ServerStatusUpdateRegistration registration) { var registrationKey = registration.SteamEndpoint.ToString(); // // First check the process status // Process process; var processStatus = GetServerProcessStatus(registration, out process); switch (processStatus) { case ServerProcessStatus.NotInstalled: return(new ServerStatusUpdate { Status = ServerStatus.NotInstalled }); case ServerProcessStatus.Stopped: return(new ServerStatusUpdate { Status = ServerStatus.Stopped }); case ServerProcessStatus.Unknown: return(new ServerStatusUpdate { Status = ServerStatus.Unknown }); case ServerProcessStatus.Running: break; default: Debugger.Break(); break; } var currentStatus = ServerStatus.Initializing; // // If the process was running do we then perform network checks. // Logger.Debug("Checking server local status at {0}", registration.LocalEndpoint); // get the server information direct from the server using local connection. ReadOnlyCollection <Player> players; var localInfo = GetLocalNetworkStatus(registration.LocalEndpoint, out players); if (localInfo != null) { currentStatus = ServerStatus.RunningLocalCheck; // // Now that it's running, we can check the publication status. // Logger.Debug("Checking server public status at {0}", registration.SteamEndpoint); // get the server information direct from the server using public connection. var serverStatus = NetworkUtils.CheckServerStatusDirect(registration.SteamEndpoint); // check if the server returned the information. if (!serverStatus) { // server did not return any information var lastExternalStatusQuery = _lastExternalStatusQuery.ContainsKey(registrationKey) ? _lastExternalStatusQuery[registrationKey] : DateTime.MinValue; if (DateTime.Now >= lastExternalStatusQuery.AddMilliseconds(REMOTE_STATUS_QUERY_DELAY)) { currentStatus = ServerStatus.RunningExternalCheck; // get the server information direct from the server using external connection. var uri = new Uri(string.Format(Config.Default.ServerStatusUrlFormat, Config.Default.ServerManagerCode, registration.SteamEndpoint.Address, registration.SteamEndpoint.Port)); serverStatus = await NetworkUtils.CheckServerStatusViaAPI(uri, registration.SteamEndpoint); _lastExternalStatusQuery[registrationKey] = DateTime.Now; } } //var lastExternalCallQuery = _lastExternalCallQuery.ContainsKey(registrationKey) ? _lastExternalCallQuery[registrationKey] : DateTime.MinValue; //if (lastExternalCallQuery == DateTime.MinValue) //{ // // perform a server call to the web api. // var uri = new Uri(string.Format(Config.Default.ServerCallUrlFormat, Config.Default.ServerManagerCode, registration.SteamEndpoint.Address, registration.SteamEndpoint.Port, Config.Default.ServerManagerUniqueKey, registration.ProfileId)); // await NetworkUtils.PerformServerCallToAPI(uri, registration.SteamEndpoint); // _lastExternalCallQuery[registrationKey] = DateTime.Now; //} // check if the server returned the information. if (serverStatus) { currentStatus = ServerStatus.Published; } else { Logger.Debug("No public status returned for {0}", registration.SteamEndpoint); } } var statusUpdate = new ServerStatusUpdate { Process = process, Status = currentStatus, ServerInfo = localInfo, Players = players }; return(await Task.FromResult(statusUpdate)); }
private void PostServerStatusUpdate(ServerStatusUpdateRegistration registration, StatusCallback callback, ServerStatusUpdate statusUpdate) { _eventQueue.Post(() => { if (this._serverRegistrations.Contains(registration)) { try { callback(registration, statusUpdate); } catch (Exception ex) { DebugUtils.WriteFormatThreadSafeAsync("Exception during local status update callback: {0}\n{1}", ex.Message, ex.StackTrace).DoNotWait(); } } return(TaskUtils.FinishedTask); }); }
private void MessageReceived() { lock (_receivedData) { _receivedData.Seek(0, SeekOrigin.Begin); int messageType = _receivedData.ReadByte(); ServerMessageType type = (ServerMessageType)messageType; switch (type) { case ServerMessageType.Map: Map map = Serializer.DeserializeWithLengthPrefix <Map>(_receivedData, PrefixStyle.Base128); Debug.WriteLine("Map received."); // Map successfully received, change game state to wait for start _gameInfo.Level = map; _gameInfo.State = RunStates.WaitingForGameStart; // Update status display Deployment.Current.Dispatcher.BeginInvoke(() => _mainState.DisplayStatusMessage("Waiting for players to be ready...\nYou are NOT ready.")); SendResponse(new ClientStatusUpdate(ClientUpdate.MapOk)); break; case ServerMessageType.Player: PlayerInfo playerInfo = Serializer.DeserializeWithLengthPrefix <PlayerInfo>(_receivedData, PrefixStyle.Base128); _gameInfo.AddPlayer(playerInfo.Color, playerInfo.X, playerInfo.Y); SendResponse(new ClientStatusUpdate(ClientUpdate.PlayerInfoOk)); Debug.WriteLine("Player info received..."); break; case ServerMessageType.StatusUpdate: ServerStatusUpdate update = Serializer.DeserializeWithLengthPrefix <ServerStatusUpdate>(_receivedData, PrefixStyle.Base128); _gameInfo.UpdateStatus(update); break; case ServerMessageType.BombExplosion: BombExplode explosion = Serializer.DeserializeWithLengthPrefix <BombExplode>(_receivedData, PrefixStyle.Base128); _gameInfo.ExplodeBomb(explosion); break; case ServerMessageType.PlayerDeath: PlayerDeath playerDeath = Serializer.DeserializeWithLengthPrefix <PlayerDeath>(_receivedData, PrefixStyle.Base128); _gameInfo.KillPlayer(playerDeath); break; case ServerMessageType.GameOver: GameOverUpdate gameOverUpdate = Serializer.DeserializeWithLengthPrefix <GameOverUpdate>(_receivedData, PrefixStyle.Base128); _gameInfo.EndGame(gameOverUpdate); SendResponseSync("GO OK"); break; default: Debug.WriteLine("Unrecognised package received!"); break; } _receivedData = new MemoryStream(); } }
private static async Task <ServerStatusUpdate> GenerateServerStatusUpdateAsync(ServerStatusUpdateRegistration registration) { // // First check the process status // Process process; var processStatus = GetServerProcessStatus(registration, out process); switch (processStatus) { case ServerProcessStatus.NotInstalled: return(new ServerStatusUpdate { Status = ServerStatus.NotInstalled }); case ServerProcessStatus.Stopped: return(new ServerStatusUpdate { Status = ServerStatus.Stopped }); case ServerProcessStatus.Running: break; default: Debugger.Break(); break; } ServerStatus currentStatus = ServerStatus.Initializing; // // If the process was running do we then perform network checks. // ServerInfo localInfo; ReadOnlyCollection <Player> players; localInfo = GetLocalNetworkStatus(registration.LocalEndpoint, out players); if (localInfo != null) { currentStatus = ServerStatus.Running; // // Now that it's running, we can check the publication status. // logger.Debug("Checking server public status at {0}", registration.SteamEndpoint); var serverInfo = await NetworkUtils.GetServerNetworkInfo(registration.SteamEndpoint); if (serverInfo != null) { currentStatus = ServerStatus.Published; } else { logger.Debug("No public status returned for {0}", registration.SteamEndpoint); } } var statusUpdate = new ServerStatusUpdate { Process = process, Status = currentStatus, ServerInfo = localInfo, Players = players }; return(await Task.FromResult(statusUpdate)); }
public void UpdateStatus(ServerStatusUpdate update) { // Update players first foreach (PlayerInfo player in update.Players) { // Don't change coordinates of the local player if (player.Color == _mainState.LocalPlayer.Color) { continue; } var ply = GetPlayer(player.Color); if (ply == null) { AddPlayer(player.Color, player.X, player.Y); } else { // Dispatch position change to the UI thread PlayerInfo info = player; Deployment.Current.Dispatcher.BeginInvoke(() => { ply.X = info.X; ply.Y = info.Y; ply.Direction = info.Direction; ply.Moving = info.Moving; }); } } // Check for command switch (update.Update) { case ServerCommand.StartGame: GameStart(); break; case ServerCommand.PlayerUpdate: // Do nothing, players were already updated break; // A new bomb was set, display it case ServerCommand.BombSet: AutoResetEvent rst = new AutoResetEvent(false); Bomb bomb = null; Deployment.Current.Dispatcher.BeginInvoke(() => { bomb = new Bomb(_mainState.GameCanvas, update.X, update.Y); rst.Set(); }); rst.WaitOne(); lock (_bombs) { _bombs.Add(bomb); } Debug.WriteLine("Bomb set on " + bomb.Position); break; case ServerCommand.ScrambleControls: _mainState.LocalPlayer.ScrambleControls(); RemovePowerup(update.X, update.Y); break; case ServerCommand.ClearPowerup: RemovePowerup(update.X, update.Y); break; default: throw new NotImplementedException(); } }