Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 80 additions & 70 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,75 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>pintudos</groupId>
<artifactId>game</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>game</name>
<description>This is a game similar to pictionari, which this project is the back of the game</description>
<url/>
<licenses>
<license/>
</licenses>
<developers>
<developer/>
</developers>
<scm>
<connection/>
<developerConnection/>
<tag/>
<url/>
</scm>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<modelVersion>4.0.0</modelVersion>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<groupId>pintudos</groupId>
<artifactId>game</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>game</name>
<description>This is a game similar to pictionari, which this project is the back of the game</description>

<properties>
<java.version>17</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<!-- Compilador Java configurado para release 17 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>17</release>
</configuration>
</plugin>

<!-- Plugin de Spring Boot -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>
7 changes: 3 additions & 4 deletions src/main/java/pintudos/game/GameApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
37 changes: 37 additions & 0 deletions src/main/java/pintudos/game/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
24 changes: 24 additions & 0 deletions src/main/java/pintudos/game/config/WebConfig.java
Original file line number Diff line number Diff line change
@@ -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
}
};
}
}
142 changes: 142 additions & 0 deletions src/main/java/pintudos/game/controller/ChatController.java
Original file line number Diff line number Diff line change
@@ -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<String> 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());
}
}
Loading