Skip to content

Commit 723ff2a

Browse files
committed
add /api/create
1 parent 5e3c9ba commit 723ff2a

15 files changed

+157
-46
lines changed

src/main/client/src/Lobby.jsx

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ import {
1515
base,
1616
StompContext,
1717
} from "./util.js"
18+
import {
19+
LobbyPanel,
20+
} from "./feature/LobbyPanel.jsx"
1821
import {
1922
useAuthStore,
2023
useGameStore,
2124
} from "./store.js"
2225

2326
export function Lobby() {
2427
let [matchRequested, setMatchRequested] = useState(false)
25-
let [users, setUsers] = useState([])
2628
let stompClient = useContext(StompContext)
2729
let navigate = useNavigate()
2830
let auth = useAuthStore(state => state.auth)
@@ -37,11 +39,7 @@ export function Lobby() {
3739
let game = JSON.parse(message.body)
3840
navigate(base + "/game/" + game.id)
3941
})
40-
let sub2 = stompClient.subscribe("/topic/lobby/users", (message) => {
41-
let r = JSON.parse(message.body)
42-
setUsers(r.users)
43-
})
44-
let sub3 = stompClient.subscribe("/topic/lobby/gamerequest", (message) => {
42+
let sub2 = stompClient.subscribe("/topic/lobby/gamerequest", (message) => {
4543
let r = JSON.parse(message.body)
4644
if (r.name === auth.name) {
4745
setMatchRequested(true)
@@ -50,51 +48,44 @@ export function Lobby() {
5048
stompClient.publish({
5149
destination: "/app/lobby/hello",
5250
body: JSON.stringify({
53-
name: auth.name,
5451
}),
5552
})
5653
return () => {
5754
sub1.unsubscribe()
5855
sub2.unsubscribe()
59-
sub3.unsubscribe()
6056
}
61-
}, [setInit, setUsers, setMatchRequested, auth, initialized, stompClient, navigate])
57+
}, [setInit, setMatchRequested, auth, initialized, stompClient, navigate])
6258
let matchRequest = useCallback((editMode) => {
6359
stompClient.publish({
6460
destination: "/app/lobby/match",
6561
body: JSON.stringify({
66-
name: auth.name,
6762
dim: 9,
6863
editMode: editMode,
6964
}),
7065
})
71-
}, [auth, stompClient])
72-
if (!matchRequested) {
66+
}, [stompClient])
67+
if (matchRequested) {
7368
return (
7469
<div className="m-4">
75-
<div>
76-
<Button
77-
onClick={() => matchRequest(true)}>
78-
Create
79-
</Button>
80-
</div>
81-
<div className="mt-2">
82-
<Button
83-
onClick={() => matchRequest(false)}>
84-
Find match
85-
</Button>
86-
</div>
87-
<div className="mt-2">
88-
{users.map(user => (
89-
<div key={user.name}>{user.name}</div>
90-
))}
91-
</div>
70+
Waiting for match...
9271
</div>
9372
)
9473
}
9574
return (
9675
<div className="m-4">
97-
Waiting for match...
76+
<div>
77+
<Button
78+
onClick={() => matchRequest(true)}>
79+
Create
80+
</Button>
81+
</div>
82+
<div className="mt-2">
83+
<Button
84+
onClick={() => matchRequest(false)}>
85+
Find match
86+
</Button>
87+
</div>
88+
<LobbyPanel />
9889
</div>
9990
)
10091
}

src/main/client/src/Login.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {
22
Form,
3-
} from "./Form.jsx"
3+
} from "./component/Form.jsx"
44
import {
55
Input,
66
} from "./component/Input.jsx"
File renamed without changes.

src/main/client/src/feature/GamePanel.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const GamePanel = () => {
2424
return (
2525
<div className="fixed top-0 right-0 h-full bg-slate-800 border-l-2 border-slate-700">
2626
<div className="pr-12 pt-8 pl-8">
27-
<Panel />
27+
<Panel />
2828
</div>
2929
</div>
3030
)
@@ -56,7 +56,7 @@ function Panel() {
5656
if (!board.length) {
5757
return <span>Loading...</span>
5858
}
59-
let result = counting ? getResult(board) : undefined
59+
let result = counting ? getScore(board) : undefined
6060
return (
6161
<>
6262
<div>
@@ -96,7 +96,7 @@ function Panel() {
9696
)
9797
}
9898

99-
function getResult(board) {
99+
function getScore(board) {
100100
let w = 0, b = 0
101101
for (let y = 0; y < board.length; y++) {
102102
for (let x = 0; x < board[y].length; x++) {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import {
2+
useContext,
3+
useRef,
4+
useEffect,
5+
useState,
6+
} from "react"
7+
import {
8+
StompContext,
9+
} from "../util.js"
10+
11+
export const LobbyPanel = () => {
12+
return (
13+
<div className="fixed top-0 right-0 w-64 h-full bg-slate-800 border-l-2 border-slate-700">
14+
<div className="pt-2 pl-4">
15+
<Panel />
16+
</div>
17+
</div>
18+
)
19+
}
20+
21+
function Panel() {
22+
let stompClient = useContext(StompContext)
23+
let [users, setUsers] = useState([])
24+
let initialized = useRef()
25+
useEffect(() => {
26+
if (initialized.current) {
27+
return
28+
}
29+
initialized.current = true
30+
let sub1 = stompClient.subscribe("/topic/lobby/users", (message) => {
31+
let r = JSON.parse(message.body)
32+
setUsers(r.users)
33+
})
34+
stompClient.publish({
35+
destination: "/app/lobby/hello",
36+
body: JSON.stringify({
37+
}),
38+
})
39+
return () => {
40+
sub1.unsubscribe()
41+
}
42+
}, [setUsers, initialized, stompClient])
43+
return (
44+
<div className="mt-2">
45+
{users.map(user => (
46+
<div key={user.name}>{user.name}</div>
47+
))}
48+
</div>
49+
)
50+
}

src/main/client/src/model/board.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export function getGroup(board, xx, yy) {
8989
}
9090
}
9191

92-
export function createBoardWithGroups(board) {
92+
export function rehydrate(board) {
9393
let dim = board.length
9494
let result = []
9595
for (let i = 0; i < board.length; i++) {

src/main/client/src/model/board.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
} from "vitest"
55
import {
66
getGroup,
7-
createBoardWithGroups,
7+
rehydrate,
88
} from "./board.js"
99
import {
1010
BLACK,
@@ -20,7 +20,7 @@ test("liberties", () => {
2020
[w, w, w, 0],
2121
[0, 0, 0, 0],
2222
]
23-
let result = createBoardWithGroups(board)
23+
let result = rehydrate(board)
2424
expect(result[0][1].liberties).toBe(1)
2525
})
2626

src/main/client/src/store.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
BLACK,
99
} from "./util.js"
1010
import {
11-
createBoardWithGroups,
11+
rehydrate,
1212
} from "./model/board.js"
1313

1414
export const useAuthStore = create((set) => ({
@@ -56,7 +56,7 @@ export const useGameStore = create((set) => ({
5656
state.black = game.black
5757
state.white = game.white
5858
state.editMode = game.editMode
59-
state.gameState.board = createBoardWithGroups(game.board)
59+
state.gameState.board = rehydrate(game.board)
6060
state.gameState.currentPlayer = game.currentPlayer
6161
state.gameState.currentColor = game.currentColor
6262
state.gameState.counting = game.counting

src/main/java/com/bernd/GameController.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,31 @@
33
import com.bernd.model.Game;
44
import com.bernd.model.JoinGameRequest;
55
import com.bernd.model.Move;
6+
import com.bernd.model.OpenGame;
7+
import com.bernd.model.OpenGameList;
8+
import com.bernd.util.RandomString;
9+
import org.springframework.http.ResponseEntity;
610
import org.springframework.messaging.core.MessageSendingOperations;
711
import org.springframework.messaging.handler.annotation.MessageMapping;
812
import org.springframework.stereotype.Controller;
13+
import org.springframework.web.bind.annotation.PostMapping;
14+
import org.springframework.web.bind.annotation.RequestBody;
15+
import org.springframework.web.bind.annotation.ResponseBody;
916

1017
@Controller
1118
public class GameController {
1219

1320
private final MessageSendingOperations<String> operations;
1421
private final Games games;
22+
private final OpenGames openGames;
1523

1624
GameController(
1725
MessageSendingOperations<String> operations,
18-
Games games) {
26+
Games games,
27+
OpenGames openGames) {
1928
this.operations = operations;
2029
this.games = games;
30+
this.openGames = openGames;
2131
}
2232

2333
@MessageMapping("/game/hello")
@@ -33,4 +43,13 @@ public void action(Move move) {
3343
games.put(updated);
3444
operations.convertAndSend("/topic/game/" + game.id(), updated);
3545
}
46+
47+
@PostMapping(value = "/api/create", consumes = "application/json")
48+
@ResponseBody
49+
public ResponseEntity<?> newGame(@RequestBody OpenGame openGame) {
50+
openGames.put(RandomString.get(), openGame);
51+
operations.convertAndSend("/topic/lobby/open",
52+
new OpenGameList(openGames.games()));
53+
return ResponseEntity.ok().build();
54+
}
3655
}

src/main/java/com/bernd/LobbyController.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void matchAction(MatchRequest request, Principal principal) {
6161
if (lookingForMatch == null) {
6262
lookingForMatch = user;
6363
operations.convertAndSend("/topic/lobby/gamerequest",
64-
new Status(request.name(), "ready"));
64+
new Status(principal.getName(), "ready"));
6565
return;
6666
}
6767
User black = lookingForMatch;
@@ -84,7 +84,7 @@ public void matchAction(MatchRequest request, Principal principal) {
8484
operations.convertAndSend("/topic/lobby/gamestart", game);
8585
}
8686

87-
private static int[][] createEmptyBoard(MatchRequest request) {
87+
static int[][] createEmptyBoard(MatchRequest request) {
8888
int dim = Math.max(request.dim(), 2);
8989
int[][] board = new int[dim][];
9090
for (int y = 0; y < dim; y++) {

src/main/java/com/bernd/LoginController.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,19 @@ public ResponseEntity<?> loginAction(
3232
@RequestBody LoginRequest request) {
3333
if (users.contains(request.name())) {
3434
return ResponseEntity.status(HttpStatus.UNAUTHORIZED)
35-
.body(new Error("Name bereits vergeben"));
35+
.body(new Error("Please choose another name"));
3636
}
37-
Algorithm algorithm = Algorithm.HMAC512(environment.getProperty("jwt.secret.key"));
37+
String key = environment.getProperty("jwt.secret.key");
38+
if (key == null) {
39+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
40+
.body(new Error("Server configuration error"));
41+
}
42+
Algorithm algorithm = Algorithm.HMAC512(key);
3843
String token = JWT.create()
3944
.withIssuer("auth0")
4045
.withClaim("name", request.name())
4146
.sign(algorithm);
4247
users.login(request.name());
4348
return ResponseEntity.ok(new LoginResponse(request.name(), token));
4449
}
45-
}
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.bernd;
2+
3+
import com.bernd.model.OpenGame;
4+
import java.util.LinkedHashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
import org.springframework.stereotype.Component;
8+
9+
@Component
10+
public class OpenGames {
11+
private final Map<String, OpenGame> map = new LinkedHashMap<>();
12+
13+
OpenGame get(String id) {
14+
return map.get(id);
15+
}
16+
17+
OpenGame put(String id, OpenGame game) {
18+
map.put(game.id(), game);
19+
return game;
20+
}
21+
22+
List<OpenGame> games() {
23+
return List.copyOf(map.values());
24+
}
25+
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
package com.bernd.model;
22

3-
public record MatchRequest(String name, int dim, boolean editMode) {
3+
public record MatchRequest(
4+
int dim,
5+
boolean editMode,
6+
int handicap) {
47
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.bernd.model;
2+
3+
public record OpenGame(
4+
String id,
5+
User user,
6+
int dim,
7+
int handicap) {
8+
9+
public OpenGame withId(String id) {
10+
return new OpenGame(id, user, dim, handicap);
11+
}
12+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.bernd.model;
2+
3+
import java.util.List;
4+
5+
public record OpenGameList(List<OpenGame> games) {
6+
}

0 commit comments

Comments
 (0)