-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #38 from PaulKreft/multiplayer
Multiplayer
- Loading branch information
Showing
17 changed files
with
591 additions
and
7 deletions.
There are no files selected for viewing
56 changes: 56 additions & 0 deletions
56
backend/src/main/java/de/neuefische/paulkreft/backend/lobby/controller/LobbyController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package de.neuefische.paulkreft.backend.lobby.controller; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
import de.neuefische.paulkreft.backend.lobby.model.Lobby; | ||
import de.neuefische.paulkreft.backend.lobby.service.LobbyService; | ||
import de.neuefische.paulkreft.backend.users.models.Player; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequestMapping("/api/lobby") | ||
@RequiredArgsConstructor | ||
public class LobbyController { | ||
private final LobbyService lobbyService; | ||
|
||
@PostMapping | ||
public Lobby createLobby(@RequestBody Lobby lobby) { | ||
return lobbyService.createLobby(lobby); | ||
} | ||
|
||
@GetMapping("/{id}") | ||
public Lobby getLobbyById(@PathVariable String id) { | ||
return lobbyService.getLobbyById(id); | ||
} | ||
|
||
@PutMapping("/{id}/join") | ||
public Lobby joinLobby(@PathVariable String id, @RequestBody Player player) { | ||
return lobbyService.joinLobby(id, player); | ||
} | ||
|
||
@PutMapping | ||
public Lobby updateLobby(@RequestBody Lobby lobby) { | ||
return lobbyService.updateLobby(lobby); | ||
} | ||
|
||
@PutMapping("/{id}/leave") | ||
public Lobby leaveLobby(@PathVariable String id, @RequestBody Player player) { | ||
return lobbyService.leaveLobby(id, player); | ||
} | ||
|
||
@DeleteMapping("/{id}") | ||
public Lobby deleteLobby(@PathVariable String id) { | ||
return lobbyService.deleteLobby(id); | ||
} | ||
|
||
@PutMapping("/{id}/setWinner") | ||
public Lobby setWinner(@PathVariable String id, @RequestBody ObjectNode payload) throws JsonProcessingException { | ||
return lobbyService.setWinner(id, payload); | ||
} | ||
|
||
@PutMapping("/{id}/setLoser") | ||
public Lobby setLoser(@PathVariable String id, @RequestBody Player player) { | ||
return lobbyService.setLoser(id, player); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
backend/src/main/java/de/neuefische/paulkreft/backend/lobby/model/Lobby.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package de.neuefische.paulkreft.backend.lobby.model; | ||
|
||
import de.neuefische.paulkreft.backend.users.models.Player; | ||
import lombok.With; | ||
import org.springframework.data.annotation.Id; | ||
|
||
import java.util.List; | ||
|
||
@With | ||
public record Lobby( | ||
@Id | ||
String id, | ||
List<Player> players, | ||
boolean isGameInProgress, | ||
boolean isGameOver, | ||
int difficulty, | ||
Player winner, | ||
List<Player> losers, | ||
Integer timeToBeat | ||
) { | ||
} |
9 changes: 9 additions & 0 deletions
9
backend/src/main/java/de/neuefische/paulkreft/backend/lobby/repository/LobbyRepo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package de.neuefische.paulkreft.backend.lobby.repository; | ||
|
||
import de.neuefische.paulkreft.backend.lobby.model.Lobby; | ||
import org.springframework.data.mongodb.repository.MongoRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface LobbyRepo extends MongoRepository<Lobby, String> { | ||
} |
85 changes: 85 additions & 0 deletions
85
backend/src/main/java/de/neuefische/paulkreft/backend/lobby/service/LobbyService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
package de.neuefische.paulkreft.backend.lobby.service; | ||
|
||
import com.fasterxml.jackson.core.JsonProcessingException; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.node.ObjectNode; | ||
import de.neuefische.paulkreft.backend.lobby.model.Lobby; | ||
import de.neuefische.paulkreft.backend.lobby.repository.LobbyRepo; | ||
import de.neuefische.paulkreft.backend.users.models.Player; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class LobbyService { | ||
private final LobbyRepo lobbyRepo; | ||
|
||
|
||
public Lobby createLobby(Lobby lobby) { | ||
return lobbyRepo.save(lobby); | ||
} | ||
|
||
public Lobby getLobbyById(String id) { | ||
return lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
} | ||
|
||
public Lobby joinLobby(String id, @RequestBody Player player) { | ||
Lobby lobby = lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
|
||
lobby.players().add(player); | ||
return lobbyRepo.save(lobby); | ||
} | ||
|
||
public Lobby updateLobby(Lobby lobby) { | ||
if (!lobbyRepo.existsById(lobby.id())) { | ||
throw new RuntimeException(); | ||
} | ||
|
||
return lobbyRepo.save(lobby); | ||
} | ||
|
||
public Lobby leaveLobby(String id, @RequestBody Player player) { | ||
Lobby lobby = lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
|
||
lobby.players().remove(player); | ||
return lobbyRepo.save(lobby); | ||
} | ||
|
||
public Lobby deleteLobby(String id) { | ||
Lobby lobby = lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
|
||
lobbyRepo.deleteById(id); | ||
return lobby; | ||
} | ||
|
||
public Lobby setWinner(String id, ObjectNode payload) throws JsonProcessingException { | ||
Lobby lobby = lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
|
||
Player player = new ObjectMapper().treeToValue(payload.get("player"), Player.class); | ||
Integer time = payload.get("time").asInt(); | ||
|
||
|
||
Player winner = lobby.winner(); | ||
|
||
if (winner != null) { | ||
if (lobby.timeToBeat() <= time) { | ||
lobby.losers().add(player); | ||
return lobbyRepo.save(lobby); | ||
} else { | ||
lobby.losers().add(lobby.winner()); | ||
return lobbyRepo.save(lobby.withWinner(player).withTimeToBeat(time)); | ||
} | ||
} | ||
|
||
return lobbyRepo.save(lobby.withWinner(player).withTimeToBeat(time)); | ||
} | ||
|
||
public Lobby setLoser(String id, Player loser) { | ||
Lobby lobby = lobbyRepo.findById(id).orElseThrow(RuntimeException::new); | ||
|
||
lobby.losers().add(loser); | ||
return lobbyRepo.save(lobby); | ||
} | ||
|
||
} |
7 changes: 7 additions & 0 deletions
7
backend/src/main/java/de/neuefische/paulkreft/backend/users/models/Player.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package de.neuefische.paulkreft.backend.users.models; | ||
|
||
public record Player( | ||
String id, | ||
String name | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import React, { useState } from "react"; | ||
import { useNavigate } from "react-router-dom"; | ||
import axios from "axios"; | ||
import { Lobby } from "../types/Lobby.ts"; | ||
import { Player } from "../types/Player.ts"; | ||
import { User } from "../types/User.ts"; | ||
|
||
type MultiPlayerProps = { | ||
user: User; | ||
}; | ||
|
||
export const LobbyEntrance: React.FC<MultiPlayerProps> = ({ user }) => { | ||
const [lobbyId, setLobbyId] = useState<string>(""); | ||
|
||
const navigate = useNavigate(); | ||
|
||
if (!user) { | ||
return <div>No user found</div>; | ||
} | ||
|
||
const currentPlayer: Player = { id: user.id, name: user.name }; | ||
|
||
const createLobby = (): void => { | ||
const targetLobby = Math.ceil(Math.random() * 1000000).toString(); | ||
|
||
const lobby: Lobby = { | ||
id: targetLobby, | ||
players: [currentPlayer], | ||
isGameInProgress: false, | ||
isGameOver: false, | ||
difficulty: 4, | ||
losers: [], | ||
}; | ||
|
||
axios.post("/api/lobby", lobby).then(() => navigate(`/multiplayer/lobby/${targetLobby}`)); | ||
}; | ||
|
||
const joinLobby = (): void => { | ||
axios.put(`/api/lobby/${lobbyId}/join`, currentPlayer).then(() => navigate(`/multiplayer/lobby/${lobbyId}`)); | ||
}; | ||
|
||
return ( | ||
<div className="flex h-max flex-1 flex-col items-center px-5 pb-32 pt-20 xs:pb-20 sm:px-10"> | ||
<div className="flex h-80 w-96 flex-col items-center justify-evenly gap-5 rounded-2xl border-2 border-black p-5"> | ||
<button | ||
className="h-max items-center rounded-lg border-2 border-black px-6 py-2 text-xl font-light hover:bg-black hover:text-white" | ||
onClick={createLobby} | ||
> | ||
Create new lobby | ||
</button> | ||
<div className="flex justify-center gap-5"> | ||
<input | ||
className="h-max w-2/5 rounded-lg border-2 border-black px-3 py-1 font-light" | ||
type="text" | ||
value={lobbyId} | ||
onChange={(event) => setLobbyId(event.target.value)} | ||
/> | ||
<button | ||
className="h-max items-center rounded-lg border-2 border-black px-3 py-1 font-light hover:bg-black hover:text-white" | ||
onClick={joinLobby} | ||
> | ||
Join Lobby | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.