diff --git a/pom.xml b/pom.xml
index 31be34e..c28b894 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,75 +1,85 @@
-
- 4.0.0
-
- org.springframework.boot
- spring-boot-starter-parent
- 3.4.3
-
-
- pintudos
- game
- 0.0.1-SNAPSHOT
- game
- This is a game similar to pictionari, which this project is the back of the game
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 21
-
-
-
- org.springframework.boot
- spring-boot-starter-data-mongodb
-
-
- org.springframework.boot
- spring-boot-starter-oauth2-client
-
-
- org.springframework.boot
- spring-boot-starter-security
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-websocket
-
+
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.security
- spring-security-test
- test
-
-
+ 4.0.0
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
-
-
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.4.3
+
+
+
+ pintudos
+ game
+ 0.0.1-SNAPSHOT
+ game
+ This is a game similar to pictionari, which this project is the back of the game
+
+
+ 17
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ org.springframework.boot
+ spring-boot-starter-oauth2-client
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+ org.projectlombok
+ lombok
+ 1.18.24
+ provided
+
+
+ org.springframework.data
+ spring-data-mongodb
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.11.0
+
+ 17
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
diff --git a/src/main/java/pintudos/game/GameApplication.java b/src/main/java/pintudos/game/GameApplication.java
index 80b8d10..b447ebf 100644
--- a/src/main/java/pintudos/game/GameApplication.java
+++ b/src/main/java/pintudos/game/GameApplication.java
@@ -6,8 +6,7 @@
@SpringBootApplication
public class GameApplication {
- public static void main(String[] args) {
- SpringApplication.run(GameApplication.class, args);
- }
-
+ public static void main(String[] args) {
+ SpringApplication.run(GameApplication.class, args);
+ }
}
diff --git a/src/main/java/pintudos/game/config/SecurityConfig.java b/src/main/java/pintudos/game/config/SecurityConfig.java
new file mode 100644
index 0000000..700ebb8
--- /dev/null
+++ b/src/main/java/pintudos/game/config/SecurityConfig.java
@@ -0,0 +1,37 @@
+package pintudos.game.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.web.SecurityFilterChain;
+
+@Configuration
+public class SecurityConfig {
+
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http
+ .cors()
+ .and()
+ .csrf()
+ .disable() // Necesario para SockJS
+ .authorizeHttpRequests(authz ->
+ authz
+ .requestMatchers(
+ "/game/**", // SockJS handshake y WebSocket transport
+ "/ws/**", // Si usas /ws como endpoint de registro STOMP
+ "/topic/**", // Canal de suscripciones
+ "/app/**" // Canal de envío desde el cliente
+ )
+ .permitAll()
+ .anyRequest()
+ .authenticated() // El resto necesita auth
+ )
+ .formLogin()
+ .disable()
+ .httpBasic()
+ .disable();
+
+ return http.build();
+ }
+}
diff --git a/src/main/java/pintudos/game/config/WebConfig.java b/src/main/java/pintudos/game/config/WebConfig.java
new file mode 100644
index 0000000..08f9942
--- /dev/null
+++ b/src/main/java/pintudos/game/config/WebConfig.java
@@ -0,0 +1,24 @@
+package pintudos.game.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class WebConfig {
+
+ @Bean
+ public WebMvcConfigurer corsConfigurer() {
+ return new WebMvcConfigurer() {
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry
+ .addMapping("/**")
+ .allowedOrigins("http://localhost:5173", "http://localhost:3000") // Especificar frontend
+ .allowedMethods("*")
+ .allowedHeaders("*"); // Habilitar credenciales
+ }
+ };
+ }
+}
diff --git a/src/main/java/pintudos/game/controller/ChatController.java b/src/main/java/pintudos/game/controller/ChatController.java
new file mode 100644
index 0000000..0adb5d9
--- /dev/null
+++ b/src/main/java/pintudos/game/controller/ChatController.java
@@ -0,0 +1,142 @@
+package pintudos.game.controller;
+
+import java.time.LocalDateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.handler.annotation.Payload;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.ResponseBody;
+import pintudos.game.model.GameRoom;
+import pintudos.game.service.GameRoomService;
+
+@Controller
+public class ChatController {
+
+ private final SimpMessagingTemplate messagingTemplate;
+
+ @Autowired
+ private GameRoomService gameRoomService;
+
+ public ChatController(SimpMessagingTemplate messagingTemplate) {
+ this.messagingTemplate = messagingTemplate;
+ }
+
+ public static class ChatMessage {
+
+ private String sender;
+ private String message;
+ private LocalDateTime timestamp;
+
+ // Getters y setters
+
+ public String getSender() {
+ return sender;
+ }
+
+ public void setSender(String sender) {
+ this.sender = sender;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public LocalDateTime getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(LocalDateTime timestamp) {
+ this.timestamp = timestamp;
+ }
+ }
+
+ @MessageMapping("/chat/{roomId}")
+ public void handleChatMessage(
+ @DestinationVariable String roomId,
+ @Payload ChatMessage chatMessage
+ ) {
+ chatMessage.setTimestamp(LocalDateTime.now());
+
+ // Obtener la sala actual
+ GameRoom room = gameRoomService.getRoom(roomId);
+ if (room != null) {
+ // Verificar si el mensaje coincide con la palabra a adivinar
+ if (
+ room.getWordToGuess() != null &&
+ room.getWordToGuess().equalsIgnoreCase(chatMessage.getMessage())
+ ) {
+ // Enviar mensaje indicando que alguien ganó
+ ChatMessage winnerMessage = new ChatMessage();
+ winnerMessage.setSender("System");
+ winnerMessage.setMessage(
+ chatMessage.getSender() + " ha adivinado la palabra y ganó!"
+ );
+ winnerMessage.setTimestamp(LocalDateTime.now());
+
+ messagingTemplate.convertAndSend(
+ "/topic/chat/" + roomId,
+ winnerMessage
+ );
+ } else {
+ // Enviar el mensaje normal al chat
+ messagingTemplate.convertAndSend("/topic/chat/" + roomId, chatMessage);
+ }
+ }
+ }
+
+ @MessageMapping("/hint/{roomId}")
+ public void handleHintRequest(
+ @DestinationVariable String roomId,
+ @Payload String playerName
+ ) {
+ // Obtener la sala actual
+ GameRoom room = gameRoomService.getRoom(roomId);
+ if (room != null && room.getHint() != null) {
+ // Crear un mensaje para enviar la pista
+ ChatMessage hintMessage = new ChatMessage();
+ hintMessage.setSender("System");
+ hintMessage.setMessage(
+ playerName + " solicitó la pista: " + room.getHint()
+ );
+ hintMessage.setTimestamp(LocalDateTime.now());
+
+ // Enviar el mensaje al chat de la sala
+ messagingTemplate.convertAndSend("/topic/chat/" + roomId, hintMessage);
+ }
+ }
+
+ @GetMapping("/game/{roomId}/secret-word")
+ @ResponseBody
+ public String getSecretWord(@PathVariable String roomId) {
+ GameRoom room = gameRoomService.getRoom(roomId);
+ if (room != null) {
+ return room.getWordToGuess();
+ }
+ return "Room not found";
+ }
+
+ @GetMapping("/game/{roomId}/clue")
+ public ResponseEntity getClue(@PathVariable String roomId) {
+ // Aquí se asegura de que solo el primer jugador que haga la solicitud obtenga la pista
+ // Si ya se ha enviado la pista, se puede devolver un error o un mensaje indicando que ya fue entregada
+ GameRoom room = gameRoomService.getRoom(roomId);
+ if (room.isClueAlreadyGiven()) {
+ return ResponseEntity.ok("La pista ya ha sido entregada a otro jugador.");
+ }
+
+ // Marca la pista como entregada para la sala
+ room.markClueAsGiven();
+
+ return ResponseEntity.ok(room.getHint());
+ }
+}
diff --git a/src/main/java/pintudos/game/controller/GameController.java b/src/main/java/pintudos/game/controller/GameController.java
new file mode 100644
index 0000000..ee4f20e
--- /dev/null
+++ b/src/main/java/pintudos/game/controller/GameController.java
@@ -0,0 +1,63 @@
+package pintudos.game.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Controller;
+import pintudos.game.model.GameRoom;
+import pintudos.game.model.PlayerCount;
+import pintudos.game.model.RoomRequest;
+import pintudos.game.model.Trace;
+import pintudos.game.service.GameRoomService;
+import pintudos.game.service.TraceService;
+
+@Controller
+public class GameController {
+
+ @Autowired
+ private GameRoomService gameRoomService;
+
+ @Autowired
+ private TraceService traceService;
+
+ @Autowired
+ private SimpMessagingTemplate messagingTemplate;
+
+ // Crear una nueva sala
+ @MessageMapping("/createRoom")
+ public void createRoom(RoomRequest request) {
+ GameRoom room = gameRoomService.createRoom(
+ request.getRoomId(),
+ request.getPlayer()
+ );
+ messagingTemplate.convertAndSend("/topic/rooms", room);
+ }
+
+ // Unirse a una sala
+ @MessageMapping("/joinRoom")
+ public void joinRoom(RoomRequest request) {
+ GameRoom room = gameRoomService.joinRoom(
+ request.getRoomId(),
+ request.getPlayer()
+ );
+
+ if (room != null) {
+ // Notificar cambios generales de la sala (ya lo haces)
+ messagingTemplate.convertAndSend("/topic/rooms", room);
+
+ // Enviar número de jugadores a los conectados en esa sala
+ int playerCount = room.getPlayers().size();
+ messagingTemplate.convertAndSend(
+ "/topic/room/" + request.getRoomId() + "/players",
+ new PlayerCount(playerCount)
+ );
+ }
+ }
+
+ // Recibir un trazo y enviarlo a todos los miembros de la sala
+ @MessageMapping("/trace/{roomId}")
+ public void sendTrace(@DestinationVariable String roomId, Trace trace) {
+ messagingTemplate.convertAndSend("/topic/" + roomId + "/traces", trace);
+ }
+}
diff --git a/src/main/java/pintudos/game/controller/TraceController.java b/src/main/java/pintudos/game/controller/TraceController.java
new file mode 100644
index 0000000..df7ac83
--- /dev/null
+++ b/src/main/java/pintudos/game/controller/TraceController.java
@@ -0,0 +1,33 @@
+package pintudos.game.controller;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import pintudos.game.model.Trace;
+import pintudos.game.service.TraceService;
+
+@RestController
+@RequestMapping("/traces") // Permite peticiones desde cualquier frontend
+public class TraceController {
+
+ @Autowired
+ private TraceService traceService;
+
+ // Guardar un trazo
+ @PostMapping
+ public Trace saveTrace(@RequestBody TraceDTO tracedDto) {
+ Trace trace = new Trace(
+ tracedDto.getRoomId(),
+ tracedDto.getPoints(),
+ tracedDto.getColor(),
+ tracedDto.getWidth()
+ );
+ return traceService.saveTrace(trace); // Guardamos el trazo
+ }
+
+ // Obtener los trazos de una sala
+ @GetMapping("/{roomId}")
+ public List getTraces(@PathVariable String roomId) {
+ return traceService.getTracesByRoom(roomId); // Recuperamos los trazos de la sala
+ }
+}
diff --git a/src/main/java/pintudos/game/controller/TraceDTO.java b/src/main/java/pintudos/game/controller/TraceDTO.java
new file mode 100644
index 0000000..2b342ea
--- /dev/null
+++ b/src/main/java/pintudos/game/controller/TraceDTO.java
@@ -0,0 +1,18 @@
+package pintudos.game.controller;
+
+import java.util.List;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+import pintudos.game.model.CustomPoint;
+
+@Data
+@Getter
+@Setter
+public class TraceDTO {
+
+ private String roomId;
+ private List points; // Usar la clase personalizada
+ private String color;
+ private int width;
+}
diff --git a/src/main/java/pintudos/game/controller/WebSocketController.java b/src/main/java/pintudos/game/controller/WebSocketController.java
new file mode 100644
index 0000000..0a950cb
--- /dev/null
+++ b/src/main/java/pintudos/game/controller/WebSocketController.java
@@ -0,0 +1,25 @@
+package pintudos.game.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.messaging.handler.annotation.DestinationVariable;
+import org.springframework.messaging.handler.annotation.MessageMapping;
+import org.springframework.messaging.simp.SimpMessagingTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import pintudos.game.model.Trace;
+import pintudos.game.service.TraceService;
+
+@Controller
+public class WebSocketController {
+
+ @Autowired
+ private TraceService traceService;
+
+ @Autowired
+ private SimpMessagingTemplate messagingTemplate;
+
+ @MessageMapping("/ws/trace/{roomId}")
+ public void sendTrace(@DestinationVariable String roomId, Trace trace) {
+ messagingTemplate.convertAndSend("/topic/trace/" + roomId, trace);
+ }
+}
diff --git a/src/main/java/pintudos/game/model/CustomPoint.java b/src/main/java/pintudos/game/model/CustomPoint.java
new file mode 100644
index 0000000..a64efb7
--- /dev/null
+++ b/src/main/java/pintudos/game/model/CustomPoint.java
@@ -0,0 +1,53 @@
+package pintudos.game.model;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+
+public class CustomPoint {
+
+ private double latitude;
+ private double longitude;
+ private String type; // Campo opcional para JSON
+
+ public CustomPoint() {}
+
+ @JsonCreator
+ public CustomPoint(
+ @JsonProperty("type") String type,
+ @JsonProperty("coordinates") List coordinates
+ ) {
+ this.type = type; // Ignorar o validar que sea "Point"
+ this.longitude = coordinates.get(0);
+ this.latitude = coordinates.get(1);
+ }
+
+ public CustomPoint(double latitude, double longitude) {
+ this.latitude = latitude;
+ this.longitude = longitude;
+ }
+
+ public double getLatitude() {
+ return latitude;
+ }
+
+ public void setLatitude(double latitude) {
+ this.latitude = latitude;
+ }
+
+ public double getLongitude() {
+ return longitude;
+ }
+
+ public void setLongitude(double longitude) {
+ this.longitude = longitude;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+}
diff --git a/src/main/java/pintudos/game/model/GameRoom.java b/src/main/java/pintudos/game/model/GameRoom.java
new file mode 100644
index 0000000..6b74d23
--- /dev/null
+++ b/src/main/java/pintudos/game/model/GameRoom.java
@@ -0,0 +1,82 @@
+package pintudos.game.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class GameRoom {
+
+ private String roomId;
+ private List players; // Listado de jugadores conectados
+ private List traces; // Lista de trazos realizados
+ private String wordToGuess;
+ private String hint; // Pista de la palabra
+ private boolean clueAlreadyGiven; // Indica si la pista ya fue dada
+
+ public GameRoom(String roomId, String player) {
+ this.roomId = roomId;
+ this.players = new ArrayList<>();
+ this.traces = new ArrayList<>();
+ this.players.add("player");
+
+ // Mapa de palabras y pistas
+ Map wordsWithHints = new HashMap<>();
+ wordsWithHints.put("apple", "A red or green fruit.");
+ wordsWithHints.put("banana", "A yellow fruit that monkeys love.");
+ wordsWithHints.put("cherry", "A small red fruit often used as a topping.");
+ wordsWithHints.put("date", "A sweet fruit often found in deserts.");
+ wordsWithHints.put("elderberry", "A dark purple berry used in syrups.");
+
+ // Seleccionar una palabra aleatoria y su pista
+ List keys = new ArrayList<>(wordsWithHints.keySet());
+ String randomWord = keys.get((int) (Math.random() * keys.size()));
+ this.wordToGuess = randomWord;
+ this.hint = wordsWithHints.get(randomWord);
+ clueAlreadyGiven = false; // Inicialmente, la pista no ha sido dada
+ }
+
+ // Métodos para agregar jugadores y trazos
+ public void addPlayer(String player) {
+ if (!players.contains(player)) {
+ players.add(player);
+ }
+ }
+
+ public void removePlayer(String player) {
+ players.remove(player);
+ }
+
+ public void addTrace(Trace trace) {
+ traces.add(trace);
+ }
+
+ // Getters y Setters
+ public String getRoomId() {
+ return roomId;
+ }
+
+ public List getPlayers() {
+ return players;
+ }
+
+ public List getTraces() {
+ return traces;
+ }
+
+ public String getWordToGuess() {
+ return wordToGuess;
+ }
+
+ public String getHint() {
+ return hint;
+ }
+
+ public boolean isClueAlreadyGiven() {
+ return clueAlreadyGiven;
+ }
+
+ public void markClueAsGiven() {
+ this.clueAlreadyGiven = true;
+ }
+}
diff --git a/src/main/java/pintudos/game/model/PlayerCount.java b/src/main/java/pintudos/game/model/PlayerCount.java
new file mode 100644
index 0000000..e375f6a
--- /dev/null
+++ b/src/main/java/pintudos/game/model/PlayerCount.java
@@ -0,0 +1,20 @@
+package pintudos.game.model;
+
+public class PlayerCount {
+
+ private int players;
+
+ public PlayerCount() {}
+
+ public PlayerCount(int players) {
+ this.players = players;
+ }
+
+ public int getPlayers() {
+ return players;
+ }
+
+ public void setPlayers(int players) {
+ this.players = players;
+ }
+}
diff --git a/src/main/java/pintudos/game/model/RoomRequest.java b/src/main/java/pintudos/game/model/RoomRequest.java
new file mode 100644
index 0000000..de6ff81
--- /dev/null
+++ b/src/main/java/pintudos/game/model/RoomRequest.java
@@ -0,0 +1,23 @@
+package pintudos.game.model;
+
+public class RoomRequest {
+
+ private String roomId;
+ private String player;
+
+ public String getRoomId() {
+ return roomId;
+ }
+
+ public void setRoomId(String roomId) {
+ this.roomId = roomId;
+ }
+
+ public String getPlayer() {
+ return player;
+ }
+
+ public void setPlayer(String player) {
+ this.player = player;
+ }
+}
diff --git a/src/main/java/pintudos/game/model/Trace.java b/src/main/java/pintudos/game/model/Trace.java
new file mode 100644
index 0000000..56f769d
--- /dev/null
+++ b/src/main/java/pintudos/game/model/Trace.java
@@ -0,0 +1,94 @@
+package pintudos.game.model;
+
+import com.mongodb.client.model.geojson.Point;
+import com.mongodb.client.model.geojson.Position;
+import java.util.List;
+import java.util.stream.Collectors;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@Document(collection = "traces")
+public class Trace {
+
+ @Id
+ private String id;
+
+ private String roomId;
+ private List points; // Usar la clase personalizada
+ private String color;
+ private int width;
+
+ public Trace(
+ String roomId,
+ List points,
+ String color,
+ int width
+ ) {
+ this.roomId = roomId;
+ this.points = points;
+ this.color = color;
+ this.width = width;
+ }
+
+ // Getters y Setters
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getRoomId() {
+ return roomId;
+ }
+
+ public void setRoomId(String roomId) {
+ this.roomId = roomId;
+ }
+
+ public List getPoints() {
+ return points;
+ }
+
+ public void setPoints(List points) {
+ this.points = points;
+ }
+
+ public String getColor() {
+ return color;
+ }
+
+ public void setColor(String color) {
+ this.color = color;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public void setWidth(int width) {
+ this.width = width;
+ }
+
+ // Métodos para convertir entre CustomPoint y Point
+ public List toMongoPoints() {
+ return points
+ .stream()
+ .map(p -> new Point(new Position(p.getLongitude(), p.getLatitude())))
+ .collect(Collectors.toList());
+ }
+
+ public void fromMongoPoints(List mongoPoints) {
+ this.points =
+ mongoPoints
+ .stream()
+ .map(p ->
+ new CustomPoint(
+ p.getCoordinates().getValues().get(1),
+ p.getCoordinates().getValues().get(0)
+ )
+ )
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/pintudos/game/repository/TraceRepository.java b/src/main/java/pintudos/game/repository/TraceRepository.java
new file mode 100644
index 0000000..8184fd8
--- /dev/null
+++ b/src/main/java/pintudos/game/repository/TraceRepository.java
@@ -0,0 +1,9 @@
+package pintudos.game.repository;
+
+import java.util.List;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import pintudos.game.model.Trace;
+
+public interface TraceRepository extends MongoRepository {
+ List findByRoomId(String roomId); // Buscar trazos por ID de sala
+}
diff --git a/src/main/java/pintudos/game/security/JwtUtil.java b/src/main/java/pintudos/game/security/JwtUtil.java
new file mode 100644
index 0000000..a378ed3
--- /dev/null
+++ b/src/main/java/pintudos/game/security/JwtUtil.java
@@ -0,0 +1,3 @@
+package pintudos.game.security;
+
+public class JwtUtil {}
diff --git a/src/main/java/pintudos/game/security/SecurityConfig.java b/src/main/java/pintudos/game/security/SecurityConfig.java
new file mode 100644
index 0000000..a2095bc
--- /dev/null
+++ b/src/main/java/pintudos/game/security/SecurityConfig.java
@@ -0,0 +1,3 @@
+package pintudos.game.security;
+
+public class SecurityConfig {}
diff --git a/src/main/java/pintudos/game/service/GameRoomService.java b/src/main/java/pintudos/game/service/GameRoomService.java
new file mode 100644
index 0000000..f77f7d7
--- /dev/null
+++ b/src/main/java/pintudos/game/service/GameRoomService.java
@@ -0,0 +1,44 @@
+package pintudos.game.service;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.springframework.stereotype.Service;
+import pintudos.game.model.GameRoom;
+import pintudos.game.model.Trace;
+
+@Service
+public class GameRoomService {
+
+ private final Map rooms = new java.util.concurrent.ConcurrentHashMap<>();
+
+ // Crear una nueva sala
+ public GameRoom createRoom(String roomId, String player) {
+ GameRoom room = new GameRoom(roomId, player);
+ rooms.put(roomId, room);
+ return room;
+ }
+
+ // Unirse a una sala
+ public GameRoom joinRoom(String roomId, String player) {
+ GameRoom room = rooms.get(roomId);
+ if (room != null) {
+ System.out.println("➡️ Antes de agregar: " + room.getPlayers());
+ room.addPlayer(player);
+ System.out.println("✅ Después de agregar: " + room.getPlayers());
+ }
+ return room;
+ }
+
+ // Obtener una sala por ID
+ public GameRoom getRoom(String roomId) {
+ return rooms.get(roomId);
+ }
+
+ // Guardar un trazo en la sala
+ public void addTraceToRoom(String roomId, Trace trace) {
+ GameRoom room = rooms.get(roomId);
+ if (room != null) {
+ room.addTrace(trace);
+ }
+ }
+}
diff --git a/src/main/java/pintudos/game/service/TraceService.java b/src/main/java/pintudos/game/service/TraceService.java
new file mode 100644
index 0000000..d54f2a9
--- /dev/null
+++ b/src/main/java/pintudos/game/service/TraceService.java
@@ -0,0 +1,22 @@
+package pintudos.game.service;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import pintudos.game.model.Trace;
+import pintudos.game.repository.TraceRepository;
+
+@Service
+public class TraceService {
+
+ @Autowired
+ private TraceRepository traceRepository;
+
+ public Trace saveTrace(Trace trace) {
+ return traceRepository.save(trace); // Guardamos el trazo
+ }
+
+ public List getTracesByRoom(String roomId) {
+ return traceRepository.findByRoomId(roomId); // Recuperamos los trazos de la sala
+ }
+}
diff --git a/src/main/java/pintudos/game/websocket/WebSocketConfig.java b/src/main/java/pintudos/game/websocket/WebSocketConfig.java
new file mode 100644
index 0000000..b958324
--- /dev/null
+++ b/src/main/java/pintudos/game/websocket/WebSocketConfig.java
@@ -0,0 +1,26 @@
+package pintudos.game.websocket;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.simp.config.MessageBrokerRegistry;
+import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
+import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
+import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
+
+@Configuration
+@EnableWebSocketMessageBroker
+public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
+
+ @Override
+ public void registerStompEndpoints(StompEndpointRegistry registry) {
+ registry
+ .addEndpoint("/game")
+ .setAllowedOrigins("http://localhost:5173") // frontend
+ .withSockJS(); // Esto activa los endpoints como /info, /websocket, etc.
+ }
+
+ @Override
+ public void configureMessageBroker(MessageBrokerRegistry registry) {
+ registry.enableSimpleBroker("/topic", "/queue");
+ registry.setApplicationDestinationPrefixes("/app");
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 2762482..438f7c9 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,2 @@
spring.application.name=game
+spring.data.mongodb.uri=mongodb+srv://diego:marzo245@universidad.lavtxfi.mongodb.net/pintudos?retryWrites=true&w=majority