feat: A lot of new features
This commit is contained in:
@ -0,0 +1,88 @@
|
||||
package cz.jzitnik.chronos.controllers;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Item;
|
||||
import cz.jzitnik.chronos.interactions.InteractionService;
|
||||
import cz.jzitnik.chronos.payload.requests.InteractionRequest;
|
||||
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
||||
import cz.jzitnik.chronos.payload.responses.TakeItemsResponse;
|
||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||
import cz.jzitnik.chronos.repository.CharacterRepository;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import cz.jzitnik.chronos.utils.anotations.CheckUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||
@RestController
|
||||
@RequestMapping("/game/characters")
|
||||
public class CharacterController {
|
||||
@Autowired
|
||||
private InteractionService interactionService;
|
||||
|
||||
@Autowired
|
||||
private PlayerRepository playerRepository;
|
||||
|
||||
@Autowired
|
||||
private CharacterRepository characterRepository;
|
||||
|
||||
@PostMapping("/interact")
|
||||
@CheckUser
|
||||
public ResponseEntity<UnifiedResponse<InteractionResponse, Error>> interact(@RequestParam String playerKey, @RequestBody InteractionRequest interactionRequest) {
|
||||
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||
|
||||
var characterOptional = characterRepository.findById(interactionRequest.getCharacterId());
|
||||
|
||||
if (characterOptional.isEmpty()) {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(null));
|
||||
}
|
||||
if (!characterOptional.get().getRoom().equals(player.getCurrentRoom())) {
|
||||
return ResponseEntity.badRequest().body(UnifiedResponse.failure(null));
|
||||
}
|
||||
if (characterOptional.get().isInteractedWith()) {
|
||||
return ResponseEntity.noContent().build();
|
||||
}
|
||||
|
||||
var interaction = characterOptional.get().getInteraction();
|
||||
|
||||
var interactionFunc = interactionService.mapInteraction(interaction);
|
||||
|
||||
var interactionResponse = interactionFunc.apply(player, characterOptional.get(), interactionRequest.getData());
|
||||
|
||||
return ResponseEntity.ok(
|
||||
UnifiedResponse.success(interactionResponse)
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("/take_items")
|
||||
@CheckUser
|
||||
public ResponseEntity<UnifiedResponse<TakeItemsResponse, Error>> takeItems(@RequestParam String playerKey, @RequestParam Long characterId) {
|
||||
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||
|
||||
var characterOptional = characterRepository.findById(characterId);
|
||||
|
||||
if (characterOptional.isEmpty()) {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(null));
|
||||
}
|
||||
|
||||
var character = characterOptional.get();
|
||||
if (!character.getRoom().equals(player.getCurrentRoom())) {
|
||||
return ResponseEntity.badRequest().body(UnifiedResponse.failure(null));
|
||||
}
|
||||
|
||||
if (character.getPlayersWhoSaw().contains(player)) {
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TakeItemsResponse.ALREADY_TAKEN));
|
||||
}
|
||||
|
||||
for (Item item : character.getInventory()) {
|
||||
var itemClone = new Item(item.getItemType(), player);
|
||||
player.addItem(itemClone);
|
||||
}
|
||||
player.getSeenCharacters().add(character);
|
||||
|
||||
playerRepository.save(player);
|
||||
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TakeItemsResponse.DONE));
|
||||
}
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
package cz.jzitnik.chronos.controllers;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Game;
|
||||
import cz.jzitnik.chronos.payload.errors.NotFoundError;
|
||||
import cz.jzitnik.chronos.payload.responses.TestGameKeyResponse;
|
||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||
import cz.jzitnik.chronos.repository.GameRepository;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import cz.jzitnik.chronos.services.GameService;
|
||||
import cz.jzitnik.chronos.utils.anotations.CheckUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||
@ -17,6 +23,9 @@ public class GameController {
|
||||
@Autowired
|
||||
private GameRepository gameRepository;
|
||||
|
||||
@Autowired
|
||||
private PlayerRepository playerRepository;
|
||||
|
||||
@PostMapping("/new")
|
||||
public UnifiedResponse<Game, Error> createGame() {
|
||||
var game = gameService.createGame();
|
||||
@ -24,4 +33,52 @@ public class GameController {
|
||||
|
||||
return UnifiedResponse.success(game);
|
||||
}
|
||||
|
||||
@PostMapping("/start")
|
||||
@CheckUser
|
||||
public ResponseEntity<UnifiedResponse<Object, Error>> startGame(@RequestParam String playerKey, @RequestParam String gameKey) {
|
||||
var gameOptional = gameRepository.findByGameKey(gameKey);
|
||||
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||
|
||||
if (gameOptional.isEmpty()) {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(
|
||||
UnifiedResponse.failure(new NotFoundError("Game with key " + gameKey + " was not found!"))
|
||||
);
|
||||
}
|
||||
|
||||
var game = gameOptional.get();
|
||||
|
||||
if (!game.getAdminPlayer().equals(player)) {
|
||||
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(
|
||||
UnifiedResponse.failure(new Error("Not authorized!"))
|
||||
);
|
||||
}
|
||||
|
||||
game.setStarted(true);
|
||||
|
||||
gameRepository.save(game);
|
||||
|
||||
return ResponseEntity.ok(UnifiedResponse.success(null));
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
public ResponseEntity<UnifiedResponse<TestGameKeyResponse, Error>> testGameKey(@RequestParam String gameKey) {
|
||||
var gameOptional = gameRepository.findByGameKey(gameKey);
|
||||
|
||||
if (gameOptional.isEmpty()) {
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.INVALID_KEY));
|
||||
}
|
||||
|
||||
var game = gameOptional.get();
|
||||
|
||||
if (game.isStarted()) {
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.GAME_STARTED));
|
||||
}
|
||||
|
||||
if (game.getPlayers().size() >= 3) {
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.MAXIUM_PLAYERS));
|
||||
}
|
||||
|
||||
return ResponseEntity.ok(UnifiedResponse.success(TestGameKeyResponse.WORKING));
|
||||
}
|
||||
}
|
||||
|
@ -38,8 +38,6 @@ public class PlayerController {
|
||||
|
||||
var player = gameService.addPlayer(game, playerNameRequest.getName());
|
||||
|
||||
gameRepository.save(game);
|
||||
|
||||
return ResponseEntity.ok(
|
||||
UnifiedResponse.success(player.getPlayerKey())
|
||||
);
|
||||
|
@ -0,0 +1,60 @@
|
||||
package cz.jzitnik.chronos.controllers;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Room;
|
||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import cz.jzitnik.chronos.repository.RoomRepository;
|
||||
import cz.jzitnik.chronos.services.GameService;
|
||||
import cz.jzitnik.chronos.utils.anotations.CheckUser;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||
@RestController
|
||||
@RequestMapping("/game/rooms")
|
||||
public class RoomController {
|
||||
@Autowired
|
||||
private PlayerRepository playerRepository;
|
||||
|
||||
@Autowired
|
||||
private RoomRepository roomRepository;
|
||||
|
||||
@Autowired
|
||||
private GameService gameService;
|
||||
|
||||
@GetMapping("/current_room")
|
||||
@CheckUser
|
||||
public ResponseEntity<UnifiedResponse<Room, Error>> getCurrentRoom(@RequestParam("playerKey") String playerKey) {
|
||||
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||
|
||||
return ResponseEntity.ok(
|
||||
UnifiedResponse.success(player.getCurrentRoom())
|
||||
);
|
||||
}
|
||||
|
||||
@PostMapping("/move")
|
||||
@CheckUser
|
||||
public ResponseEntity<UnifiedResponse<Object, Error>> moveToRoom(@RequestParam("playerKey") String playerKey, @RequestParam("roomId") Long roomId) {
|
||||
var player = playerRepository.findByPlayerKey(playerKey).get();
|
||||
|
||||
var roomOptional = roomRepository.findById(roomId);
|
||||
|
||||
if (roomOptional.isEmpty()) {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(UnifiedResponse.failure(null));
|
||||
}
|
||||
|
||||
var fromThisGame = gameService.isFromThisGame(player.getGame(), roomOptional.get());
|
||||
|
||||
if (!fromThisGame) {
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(UnifiedResponse.failure(new Error("Invalid roomId")));
|
||||
}
|
||||
|
||||
player.setCurrentRoom(roomOptional.get());
|
||||
|
||||
playerRepository.save(player);
|
||||
|
||||
return ResponseEntity.ok(UnifiedResponse.success(null));
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package cz.jzitnik.chronos.controllers;
|
||||
|
||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@CrossOrigin(origins = "*", maxAge = 3600)
|
||||
@RestController
|
||||
@RequestMapping("/status")
|
||||
public class StatusController {
|
||||
|
||||
// Don't decode this base64, just go to /status endpoint, you'll be surprised
|
||||
@GetMapping
|
||||
public UnifiedResponse<String, Error> getStatus() {
|
||||
return UnifiedResponse.success("working");
|
||||
}
|
||||
}
|
@ -2,7 +2,9 @@ package cz.jzitnik.chronos.entities;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||
import cz.jzitnik.chronos.interactions.Interaction;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
@ -15,6 +17,7 @@ import java.util.List;
|
||||
@Setter
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Table(name = "characters")
|
||||
public class Character {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@ -29,10 +32,16 @@ public class Character {
|
||||
@Enumerated(EnumType.STRING)
|
||||
private Interaction interaction;
|
||||
|
||||
private boolean interactedWith;
|
||||
|
||||
@ManyToOne
|
||||
@JsonBackReference(value = "room-characters")
|
||||
private Room room;
|
||||
|
||||
@ManyToMany(mappedBy = "seenCharacters", cascade = CascadeType.ALL)
|
||||
@JsonIgnore
|
||||
private List<Player> playersWhoSaw = new ArrayList<>();
|
||||
|
||||
private String dialog;
|
||||
|
||||
public Character(String name, Room room, String dialog) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cz.jzitnik.chronos.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.persistence.*;
|
||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||
import lombok.Getter;
|
||||
@ -26,9 +27,20 @@ public class Game {
|
||||
private List<Player> players = new ArrayList<>();
|
||||
|
||||
@OneToMany(mappedBy = "game", cascade = CascadeType.ALL)
|
||||
@JsonManagedReference(value = "game-rooms")
|
||||
@JsonIgnore
|
||||
private List<Room> rooms = new ArrayList<>();
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "default_room_id", referencedColumnName = "id")
|
||||
private Room defaultRoom;
|
||||
|
||||
@OneToOne(cascade = CascadeType.ALL)
|
||||
@JoinColumn(name = "admin_player_id", referencedColumnName = "id")
|
||||
@JsonIgnore
|
||||
private Player adminPlayer;
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
this.players.add(player);
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
package cz.jzitnik.chronos.entities;
|
||||
|
||||
public enum Interaction {
|
||||
Farmer
|
||||
}
|
@ -34,4 +34,9 @@ public class Item {
|
||||
this.itemType = itemType;
|
||||
this.charowner = charowner;
|
||||
}
|
||||
|
||||
public Item(ItemType itemType, Player owner) {
|
||||
this.itemType = itemType;
|
||||
this.owner = owner;
|
||||
}
|
||||
}
|
||||
|
@ -33,14 +33,29 @@ public class Player {
|
||||
private Game game;
|
||||
|
||||
@ManyToOne
|
||||
@Column(name = "current_room")
|
||||
@JoinColumn(name = "current_room")
|
||||
private Room currentRoom;
|
||||
|
||||
@Column(unique = true, nullable = false)
|
||||
@JsonIgnore
|
||||
private String playerKey;
|
||||
|
||||
private boolean luck = false;
|
||||
|
||||
@ManyToMany
|
||||
@JoinTable(
|
||||
name = "character_player",
|
||||
joinColumns = @JoinColumn(name = "player_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "character_id")
|
||||
)
|
||||
@JsonIgnore
|
||||
private List<Character> seenCharacters = new ArrayList<>();
|
||||
|
||||
public Player(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void addItem(Item item) {
|
||||
inventory.add(item);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package cz.jzitnik.chronos.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonManagedReference;
|
||||
import jakarta.persistence.*;
|
||||
@ -31,13 +30,17 @@ public class Room {
|
||||
private List<Character> characters = new ArrayList<>();
|
||||
|
||||
@ManyToOne
|
||||
@JsonBackReference(value = "game-rooms")
|
||||
@JsonIgnore
|
||||
private Game game;
|
||||
|
||||
@OneToMany(mappedBy = "current_room", cascade = CascadeType.ALL)
|
||||
@OneToMany(mappedBy = "currentRoom", cascade = CascadeType.ALL)
|
||||
@JsonIgnore
|
||||
private List<Player> players = new ArrayList<>();
|
||||
|
||||
@OneToOne(mappedBy = "defaultRoom")
|
||||
@JsonIgnore
|
||||
private Game gameDefault;
|
||||
|
||||
public Room(String name, Game game) {
|
||||
this.name = name;
|
||||
this.game = game;
|
||||
|
@ -0,0 +1,5 @@
|
||||
package cz.jzitnik.chronos.interactions;
|
||||
|
||||
public enum Interaction {
|
||||
Farmer
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
package cz.jzitnik.chronos.interactions;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Item;
|
||||
import cz.jzitnik.chronos.entities.ItemType;
|
||||
import cz.jzitnik.chronos.entities.Player;
|
||||
import cz.jzitnik.chronos.entities.Character;
|
||||
import cz.jzitnik.chronos.payload.responses.InteractionResponse;
|
||||
import cz.jzitnik.chronos.repository.CharacterRepository;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@Service
|
||||
public class InteractionService {
|
||||
@Autowired
|
||||
private PlayerRepository playerRepository;
|
||||
|
||||
@Autowired
|
||||
private CharacterRepository characterRepository;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Function3<T, U, V, W> {
|
||||
W apply(T t, U u, V v);
|
||||
}
|
||||
|
||||
public Function3<Player, Character, String, InteractionResponse> mapInteraction(Interaction interaction) {
|
||||
return switch (interaction) {
|
||||
case Farmer -> ((player, character, data) -> {
|
||||
Random random = new Random();
|
||||
boolean isLucky = player.isLuck();
|
||||
|
||||
int characterChoice = random.nextInt(3);
|
||||
|
||||
int userChoice = switch (data) {
|
||||
case "0" -> 0; // Rock
|
||||
case "1" -> 1; // Paper
|
||||
case "2" -> 2; // Scissors
|
||||
default -> throw new IllegalArgumentException("Invalid choice");
|
||||
};
|
||||
|
||||
if (isLucky) {
|
||||
// 50/50 chance
|
||||
boolean playerWins = random.nextBoolean();
|
||||
|
||||
// Reset the luck potion after use
|
||||
player.setLuck(false);
|
||||
|
||||
if (playerWins) {
|
||||
player.addItem(new Item(ItemType.KEY_FRAGMENT, player));
|
||||
playerRepository.save(player);
|
||||
|
||||
character.setInteractedWith(true);
|
||||
characterRepository.save(character);
|
||||
|
||||
return new InteractionResponse(true, "Vyhrál jsi, dostáváš jeden fragment klíče.");
|
||||
} else {
|
||||
return new InteractionResponse(false, "Prohrál jsi");
|
||||
}
|
||||
} else {
|
||||
// Standard rock-paper-scissors game logic
|
||||
if (userChoice == characterChoice) {
|
||||
return new InteractionResponse(false, "Remíza, oběma hráčům se podařilo uhádnout.");
|
||||
} else if ((userChoice == 0 && characterChoice == 2) || (userChoice == 1 && characterChoice == 0) || (userChoice == 2 && characterChoice == 1)) {
|
||||
player.addItem(new Item(ItemType.KEY_FRAGMENT, player));
|
||||
playerRepository.save(player);
|
||||
|
||||
character.setInteractedWith(true);
|
||||
characterRepository.save(character);
|
||||
|
||||
return new InteractionResponse(true, "Vyhrál jsi, dostáváš jeden fragment klíče.");
|
||||
} else {
|
||||
return new InteractionResponse(false, "Prohrál jsi");
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
@ -1,12 +1,7 @@
|
||||
package cz.jzitnik.chronos.payload.errors;
|
||||
|
||||
public class NotFoundError extends Error {
|
||||
public NotFoundError() {
|
||||
super("Not Found Error");
|
||||
}
|
||||
|
||||
public NotFoundError(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package cz.jzitnik.chronos.payload.errors;
|
||||
|
||||
public class PlayerNotFoundError extends Error {
|
||||
public PlayerNotFoundError(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package cz.jzitnik.chronos.payload.requests;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class InteractionRequest {
|
||||
private String data;
|
||||
private Long characterId;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package cz.jzitnik.chronos.payload.responses;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
public class InteractionResponse {
|
||||
private boolean success;
|
||||
private String responseText;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package cz.jzitnik.chronos.payload.responses;
|
||||
|
||||
public enum TakeItemsResponse {
|
||||
DONE,
|
||||
ALREADY_TAKEN
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package cz.jzitnik.chronos.payload.responses;
|
||||
|
||||
public enum TestGameKeyResponse {
|
||||
WORKING,
|
||||
GAME_STARTED,
|
||||
INVALID_KEY,
|
||||
MAXIUM_PLAYERS
|
||||
}
|
@ -5,14 +5,12 @@ import lombok.Setter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
public class UnifiedResponse<T, U> {
|
||||
@Getter
|
||||
private final Optional<T> data;
|
||||
|
||||
@Getter
|
||||
private final Optional<U> error;
|
||||
|
||||
@Getter
|
||||
private final Boolean success;
|
||||
|
||||
private UnifiedResponse(Optional<T> data, Optional<U> error, Boolean success) {
|
||||
|
@ -0,0 +1,11 @@
|
||||
package cz.jzitnik.chronos.repository;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Character;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public interface CharacterRepository extends JpaRepository<Character, Long> {
|
||||
|
||||
}
|
@ -4,7 +4,10 @@ import cz.jzitnik.chronos.entities.Player;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Repository
|
||||
public interface PlayerRepository extends JpaRepository<Player, Long> {
|
||||
boolean existsByPlayerKey(String playerKey);
|
||||
Optional<Player> findByPlayerKey(String playerKey);
|
||||
}
|
||||
|
@ -0,0 +1,11 @@
|
||||
package cz.jzitnik.chronos.repository;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Room;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
||||
@Repository
|
||||
public interface RoomRepository extends JpaRepository<Room, Long> {
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package cz.jzitnik.chronos.services;
|
||||
|
||||
import cz.jzitnik.chronos.entities.Game;
|
||||
import cz.jzitnik.chronos.entities.Player;
|
||||
import cz.jzitnik.chronos.entities.Room;
|
||||
import cz.jzitnik.chronos.repository.GameRepository;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -59,7 +60,9 @@ public class GameService {
|
||||
Game newGame = new Game();
|
||||
newGame.setGameKey(generateUniqueGameKey());
|
||||
|
||||
initGameService.initGame(newGame);
|
||||
var defaultRoom = initGameService.initGame(newGame);
|
||||
|
||||
newGame.setDefaultRoom(defaultRoom);
|
||||
|
||||
return gameRepository.save(newGame);
|
||||
}
|
||||
@ -68,9 +71,21 @@ public class GameService {
|
||||
var player = new Player(playerName);
|
||||
player.setPlayerKey(generateUniquePlayerKey());
|
||||
player.setGame(game);
|
||||
player.setCurrentRoom(game.getDefaultRoom());
|
||||
|
||||
if (game.getPlayers().isEmpty()) {
|
||||
game.setAdminPlayer(player);
|
||||
}
|
||||
|
||||
game.addPlayer(player);
|
||||
|
||||
gameRepository.save(game);
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
|
||||
public boolean isFromThisGame(Game game, Room room) {
|
||||
return game.getRooms().stream().anyMatch(rm -> rm.equals(room));
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,16 @@ package cz.jzitnik.chronos.services;
|
||||
|
||||
import cz.jzitnik.chronos.entities.*;
|
||||
import cz.jzitnik.chronos.entities.Character;
|
||||
import cz.jzitnik.chronos.interactions.Interaction;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Service
|
||||
public class InitGameService {
|
||||
public void initGame(Game game) {
|
||||
public Room initGame(Game game) {
|
||||
var rooms = new ArrayList<Room>();
|
||||
|
||||
|
||||
// Outside
|
||||
var outside = new Room(
|
||||
"Outside", // Name
|
||||
@ -48,5 +48,8 @@ public class InitGameService {
|
||||
rooms.add(stodola);
|
||||
|
||||
game.setRooms(rooms);
|
||||
|
||||
// Return a room that all players will spawn in
|
||||
return outside;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package cz.jzitnik.chronos.utils.anotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CheckUser {
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package cz.jzitnik.chronos.utils.anotations;
|
||||
|
||||
import cz.jzitnik.chronos.payload.errors.PlayerNotFoundError;
|
||||
import cz.jzitnik.chronos.payload.responses.UnifiedResponse;
|
||||
import cz.jzitnik.chronos.repository.PlayerRepository;
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Aspect
|
||||
@Component
|
||||
public class UserCheckAspect {
|
||||
|
||||
@Autowired
|
||||
private PlayerRepository playerRepository;
|
||||
|
||||
@Around("@annotation(CheckUser)")
|
||||
public Object checkUser(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
String playerKey = (String) joinPoint.getArgs()[0]; // Assuming playerKey is the first argument
|
||||
var playerOptional = playerRepository.findByPlayerKey(playerKey);
|
||||
|
||||
if (playerOptional.isEmpty()) {
|
||||
return ResponseEntity
|
||||
.status(HttpStatus.NOT_FOUND)
|
||||
.body(UnifiedResponse.failure(new PlayerNotFoundError("Player was not found!")));
|
||||
}
|
||||
|
||||
// Proceed with the original method if the player exists
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user