public async Task <IActionResult> FireCannon([FromBody] P2PFireCannonDto dto) { if (string.IsNullOrWhiteSpace(dto.ConnectionId)) { return(BadRequest()); } if (string.IsNullOrWhiteSpace(dto.Code)) { return(BadRequest()); } PeerToPeerSessionState session = await _p2pSvc.FindActiveSessionAsync(dto.Code, dto.ConnectionId); if (session == null) { return(BadRequest()); } var connectionId = dto.ConnectionId == session.HostConnectionId ? session.FriendConnectionId : session.HostConnectionId; FireCannonDto srDto = new FireCannonDto { GameId = session.GameId, CellId = dto.CellId }; await _gameHubContext.Clients.Client(connectionId).SendAsync("MakeFireFromServer", srDto); return(Ok(new { })); }
public async Task <IActionResult> RestartGame([FromBody] P2PGameKeyDto dto) { if (string.IsNullOrWhiteSpace(dto.Code)) { return(BadRequest()); } if (string.IsNullOrWhiteSpace(dto.ConnectionId)) { return(BadRequest()); } PeerToPeerSessionState session = await _p2pSvc.FindActiveSessionAsync(dto.Code, dto.ConnectionId); if (session == null) { return(BadRequest()); } //only host can restart game for now if (dto.ConnectionId != session.HostConnectionId) { return(BadRequest()); } session = await _p2pSvc.RestartGameAsync(session); await _gameHubContext.Clients.Client(session.FriendConnectionId).SendAsync("RestartGame"); return(Ok(new { })); }
public async Task RestartGame_Ok() { var p2pSvc = new Mock <IPeerToPeerGameService>(); var session = new PeerToPeerSessionState() { Code = "12345", HostConnectionId = "c1", }; p2pSvc.Setup(x => x.FindActiveSessionAsync(It.IsAny <string>(), It.IsAny <string>())) .ReturnsAsync(session); p2pSvc.Setup(x => x.RestartGameAsync(It.IsAny <PeerToPeerSessionState>())) .ReturnsAsync(session); var controller = new PeerToPeerGameController(p2pSvc.Object, _mapper, _signalRHub.Object, _logger.Object); var output = await controller.RestartGame(new P2PGameKeyDto { Code = "12345", ConnectionId = "c1" }); p2pSvc.Verify(p => p.FindActiveSessionAsync(It.IsAny <string>(), It.IsAny <string>()), Times.Once); p2pSvc.Verify(p => p.RestartGameAsync(It.IsAny <PeerToPeerSessionState>()), Times.Once); _signalRHub.VerifyGet(p => p.Clients, Times.Once); Assert.AreEqual(output.GetType(), typeof(OkObjectResult)); }
public async Task <PeerToPeerSessionState> UpdateP2PSessionAsync(PeerToPeerSessionState p2pSession) { //TODO: Implement await Task.FromResult(0); throw new NotImplementedException(); }
public virtual async Task <PeerToPeerSessionState> StartNewGameAsync(PeerToPeerSessionState session) { PeerToPeerGameState game = PeerToPeerGameState.CreateNew(); session.GameId = game.GameId; game = await _storage.AddP2PGameAsync(game); return(await _storage.UpdateP2PSessionAsync(session)); }
public async Task StartNewSessionAsync_Ok() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); _storage.Setup(p => p.AddP2PSessionAsync(It.IsAny <PeerToPeerSessionState>())).ReturnsAsync(new PeerToPeerSessionState()); PeerToPeerSessionState res = await svc.StartNewSessionAsync("connectionId"); _storage.Verify(p => p.AddP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Once); Assert.IsNotNull(res); }
public async Task <PeerToPeerSessionState> StartNewSessionAsync(string hostConnectionId) { //fallback afer 1000 tries if game is super popular :) string code = await GenerateCode() ?? hostConnectionId; PeerToPeerSessionState session = new PeerToPeerSessionState() { HostConnectionId = hostConnectionId, Code = code }; return(await _storage.AddP2PSessionAsync(session)); }
public async Task <IActionResult> StartSession([FromBody] string connectionId) { if (string.IsNullOrWhiteSpace(connectionId)) { return(BadRequest()); } PeerToPeerSessionState g = await _p2pSvc.StartNewSessionAsync(connectionId); return(Ok(new P2PStartSessionDto { Code = g.Code })); }
public async Task RestartGameAsync() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); PeerToPeerSessionState session = new PeerToPeerSessionState(); _storage.Setup(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>())).ReturnsAsync(session); PeerToPeerSessionState res = await svc.RestartGameAsync(session); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Once); Assert.IsNotNull(res); }
public async Task AddPeerToSession_SessionNotFound() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); _storage.Setup(p => p.FindP2PSessionAsync(It.IsAny <string>())).ReturnsAsync((PeerToPeerSessionState)null); PeerToPeerSessionState res = await svc.AddPeerToSession("code", "FriendConnectionId", new List <ShipInfo>()); _storage.Verify(p => p.FindP2PSessionAsync(It.IsAny <string>()), Times.Once); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Never); Assert.IsNull(res); }
public async Task AddPeerToSession_GameAlreadyJoinedByAll() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); var session = new PeerToPeerSessionState() { Code = "code", HostConnectionId = "HostConnectionId", FriendConnectionId = "FriendConnectionId", GameStartedCount = 2, }; _storage.Setup(p => p.FindP2PSessionAsync(It.IsAny <string>())).ReturnsAsync(session); PeerToPeerSessionState res = await svc.AddPeerToSession("code", "FriendConnectionId", new List <ShipInfo>()); }
public async Task <PeerToPeerSessionState> FindActiveSessionAsync(string code, string connectionId) { PeerToPeerSessionState session = await _storage.FindP2PSessionAsync(code); if (session == null) { return(null); } if (session.HostConnectionId == connectionId || session.FriendConnectionId == connectionId) { return(session); } return(null); }
public async Task <PeerToPeerSessionState> AddPeerToSession(string code, string connectionId, IEnumerable <ShipInfo> ships) { PeerToPeerSessionState s = await _storage.FindP2PSessionAsync(code); if (s == null) { return(null); } //game already started by both peers if (s.GameStartedCount == 2) { throw new InvalidOperationException("Game already has 2 participants"); } if (s.HostConnectionId == connectionId && s.HostStartedGame) { throw new InvalidOperationException("Host already started game"); } if (s.FriendConnectionId == connectionId && s.FriendStartedGame) { throw new InvalidOperationException("Friend already started game"); } if (s.HostConnectionId == connectionId || s.FriendConnectionId == connectionId) { if (s.HostConnectionId == connectionId) { s.HostStartedGame = true; s.HostShips = new List <ShipInfo>(ships); } else if (s.FriendConnectionId == connectionId) { s.FriendStartedGame = true; s.FriendShips = new List <ShipInfo>(ships); } s.GameStartedCount++; s = await _storage.UpdateP2PSessionAsync(s); return(s); } return(null); }
public async Task JoinSessionAsync_FriendAlreadyConnected() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); _storage.Setup(p => p.FindP2PSessionAsync(It.IsAny <string>())).ReturnsAsync(new PeerToPeerSessionState() { FriendConnectionId = "connectionId" }); _storage.Setup(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>())).ReturnsAsync(new PeerToPeerSessionState()); PeerToPeerSessionState res = await svc.JoinSessionAsync("code", "connectionId"); _storage.Verify(p => p.FindP2PSessionAsync(It.IsAny <string>()), Times.Once); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Never); Assert.IsNull(res); }
public async Task <IActionResult> FireCannonProcessResult([FromBody] P2PFireCannonCallbackDto dto) { if (string.IsNullOrWhiteSpace(dto.ConnectionId)) { return(BadRequest()); } if (string.IsNullOrWhiteSpace(dto.Code)) { return(BadRequest()); } PeerToPeerSessionState session = await _p2pSvc.FindActiveSessionAsync(dto.Code, dto.ConnectionId); if (session == null) { return(BadRequest()); } List <ShipInfo> ships = dto.ConnectionId == session.HostConnectionId ? session.FriendShips : session.HostShips; FireCannonResultDto respDto = new FireCannonResultDto { CellId = dto.CellId, ShipDestroyed = dto.ShipDestroyed, IsAwaitingServerTurn = !dto.Result, IsGameOver = dto.IsGameOver, Result = dto.Result, }; var connectionId = dto.ConnectionId == session.HostConnectionId ? session.FriendConnectionId : session.HostConnectionId; await _gameHubContext.Clients.Client(connectionId).SendAsync("MakeFireProcessResult", respDto); if (dto.IsGameOver) { await _p2pSvc.StopGameAsync(session); GameOverDto shipsDto = new GameOverDto { Ships = ships.Select(s => s.Cells).ToList() }; return(Ok(shipsDto)); } return(Ok(new { })); }
public virtual async Task <PeerToPeerSessionState> StopGameAsync(PeerToPeerSessionState session) { PeerToPeerGameState game = await FindActiveP2PGameAsync(session.GameId); if (game == null) { return(null); } game.DateEnd = DateTime.Now; await _storage.UpdateP2PGameAsync(game); session.PreviousGames.Add(session.GameId); session.GameId = null; return(await _storage.UpdateP2PSessionAsync(session)); }
/// <summary> /// Cleanup old objects from memory storage /// </summary> /// <returns></returns> public Task Cleanup() { DateTime now = DateTime.Now; if (_games.Count > 500) { foreach (string key in _games.Keys) { GameState g = _games[key]; TimeSpan ts = now - g.LastUpdated; if (ts.TotalHours >= HoursToLive) { _games.TryRemove(key, out _); } } } if (_p2pGames.Count > 500) { foreach (string key in _p2pGames.Keys) { PeerToPeerGameState g = _p2pGames[key]; TimeSpan ts = now - g.LastUpdated; if (ts.TotalHours >= HoursToLive) { _p2pGames.TryRemove(key, out _); } } } if (_p2pSessions.Count > 500) { foreach (string key in _p2pSessions.Keys) { PeerToPeerSessionState g = _p2pSessions[key]; TimeSpan ts = now - g.LastUpdated; if (ts.TotalHours >= HoursToLive) { _p2pSessions.TryRemove(key, out _); } } } return(Task.FromResult(0)); }
public async Task StopGameAsync() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); PeerToPeerGameState game = PeerToPeerGameState.CreateNew(); PeerToPeerSessionState session = new PeerToPeerSessionState(); _storage.Setup(p => p.FindActiveP2PGameAsync(It.IsAny <string>())).ReturnsAsync(game); _storage.Setup(p => p.UpdateP2PGameAsync(It.IsAny <PeerToPeerGameState>())).ReturnsAsync(game); _storage.Setup(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>())).ReturnsAsync(session); PeerToPeerSessionState res = await svc.StopGameAsync(session); _storage.Verify(p => p.FindActiveP2PGameAsync(It.IsAny <string>()), Times.Once); _storage.Verify(p => p.UpdateP2PGameAsync(It.IsAny <PeerToPeerGameState>()), Times.Once); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Once); Assert.IsNotNull(res); }
public async Task <PeerToPeerSessionState> JoinSessionAsync(string code, string connectionId) { PeerToPeerSessionState session = await _storage.FindP2PSessionAsync(code); if (session == null) { return(null); } //if friend already joined. if (!string.IsNullOrWhiteSpace(session.FriendConnectionId)) { return(null); } session.FriendConnectionId = connectionId; return(await _storage.UpdateP2PSessionAsync(session)); }
public async Task AddPeerToSession_WrongConnectionId() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); var session = new PeerToPeerSessionState() { Code = "code", HostConnectionId = "HostConnectionId", FriendConnectionId = "FriendConnectionId", }; _storage.Setup(p => p.FindP2PSessionAsync(It.IsAny <string>())).ReturnsAsync(session); PeerToPeerSessionState res = await svc.AddPeerToSession("code", "WrongConnectionId", new List <ShipInfo>()); _storage.Verify(p => p.FindP2PSessionAsync(It.IsAny <string>()), Times.Once); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Never); Assert.IsNull(res); }
public async Task CleanupTest() { InMemoryStaticStorage s = new InMemoryStaticStorage { HoursToLive = 0 }; //clean results of older runs await s.Cleanup(); for (int i = 0; i < 1000; i++) { var game = PeerToPeerGameState.CreateNew(); await s.AddP2PGameAsync(game); } for (int i = 0; i < 1000; i++) { var session = new PeerToPeerSessionState() { Code = i.ToString(), }; await s.AddP2PSessionAsync(session); } for (int i = 0; i < 1000; i++) { var game = new GameState { GameId = Guid.NewGuid().ToString() }; await s.AddGameAsync(game); } await s.Cleanup(); Assert.AreEqual(0, s.PeerToPeerGamesCount); Assert.AreEqual(0, s.PeerToPeerSessionsCount); Assert.AreEqual(0, s.GamesCount); }
private async Task <string> GenerateCode() { Random rnd = new Random(); int i = 0; while (i < 1000) { int num = rnd.Next(0, 9999); string code = num.ToString().PadLeft(4, '0'); //if session not found - code OK. Otherwise generate new code PeerToPeerSessionState s = await _storage.FindP2PSessionAsync(code); if (s == null) { return(code); } ++i; } return(null); }
public async Task <IActionResult> JoinSession([FromBody] P2PGameKeyDto dto) { if (string.IsNullOrWhiteSpace(dto.ConnectionId)) { return(BadRequest()); } PeerToPeerSessionState g = await _p2pSvc.JoinSessionAsync(dto.Code, dto.ConnectionId); if (g == null) { return(BadRequest()); } if (dto.ConnectionId == g.HostConnectionId) { return(BadRequest()); } await _gameHubContext.Clients.Client(g.HostConnectionId).SendAsync("FriendConnected"); return(Ok(new { })); }
public async Task AddPeerToSession_HostAdded() { PeerToPeerGameService svc = new PeerToPeerGameService(_storage.Object); var session = new PeerToPeerSessionState() { Code = "code", HostConnectionId = "HostConnectionId", FriendConnectionId = "FriendConnectionId" }; _storage.Setup(p => p.FindP2PSessionAsync(It.IsAny <string>())).ReturnsAsync(session); _storage.Setup(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>())).ReturnsAsync(session); PeerToPeerSessionState res = await svc.AddPeerToSession("code", "HostConnectionId", new List <ShipInfo>()); _storage.Verify(p => p.FindP2PSessionAsync(It.IsAny <string>()), Times.Once); _storage.Verify(p => p.UpdateP2PSessionAsync(It.IsAny <PeerToPeerSessionState>()), Times.Once); Assert.IsNotNull(res); Assert.IsTrue(session.HostStartedGame); Assert.AreEqual(1, session.GameStartedCount); Assert.IsNotNull(session.HostShips); }
public Task <PeerToPeerSessionState> FindP2PSessionAsync(string code) { PeerToPeerSessionState p2pSession = _p2pSessions.FirstOrDefault(u => u.Key == code).Value; return(Task.FromResult(p2pSession)); }
public Task <PeerToPeerSessionState> UpdateP2PSessionAsync(PeerToPeerSessionState p2pSession) { p2pSession.LastUpdated = DateTime.Now; p2pSession = _p2pSessions.AddOrUpdate(p2pSession.Code, p2pSession, (key, val) => p2pSession); return(Task.FromResult(p2pSession)); }
public async Task <IActionResult> StartNewGame([FromBody] P2PNewGametDto dto) { if (string.IsNullOrWhiteSpace(dto.ConnectionId)) { return(BadRequest()); } if (string.IsNullOrWhiteSpace(dto.Code)) { return(BadRequest()); } if (dto.Ships == null || dto.Ships.Length != 10) { return(BadRequest()); } PeerToPeerSessionState session = null; try { session = await _p2pSvc.AddPeerToSession(dto.Code, dto.ConnectionId, _mapper.Map <IEnumerable <ShipInfo> >(dto.Ships)); } catch (Exception e) { _logger.LogError(e, e.Message); } if (session == null) { return(BadRequest()); } if (session.HostConnectionId == session.FriendConnectionId) { return(BadRequest()); } if (session.GameStartedCount == 2) { //TODO: Implement add board to Game and track battle history session = await _p2pSvc.StartNewGameAsync(session); var connectionId = dto.ConnectionId == session.HostConnectionId ? session.FriendConnectionId : session.HostConnectionId; await _gameHubContext.Clients.Client(connectionId).SendAsync("GameStartedYourMove", new P2PNewGameResultDto { GameId = session.GameId, YourMove = true }); await _gameHubContext.Clients.Client(dto.ConnectionId).SendAsync("GameStartedFriendsMove", new P2PNewGameResultDto { GameId = session.GameId, YourMove = false }); } else { var connectionId = dto.ConnectionId == session.HostConnectionId ? session.FriendConnectionId : session.HostConnectionId; await _gameHubContext.Clients.Client(connectionId).SendAsync("FriendStartedGame"); await _gameHubContext.Clients.Client(dto.ConnectionId).SendAsync("YouStartedGame"); } return(Ok(new { })); }
public Task <PeerToPeerSessionState> AddP2PSessionAsync(PeerToPeerSessionState p2pSession) { p2pSession.LastUpdated = DateTime.Now; p2pSession = _p2pSessions.GetOrAdd(p2pSession.Code, p2pSession); return(Task.FromResult(p2pSession)); }
public async Task <PeerToPeerSessionState> RestartGameAsync(PeerToPeerSessionState session) { session.Reset(); return(await _storage.UpdateP2PSessionAsync(session)); }