using System; using System.Collections.Generic; using System.Net.WebSockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace gameapi.Library { public class GameState { public static GameState instance; public static GameState GetInstance() { if (GameState.instance == null) { GameState.instance = new GameState(); } return GameState.instance; } private Dictionary players; private Dictionary, List> channels; public GameState() { this.players = new Dictionary(); } public async Task EnterSector(Player player, Tuple sector) { var leaveMessage = string.Format("leave {0}", player.GetKey()); await this.MessageAllOtherPlayersInSector(player, leaveMessage); player.SetSector(sector); //TODO: get valid location in sector to enter player.SetPosition(5000, 5000); var joinMessage = string.Format("join {0}", player.GetShipData()); await this.MessageAllOtherPlayersInSector(player, joinMessage); } public List GetAllPlayers() { List allPlayers = new List(); allPlayers.AddRange(this.players.Values); return allPlayers; } public List GetSectorPopulation(Tuple sector, Player exclude = null) { var playersInSector = new List(); foreach (var kvp in this.players) { if (exclude != null && kvp.Key.Equals(exclude.GetKey())) { continue; } if (kvp.Value.GetSector().Equals(sector)) { playersInSector.Add(kvp.Value); } } return playersInSector; } public async Task MessageAllPlayers(string message) { List messagesToSend = new List(); foreach (var player in this.players) { messagesToSend.Add(this.MessagePlayer(player.Value, message)); } await Task.WhenAll(messagesToSend); } public async Task MessageAllPlayersInSector(Player fromPlayer, string message) { List messagesToSend = new List(); var playersInSector = this.GetSectorPopulation(fromPlayer.GetSector()); await this.MessagePlayers(playersInSector, message); } public async Task MessageAllPlayersInSector(Tuple sector, string message) { List messagesToSend = new List(); var playersInSector = this.GetSectorPopulation(sector); await this.MessagePlayers(playersInSector, message); } public async Task MessageAllOtherPlayersInSector(Player fromPlayer, string message) { List messagesToSend = new List(); var playersInSector = this.GetSectorPopulation(fromPlayer.GetSector(), fromPlayer); await this.MessagePlayers(playersInSector, message); } public async Task MessagePlayers(IEnumerable playersToMessage, string message) { List messagesToSend = new List(); foreach (var player in playersToMessage) { messagesToSend.Add(this.MessagePlayer(player, message)); } await Task.WhenAll(messagesToSend.ToArray()); } public Player GetPlayerBySocket(WebSocket webSocket) { return this.players.GetValueOrDefault("" + webSocket.GetHashCode(), null); } public void AddPlayer(WebSocket socket) { var player = new Player(socket); this.players.Add("" + socket.GetHashCode(), player); } public async Task MessagePlayer(Player player, string message) { var connection = player.GetConnection(); if (connection.State == WebSocketState.Open) { await connection.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(message), 0, message.Length), WebSocketMessageType.Text, true, CancellationToken.None); } } internal IEnumerable GetPlayers() { return this.players.Values; } } }