using Microsoft.Extensions.DependencyInjection; using PUSG.Web.Extensions; using PUSG.Web.Models; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace PUSG.Web.Services { public class GameService : IGameService { private ConcurrentDictionary sessions; private ConcurrentDictionary loops; private ConcurrentDictionary loopCancellationTokens; private IServiceProvider serviceProvider; public GameService(IServiceProvider serviceProvider) { // Key - Socket Id (client), Value - Game Session this.sessions = new ConcurrentDictionary(); this.loops = new ConcurrentDictionary(); this.loopCancellationTokens = new ConcurrentDictionary(); this.Waiting = new List(); this.PlayerUsernames = new ConcurrentDictionary(); this.OtherPlayer = new ConcurrentDictionary(); this.PlayerColor = new ConcurrentDictionary(); this.serviceProvider = serviceProvider; } public List Waiting { get; } public ConcurrentDictionary PlayerUsernames { get; } public ConcurrentDictionary OtherPlayer { get; } public ConcurrentDictionary PlayerColor { get; } public async Task CreateGameSession(string blueClientId, string redClientId) { GameSession gameSession = new GameSession(); gameSession.BluePlayer = new Player { X = 50, Y = 384, Direction = "right", Color = "blue", Type = "basic" }; gameSession.RedPlayer = new Player { X = 1266, Y = 384, Direction = "left", Color = "red", Type = "basic" }; this.sessions[blueClientId] = gameSession; this.sessions[redClientId] = gameSession; this.OtherPlayer[blueClientId] = redClientId; this.OtherPlayer[redClientId] = blueClientId; this.PlayerColor[blueClientId] = "blue"; this.PlayerColor[redClientId] = "red"; CancellationTokenSource tokenSource = new CancellationTokenSource(); CancellationToken token = tokenSource.Token; GameLoopService gameLoop = this.serviceProvider.CreateScope().ServiceProvider.GetRequiredService(); this.loops[blueClientId] = gameLoop; this.loops[redClientId] = gameLoop; this.loopCancellationTokens[blueClientId] = token; this.loopCancellationTokens[redClientId] = token; gameLoop.GameSession = gameSession; await gameLoop.StartAsync(token); } public async Task DestroyGameSession(string clientId) { string otherClientId = this.OtherPlayer.ContainsKey(clientId) ? this.OtherPlayer[clientId] : null; await this.loops[clientId].StopAsync(this.loopCancellationTokens[clientId]); this.loops[clientId].Dispose(); this.loops.Delete(clientId); this.sessions.Delete(clientId); this.PlayerUsernames.Delete(clientId); this.PlayerColor.Delete(clientId); this.loopCancellationTokens.Delete(clientId); this.OtherPlayer.Delete(clientId); if (otherClientId != null) { this.loops.Delete(otherClientId); this.sessions.Delete(otherClientId); this.PlayerUsernames.Delete(otherClientId); this.PlayerColor.Delete(otherClientId); this.loopCancellationTokens.Delete(otherClientId); this.OtherPlayer.Delete(otherClientId); } } public GameSession this[string clientId] { get { return this.sessions.ContainsKey(clientId) ? this.sessions[clientId] : null; } set { this.sessions[clientId] = value; } } public void Shoot(string clientId) { this.sessions[clientId].Shoot(this.PlayerColor[clientId]); } public void MoveUp(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].MoveUp(); } public void MoveRight(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].MoveRight(); } public void MoveDown(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].MoveDown(); } public void MoveLeft(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].MoveLeft(); } public void RotateLeft(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].RotateLeft(); } public void RotateRight(string clientId) { this.sessions[clientId][this.PlayerColor[clientId]].RotateRight(); } } }