Added endpoint for creating and joining a game
This commit is contained in:
parent
7e8dc44ce9
commit
65b69a763f
@ -65,7 +65,7 @@ public class ActionServiceTests
|
||||
[Test]
|
||||
public void RollDice_ReturnsListOfIntegers()
|
||||
{
|
||||
_service.Group = new pacMan.Services.Game(new Queue<DirectionalPosition>());
|
||||
_service.Game = new pacMan.Services.Game(new Queue<DirectionalPosition>());
|
||||
var dices = _service.RollDice();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
@ -182,7 +182,7 @@ public class ActionServiceTests
|
||||
{
|
||||
var group = new pacMan.Services.Game(new Queue<DirectionalPosition>())
|
||||
{ Players = { _blackPlayer, _whitePlayer } };
|
||||
_service.Group = group;
|
||||
_service.Game = group;
|
||||
_service.Player = _blackPlayer;
|
||||
|
||||
var result = _service.Ready();
|
||||
@ -204,14 +204,14 @@ public class ActionServiceTests
|
||||
[Test]
|
||||
public void FindNextPlayer_NoPlayers()
|
||||
{
|
||||
_service.Group = new pacMan.Services.Game(new Queue<DirectionalPosition>());
|
||||
_service.Game = new pacMan.Services.Game(new Queue<DirectionalPosition>());
|
||||
Assert.Throws<InvalidOperationException>(() => _service.FindNextPlayer());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FindNextPlayer_OnePlayer()
|
||||
{
|
||||
_service.Group =
|
||||
_service.Game =
|
||||
new pacMan.Services.Game(new Queue<DirectionalPosition>(
|
||||
new[] { new DirectionalPosition { At = new Position { X = 3, Y = 3 }, Direction = Direction.Up } }))
|
||||
{ Players = { _whitePlayer } };
|
||||
@ -223,7 +223,7 @@ public class ActionServiceTests
|
||||
[Test]
|
||||
public void FindNextPlayer_TwoPlayers()
|
||||
{
|
||||
_service.Group = new pacMan.Services.Game(new Queue<DirectionalPosition>(
|
||||
_service.Game = new pacMan.Services.Game(new Queue<DirectionalPosition>(
|
||||
new[]
|
||||
{
|
||||
new DirectionalPosition { At = new Position { X = 3, Y = 3 }, Direction = Direction.Up },
|
||||
|
@ -18,6 +18,7 @@ const NavMenu: Component = () => {
|
||||
<ul className="navbar-nav flex-grow">
|
||||
<Link className="text-dark" to="/">Home</Link>
|
||||
<Link className="text-dark" to="/counter">Counter</Link>
|
||||
<Link to={"/lobby"}>Lobby</Link>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, {useEffect} from "react";
|
||||
import React, {FC, useEffect} from "react";
|
||||
import {GameComponent} from "../components/gameComponent";
|
||||
import {useAtomValue} from "jotai";
|
||||
import {thisPlayerAtom} from "../utils/state";
|
||||
import {testMap} from "../game/map";
|
||||
|
||||
const Game: Component = () => {
|
||||
const Game: FC = () => { // TODO gameId in path
|
||||
const player = useAtomValue(thisPlayerAtom);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,13 +1,14 @@
|
||||
import React, {Suspense} from "react";
|
||||
import React, {FC, Suspense} from "react";
|
||||
import {atom, useAtomValue} from "jotai";
|
||||
import {Button} from "../components/Button";
|
||||
import {thisPlayerAtom} from "../utils/state";
|
||||
|
||||
const fetchAtom = atom(async () => {
|
||||
const response = await fetch(import.meta.env.VITE_API_HTTP + "/allGames");
|
||||
const response = await fetch(import.meta.env.VITE_API_HTTP + "/all");
|
||||
return await response.json() as Game[];
|
||||
});
|
||||
|
||||
const LobbyPage: Component = () => (
|
||||
// TODO create game button
|
||||
const LobbyPage: FC = () => ( // TODO check if player is defined in storage, if not redirect to login
|
||||
<Suspense fallback={"Please wait"}>
|
||||
<GameTable className={"mx-auto"}/>
|
||||
</Suspense>
|
||||
@ -18,9 +19,28 @@ export default LobbyPage;
|
||||
const GameTable: Component = ({className}) => {
|
||||
|
||||
const data = useAtomValue(fetchAtom);
|
||||
const thisPlayer = useAtomValue(thisPlayerAtom);
|
||||
|
||||
function joinGame(gameId: string): void {
|
||||
console.log("Joining game " + gameId); // TODO: Implement
|
||||
async function joinGame(gameId: string): Promise<void> {
|
||||
if (thisPlayer === undefined) throw new Error("Player is undefined");
|
||||
|
||||
console.debug("Joining game " + gameId);
|
||||
|
||||
const result = await fetch(import.meta.env.VITE_API_HTTP + "/join/" + gameId, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(thisPlayer),
|
||||
})
|
||||
|
||||
if (result.ok) {
|
||||
console.debug("Joined game " + gameId, result.body);
|
||||
// TODO redirect to game page
|
||||
} else {
|
||||
console.error("Failed to join game " + gameId, result.body);
|
||||
// TODO show error message
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System.Net.WebSockets;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using pacMan.Exceptions;
|
||||
using pacMan.GameStuff;
|
||||
using pacMan.GameStuff.Items;
|
||||
using pacMan.Services;
|
||||
using pacMan.Utils;
|
||||
|
||||
@ -23,13 +25,47 @@ public class GameController : GenericController // TODO reconnect using player i
|
||||
[HttpGet("connect")]
|
||||
public override async Task Accept() => await base.Accept();
|
||||
|
||||
[HttpGet("allGames")]
|
||||
[HttpGet("all")]
|
||||
public IEnumerable<Game> GetAllGames()
|
||||
{
|
||||
Logger.Log(LogLevel.Information, "Returning all games");
|
||||
Logger.Log(LogLevel.Debug, "Returning all games");
|
||||
return _gameService.Games;
|
||||
}
|
||||
|
||||
[HttpPost("join/{gameId}")]
|
||||
public IActionResult JoinGame(Guid gameId, [FromBody] Player player) // TODO what if player is in a game already?
|
||||
{
|
||||
Logger.Log(LogLevel.Debug, "Joining game {}", gameId);
|
||||
try
|
||||
{
|
||||
_gameService.JoinById(gameId, player);
|
||||
return Ok("Game joined successfully");
|
||||
}
|
||||
catch (GameNotFoundException e)
|
||||
{
|
||||
return NotFound(e.Message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("createGame")]
|
||||
public IActionResult CreateGame([FromBody] PlayerInfoData data)
|
||||
{
|
||||
Logger.Log(LogLevel.Debug, "Creating game");
|
||||
try
|
||||
{
|
||||
var game = _gameService.CreateAndJoin(data.Player, data.Spawns);
|
||||
return Created($"/{game.Id}", game);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return BadRequest(e.Message); // TODO not necessary?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override ArraySegment<byte> Run(WebSocketReceiveResult result, byte[] data)
|
||||
{
|
||||
@ -47,6 +83,7 @@ public class GameController : GenericController // TODO reconnect using player i
|
||||
protected override Task Echo()
|
||||
{
|
||||
_gameService.Connections += WsServiceOnFire;
|
||||
// _actionService.Game.Connections += WsServiceOnFire;
|
||||
return base.Echo();
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using pacMan.GameStuff;
|
||||
using pacMan.GameStuff.Items;
|
||||
|
||||
@ -7,7 +8,7 @@ namespace pacMan.Services;
|
||||
public interface IActionService
|
||||
{
|
||||
IPlayer Player { set; }
|
||||
Game Group { set; }
|
||||
Game Game { set; }
|
||||
void DoAction(ActionMessage message);
|
||||
List<int> RollDice();
|
||||
List<IPlayer> SetPlayerInfo(JsonElement? jsonElement);
|
||||
@ -28,7 +29,7 @@ public class ActionService : IActionService
|
||||
_gameService = gameService;
|
||||
}
|
||||
|
||||
public Game? Group { get; set; }
|
||||
public Game? Game { get; set; }
|
||||
|
||||
public IPlayer? Player { get; set; }
|
||||
|
||||
@ -47,8 +48,8 @@ public class ActionService : IActionService
|
||||
|
||||
public List<int> RollDice()
|
||||
{
|
||||
Group?.DiceCup.Roll();
|
||||
var rolls = Group?.DiceCup.Values ?? new List<int>();
|
||||
Game?.DiceCup.Roll();
|
||||
var rolls = Game?.DiceCup.Values ?? new List<int>();
|
||||
_logger.Log(LogLevel.Information, "Rolled [{}]", string.Join(", ", rolls));
|
||||
|
||||
return rolls;
|
||||
@ -66,27 +67,27 @@ public class ActionService : IActionService
|
||||
{
|
||||
player.State = group.IsGameStarted ? State.InGame : State.WaitingForPlayers;
|
||||
Player = player;
|
||||
Group = group;
|
||||
Game = group;
|
||||
// TODO send missing data: Dices, CurrentPlayer, Ghosts
|
||||
}
|
||||
else
|
||||
{
|
||||
Group = _gameService.AddPlayer(Player, data.Spawns);
|
||||
Game = _gameService.AddPlayer(Player, data.Spawns);
|
||||
}
|
||||
|
||||
return Group.Players;
|
||||
return Game.Players;
|
||||
}
|
||||
|
||||
public object Ready()
|
||||
{
|
||||
object data;
|
||||
if (Player != null && Group != null)
|
||||
if (Player != null && Game != null)
|
||||
{
|
||||
var players = Group.SetReady(Player).ToArray();
|
||||
var players = Game.SetReady(Player).ToArray();
|
||||
// TODO roll to start
|
||||
Group.Shuffle();
|
||||
Game.Shuffle();
|
||||
var allReady = players.All(p => p.State == State.Ready);
|
||||
if (allReady) Group.SetAllInGame();
|
||||
if (allReady) Game.SetAllInGame();
|
||||
data = new ReadyData { AllReady = allReady, Players = players };
|
||||
}
|
||||
else
|
||||
@ -97,7 +98,7 @@ public class ActionService : IActionService
|
||||
return data;
|
||||
}
|
||||
|
||||
public string FindNextPlayer() => Group?.NextPlayer().UserName ?? "Error: No group found";
|
||||
public string FindNextPlayer() => Game?.NextPlayer().UserName ?? "Error: No group found";
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
@ -106,9 +107,9 @@ public class ActionService : IActionService
|
||||
|
||||
public object? HandleMoveCharacter(JsonElement? jsonElement)
|
||||
{
|
||||
if (Group != null && jsonElement.HasValue)
|
||||
Group.Ghosts = jsonElement.Value.GetProperty("Ghosts").Deserialize<List<Character>>() ??
|
||||
throw new JsonException("Ghosts is null");
|
||||
if (Game != null && jsonElement.HasValue)
|
||||
Game.Ghosts = jsonElement.Value.GetProperty("Ghosts").Deserialize<List<Character>>() ??
|
||||
throw new JsonException("Ghosts is null");
|
||||
|
||||
return jsonElement;
|
||||
}
|
||||
@ -116,12 +117,12 @@ public class ActionService : IActionService
|
||||
|
||||
public struct PlayerInfoData
|
||||
{
|
||||
public required Player Player { get; set; }
|
||||
public required Queue<DirectionalPosition> Spawns { get; set; }
|
||||
[JsonInclude] public required Player Player { get; init; }
|
||||
[JsonInclude] public required Queue<DirectionalPosition> Spawns { get; init; }
|
||||
}
|
||||
|
||||
public struct ReadyData
|
||||
{
|
||||
public required bool AllReady { get; init; }
|
||||
public required IEnumerable<IPlayer> Players { get; set; }
|
||||
[JsonInclude] public required bool AllReady { get; init; }
|
||||
[JsonInclude] public required IEnumerable<IPlayer> Players { get; set; }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user