static int GetPreferredDifficulty(CustomSongInfo _song) { int difficulty = 0; foreach (CustomSongInfo.DifficultyLevel diff in _song.difficultyLevels) { if ((int)Enum.Parse(typeof(Difficulty), diff.difficulty) <= 3 && (int)Enum.Parse(typeof(Difficulty), diff.difficulty) >= difficulty) { difficulty = (int)Enum.Parse(typeof(Difficulty), diff.difficulty); } } return(difficulty); }
private static void DownloadSongs() { Settings.Instance.Server.Downloaded.GetDirectories().AsParallel().ForAll(dir => dir.Delete(true)); Settings.Instance.AvailableSongs.Songs.ToList().AsParallel().ForAll(id => { DownloadSongByID(id); }); Logger.Instance.Log("All songs downloaded!"); List <CustomSongInfo> _songs = SongLoader.RetrieveAllSongs(); _songs.AsParallel().ForAll(song => { ProcessSong(song); }); if (Settings.Instance.AvailableSongs.SongOrder == Settings.SongOrder.List) { CustomSongInfo[] buffer = new CustomSongInfo[availableSongs.Count]; availableSongs.CopyTo(buffer); availableSongs.Clear(); foreach (string id in Settings.Instance.AvailableSongs.Songs) { try { availableSongs.Add(buffer.First(x => x.beatSaverId == id)); } catch (Exception) { Logger.Instance.Warning($"Can't find song with ID {id}"); } } var notSortedSongs = buffer.Except(availableSongs).ToList(); if (notSortedSongs.Count > 0) { Logger.Instance.Warning($"{notSortedSongs.Count} songs not sorted!"); availableSongs.AddRange(notSortedSongs); } } Logger.Instance.Log("Done!"); }
private static void ProcessSong(CustomSongInfo song) { try { Logger.Instance.Log($"Processing {song.songName} {song.songSubName}"); if (song.difficultyLevels[0].audioPath.ToLower().EndsWith(".ogg")) { string pathToLoad = $"{song.path}/{song.difficultyLevels[0].audioPath}"; string[] actualFileNames = Directory.GetFiles(song.path, "*.ogg", SearchOption.TopDirectoryOnly); if (!File.Exists(pathToLoad)) { pathToLoad = $"{song.path}/{actualFileNames[0]}"; } using (VorbisReader vorbis = new VorbisReader(pathToLoad)) { song.duration = vorbis.TotalTime; } } else { string pathToLoad = $"{song.path}/{song.difficultyLevels[0].audioPath}"; string[] actualFileNames = Directory.GetFiles(song.path, "*.wav", SearchOption.TopDirectoryOnly); if (!File.Exists(pathToLoad)) { pathToLoad = $"{song.path}/{actualFileNames[0]}"; } using (AudioFileReader wave = new AudioFileReader(pathToLoad)) { song.duration = wave.TotalTime; } } availableSongs.Add(song); } catch (AggregateException e) { Logger.Instance.Error(e.Message); Logger.Instance.Warning("One common cause of this is incorrect case sensitivity in the song's json file in comparison to its actual song name."); } }
static int GetPreferredDifficulty(CustomSongInfo _song) { int difficulty = 0; foreach (CustomSongInfo.DifficultyLevel diff in _song.difficultyLevels) { if ((int)Enum.Parse(typeof(Difficulty), diff.difficulty, true) <= (int)Settings.Instance.Server.PreferredDifficulty && (int)Enum.Parse(typeof(Difficulty), diff.difficulty, true) >= difficulty) { difficulty = (int)Enum.Parse(typeof(Difficulty), diff.difficulty, true); } } if (difficulty == 0 && _song.difficultyLevels.Length > 0) { difficulty = (int)Enum.Parse(typeof(Difficulty), _song.difficultyLevels[0].difficulty, true); } return(difficulty); }
void ServerLoop() { Stopwatch _timer = new Stopwatch(); _timer.Start(); int _timerSeconds = 0; TimeSpan _lastTime = new TimeSpan(); float lobbyTimer = 0; float sendTimer = 0; float sendTime = 1f / 20; int lobbyTime = Settings.Instance.Server.LobbyTime; TimeSpan deltaTime; while (ServerLoopThread.IsAlive) { deltaTime = (_timer.Elapsed - _lastTime); _lastTime = _timer.Elapsed; try { switch (serverState) { case ServerState.Preparing: case ServerState.Voting: { sendTimer += (float)deltaTime.TotalSeconds; lobbyTimer += (float)deltaTime.TotalSeconds; if (clients.Count == 0) { lobbyTimer = 0; } if (Math.Ceiling(lobbyTimer) > _timerSeconds && _timerSeconds > -1) { _timerSeconds = Math.Ceiling(lobbyTimer); SendToAllClients( new ServerCommand(ServerCommandType.SetLobbyTimer, Math.Max(lobbyTime - _timerSeconds, 0))); } if (sendTimer >= sendTime) { SendToAllClients(new ServerCommand( ServerCommandType.SetPlayerInfos, _playerInfos: (clients.Where(x => x != null && x.playerInfo != null) .Select(x => JsonConvert.SerializeObject(x.playerInfo))).ToArray() )); sendTimer = 0f; } if (currentSongIndex == -1 && availableSongs.Count > 0) { switch (Settings.Instance.AvailableSongs.SongOrder) { case Settings.SongOrder.Voting: { if (lobbyTimer >= lobbyTime / 2) { if (clients.Any(x => x.votedFor != null)) { string selectedLevelId = clients.Where(x => x.votedFor != null).Select(x => x.votedFor).GroupBy(v => v).OrderByDescending(g => g.Count()).First().Key.levelId; CustomSongInfo song = availableSongs.FirstOrDefault(x => x.levelId == selectedLevelId); if (song != null) { currentSongIndex = availableSongs.IndexOf(song); } else { currentSongIndex = lastSelectedSong + 1; } } else { currentSongIndex = lastSelectedSong + 1; } } }; break; case Settings.SongOrder.Shuffle: { Random rand = new Random(); currentSongIndex = rand.Next(availableSongs.Count); if (currentSongIndex == lastSelectedSong) { currentSongIndex = lastSelectedSong + 1; } }; break; case Settings.SongOrder.List: { currentSongIndex = lastSelectedSong + 1; }; break; case Settings.SongOrder.Manual: { serverState = ServerState.Preparing; lobbyTimer = 0; }; break; } if (currentSongIndex >= availableSongs.Count) { currentSongIndex = 0; } if (currentSongIndex != -1) { serverState = ServerState.Preparing; SendToAllClients(new ServerCommand( ServerCommandType.SetSelectedSong, _difficulty: GetPreferredDifficulty(availableSongs[currentSongIndex])), wss); Logger.Instance.Log($"Next song is {availableSongs[currentSongIndex].songName} {availableSongs[currentSongIndex].songSubName}"); } } if (lobbyTimer >= lobbyTime) { if (availableSongs.Count > 0) { SendToAllClients(new ServerCommand( ServerCommandType.StartSelectedSongLevel, _difficulty: GetPreferredDifficulty(availableSongs[currentSongIndex])), wss); serverState = ServerState.Playing; Logger.Instance.Log("Starting song " + availableSongs[currentSongIndex].songName + " " + availableSongs[currentSongIndex].songSubName + "..."); } _timerSeconds = 0; lobbyTimer = 0; } }; break; case ServerState.Playing: { sendTimer += (float)deltaTime.TotalSeconds; playTime += deltaTime; if (sendTimer >= sendTime) { SendToAllClients(new ServerCommand( ServerCommandType.SetPlayerInfos, _playerInfos: (clients.Where(x => x.playerInfo != null) .OrderByDescending(x => x.playerInfo.playerScore) .Select(x => JsonConvert.SerializeObject(x.playerInfo))).ToArray(), _selectedSongDuration: availableSongs[currentSongIndex].duration.TotalSeconds, _selectedSongPlayTime: playTime.TotalSeconds), wss); sendTimer = 0f; } if (playTime.TotalSeconds >= availableSongs[currentSongIndex].duration.TotalSeconds + 15f) { playTime = new TimeSpan(); sendTimer = 0f; serverState = ServerState.Voting; lastSelectedSong = currentSongIndex; currentSongIndex = -1; Logger.Instance.Log("Returning to lobby..."); SendToAllClients(new ServerCommand(ServerCommandType.SetServerState)); } if (clients.Count(x => x.state == ClientState.Playing) == 0 && playTime.TotalSeconds > 5 && playTime.TotalSeconds <= availableSongs[currentSongIndex].duration.TotalSeconds - 10f) { playTime = new TimeSpan(); sendTimer = 0f; serverState = ServerState.Voting; lastSelectedSong = currentSongIndex; currentSongIndex = -1; Logger.Instance.Log("Returning to lobby (NO PLAYERS)..."); SendToAllClients(new ServerCommand(ServerCommandType.SetServerState)); } }; break; } Console.Title = string.Format(TitleFormat, Settings.Instance.Server.ServerName, clients.Count); }catch (Exception e) { Logger.Instance.Error($"Server loop exception: {e}"); } Thread.Sleep(5); } }
void ClientLoop() { int pingTimer = 0; Logger.Instance.Log("Client connected!"); if (Misc.Settings.Instance.Server.MaxPlayers != 0) { if (Misc.Settings.Instance.Server.MaxPlayers < ServerMain.clients.Count) { KickClient("Too many players"); return; } } while (_clientLoopThread.IsAlive) { try { if (_client != null && _client.Connected) { clientIP = ((IPEndPoint)_client.Client.RemoteEndPoint).Address.ToString(); pingTimer++; if (pingTimer > 180) { SendToClient(new ServerCommand(ServerCommandType.Ping)); pingTimer = 0; } string[] commands = ReceiveFromClient(); if (commands != null) { foreach (string data in commands) { ClientCommand command = JsonConvert.DeserializeObject <ClientCommand>(data); Version clientVersion = new Version(command.version); if (clientVersion.Major != ServerMain.serverVersion.Major || clientVersion.Minor != ServerMain.serverVersion.Minor || clientVersion.Build != ServerMain.serverVersion.Build) { state = ClientState.UpdateRequired; SendToClient(new ServerCommand(ServerCommandType.UpdateRequired)); DestroyClient(); } if (state != ClientState.Playing && state != ClientState.Connected) { state = ClientState.Connected; } switch (command.commandType) { case ClientCommandType.SetPlayerInfo: { PlayerInfo receivedPlayerInfo = JsonConvert.DeserializeObject <PlayerInfo>(command.playerInfo); if (receivedPlayerInfo != null) { if (ServerMain.serverState == ServerState.Playing) { state = ClientState.Playing; } if (playerId == 0) { playerId = receivedPlayerInfo.playerId; if (!ServerMain.clients.Contains(this)) { ServerMain.clients.Add(this); Logger.Instance.Log("New player: " + receivedPlayerInfo.playerName); } } else if (playerId != receivedPlayerInfo.playerId) { return; } if (playerName == null) { playerName = receivedPlayerInfo.playerName; } else if (playerName != receivedPlayerInfo.playerName) { return; } playerScore = receivedPlayerInfo.playerScore; playerInfo = receivedPlayerInfo; if (Misc.Settings.Instance.Access.Blacklist.Contains(receivedPlayerInfo.playerId.ToString()) || Misc.Settings.Instance.Access.Blacklist.Contains(clientIP)) { KickClient(); return; } if (Misc.Settings.Instance.Access.WhitelistEnabled && !Misc.Settings.Instance.Access.Whitelist.Contains(receivedPlayerInfo.playerId.ToString()) && !Misc.Settings.Instance.Access.Whitelist.Contains(clientIP)) { KickClient(); return; } } } ; break; case ClientCommandType.GetServerState: { if (ServerMain.serverState != ServerState.Playing) { SendToClient(new ServerCommand(ServerCommandType.SetServerState)); } else { SendToClient(new ServerCommand( ServerCommandType.SetServerState, _selectedSongDuration: ServerMain.availableSongs[ServerMain.currentSongIndex].duration.TotalSeconds, _selectedSongPlayTime: ServerMain.playTime.TotalSeconds)); } } ; break; case ClientCommandType.GetAvailableSongs: { SendToClient(new ServerCommand( ServerCommandType.DownloadSongs, _songs: ServerMain.availableSongs.Select(x => x.levelId).ToArray())); }; break; case ClientCommandType.VoteForSong: { if (ServerMain.serverState == ServerState.Voting) { votedFor = ServerMain.availableSongs.FirstOrDefault(x => x.levelId.Substring(0, 32) == command.voteForLevelId.Substring(0, 32)); } }; break; } } } while (sendQueue.Count != 0) { SendToClient(sendQueue.Dequeue()); } } else { if ((ServerMain.serverState == ServerState.Playing && ServerMain.playTime.TotalSeconds <= ServerMain.availableSongs[ServerMain.currentSongIndex].duration.TotalSeconds - 10f) || ServerMain.serverState != ServerState.Playing) { DestroyClient(); return; } } }catch (Exception e) { Logger.Instance.Warning($"CLIENT EXCEPTION: {e}"); } Thread.Sleep(8); } }