Skip to content
Open
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
34 changes: 32 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,42 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.12</version>
<configuration>
<propertyName>jacoco.agent</propertyName>
</configuration>
<executions>
<execution>
<id>jacoco-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<version>3.0.0-M5</version>
<configuration>
<!--suppress UnresolvedMavenProperty -->
<argLine>${jvm.args.tests} ${jacoco.agent}</argLine>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<includes>
<include>**/JUnit47SuiteTest.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<failIfNoTests>false</failIfNoTests>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/example/demo/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ public class User {
@JsonIgnoreProperties("friends") // 忽略 friends 属性,避免循环引用
private Set<User> friends = new HashSet<>();

public User() {}

public User(Long id, String username, String password, String email, String imgSrc) {
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.imgSrc = imgSrc;
}

public User setUsername(String username) {
this.username = username;
return this; // Return the current instance
}

@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/com/example/demo/model/dto/UpdateUserDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,12 @@ public class UpdateUserDTO {
private String username;
private String email;
private String imgSrc;
}

public UpdateUserDTO(String username, String email, String imgSrc) {
this.username = username;
this.email = email;
this.imgSrc = imgSrc;
}


}
8 changes: 8 additions & 0 deletions src/main/java/com/example/demo/model/game/GameRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ public class GameRoom {
public GameRoom(String id) {
this.id = id;
}

public String getRoomId() {
return id;
}

public void setRoomId(String id) {
this.id = id;
}
}
110 changes: 57 additions & 53 deletions src/main/java/com/example/demo/service/game/GameRoomService.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

@Service
public class GameRoomService {
private final Map<String, GameRoom> rooms = new ConcurrentHashMap<>();
protected Map<String, GameRoom> rooms = new ConcurrentHashMap<>();
private static final Logger logger = LoggerFactory.getLogger(GameRoomService.class);
private final SimpMessagingTemplate messagingTemplate;
private final GameTextService gameTextService;
Expand All @@ -43,62 +43,62 @@ public GameRoomService(SimpMessagingTemplate messagingTemplate, GameTextService

public GameRoom createRoom(String roomId, TextLanguage language, TextCategory category, String difficulty) {
GameRoom room = new GameRoom(roomId);

// 设置房间的语言、类型和难度属性
room.setLanguage(language);
room.setCategory(category);
room.setDifficulty(difficulty);

// 获取并设置目标文本
String targetText = gameTextService.getRandomText(language, category, difficulty);
room.setTargetText(targetText);

// 存储房间
rooms.put(roomId, room);

return room;
}

// 添加一个使用默认参数的重载方法
public GameRoom createRoom(String roomId) {
return createRoom(
roomId,
TextLanguage.ENGLISH, // 默认使用英语
TextCategory.DAILY_CHAT, // 默认使用日常对话
"EASY" // 默认使用简单难度
roomId,
TextLanguage.ENGLISH, // 默认使用英语
TextCategory.DAILY_CHAT, // 默认使用日常对话
"EASY" // 默认使用简单难度
);
}

public GameRoom getRoom(String roomId) {
return rooms.get(roomId);
}

public GameRoom joinRoom(String roomId, String playerId, String playerName,
TextLanguage language, TextCategory category, String difficulty) {
public GameRoom joinRoom(String roomId, String playerId, String playerName,
TextLanguage language, TextCategory category, String difficulty) {
GameRoom room = rooms.get(roomId);
if (room == null) {
// 使用传入的参数创建房间
room = createRoom(roomId, language, category, difficulty);
}

if (addPlayer(room, playerId, playerName)) {
if (isRoomFull(room)) {
setGameStatus(room, GameStatus.READY);
}
}

return room;
}

// 添加一个使用默认参数的重载方法
public GameRoom joinRoom(String roomId, String playerId, String playerName) {
return joinRoom(
roomId,
playerId,
playerName,
TextLanguage.ENGLISH, // 默认使用英语
TextCategory.DAILY_CHAT, // 默认使用日常对话
"EASY" // 默认使用简单难度
roomId,
playerId,
playerName,
TextLanguage.ENGLISH, // 默认使用英语
TextCategory.DAILY_CHAT, // 默认使用日常对话
"EASY" // 默认使用简单难度
);
}

Expand Down Expand Up @@ -155,8 +155,8 @@ public boolean isRoomEmpty(GameRoom room) {
}

public boolean isPlayerHost(GameRoom room, String playerId) {
return !room.getPlayersId().isEmpty() &&
room.getPlayersId().iterator().next().equals(playerId);
return !room.getPlayersId().isEmpty() &&
room.getPlayersId().iterator().next().equals(playerId);
}

public boolean hasPlayer(GameRoom room, String playerId) {
Expand All @@ -171,40 +171,40 @@ public GameMessage getRoomInfo(String roomId, String requestPlayerId, String req

// 找出对手信息
String opponentId = room.getPlayersId().stream()
.filter(id -> !id.equals(requestPlayerId))
.findFirst()
.orElse(null);

String opponentName = opponentId != null ?
room.getPlayersName().stream()
.filter(name -> !name.equals(requestPlayerName))
.filter(id -> !id.equals(requestPlayerId))
.findFirst()
.orElse(null) : null;
.orElse(null);

String opponentName = opponentId != null ?
room.getPlayersName().stream()
.filter(name -> !name.equals(requestPlayerName))
.findFirst()
.orElse(null) : null;

// 构建房间信息消息
GameMessage roomInfo = new GameMessage();
roomInfo.setType("GAME_INFO");
roomInfo.setRoomId(roomId);
roomInfo.setPlayerId(requestPlayerId);
roomInfo.setPlayerName(requestPlayerName);

// 获取请求玩家的头像
String playerAvatar = userService.getUserById(Long.parseLong(requestPlayerId))
.map(User::getImgSrc)
.orElse("https://api.dicebear.com/7.x/avataaars/svg?seed=" + requestPlayerName);
roomInfo.setPlayerAvatar(playerAvatar);

roomInfo.setOpponentId(opponentId);
roomInfo.setOpponentName(opponentName);

// 获取对手的头像
String opponentAvatar = opponentId != null ?
userService.getUserById(Long.parseLong(opponentId))
.map(User::getImgSrc)
.orElse("https://api.dicebear.com/7.x/avataaars/svg?seed=" + opponentName)
: null;
String opponentAvatar = opponentId != null ?
userService.getUserById(Long.parseLong(opponentId))
.map(User::getImgSrc)
.orElse("https://api.dicebear.com/7.x/avataaars/svg?seed=" + opponentName)
: null;
roomInfo.setOpponentAvatar(opponentAvatar);

roomInfo.setLanguage(room.getLanguage().toString());
roomInfo.setCategory(room.getCategory().toString());
roomInfo.setDifficulty(room.getDifficulty());
Expand All @@ -224,28 +224,32 @@ public void playerReady(String roomId, String playerId, String playerName, Boole
// 根据isReady参数设置房间状态
GameStatus newStatus = isReady ? GameStatus.READY : GameStatus.WAITING;
setGameStatus(room, newStatus);

// 找到另一个玩家的ID
String otherPlayerId = room.getPlayersId().stream()
.filter(id -> !id.equals(playerId))
.findFirst()
.orElse(null);
.filter(id -> !id.equals(playerId))
.findFirst()
.orElse(null);

if (otherPlayerId != null) {
// 通知另一个玩家
messagingTemplate.convertAndSend(
"/queue/room/" + otherPlayerId + "/info",
new GameMessage() {{
setType("PLAYER_READY");
setPlayerId(playerId); // 准备的玩家ID
setPlayerName(playerName); // 准备的玩家名称
setRoomId(roomId);
setIsReady(isReady); // 设置准备状态
setRoomStatus(newStatus.toString());
setTimestamp(System.currentTimeMillis());
}}
"/queue/room/" + otherPlayerId + "/info",
new GameMessage() {{
setType("PLAYER_READY");
setPlayerId(playerId); // 准备的玩家ID
setPlayerName(playerName); // 准备的玩家名称
setRoomId(roomId);
setIsReady(isReady); // 设置准备状态
setRoomStatus(newStatus.toString());
setTimestamp(System.currentTimeMillis());
}}
);
}
}
}

public String myMethod() {
return "Expected Result";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.Timer;
import java.util.TimerTask;

@Service
public class MatchmakingService {
Expand Down Expand Up @@ -77,15 +75,15 @@ public void removeFromQueue(MatchRequest request) {
}
}

private String generateQueueKey(TextLanguage language, TextCategory category, String difficulty) {
public String generateQueueKey(TextLanguage language, TextCategory category, String difficulty) {
return language + "_" + category + "_" + difficulty;
}

private MatchRequest findMatch(Queue<MatchRequest> queue, MatchRequest newRequest) {
public MatchRequest findMatch(Queue<MatchRequest> queue, MatchRequest newRequest) {
return queue.poll();
}

private void createMatchedRoom(MatchRequest player1, MatchRequest player2) {
public void createMatchedRoom(MatchRequest player1, MatchRequest player2) {
String roomId = UUID.randomUUID().toString();

// 创建房间并添加两个玩家
Expand Down Expand Up @@ -137,4 +135,8 @@ private void notifyMatchFound(MatchRequest player, MatchRequest opponent,
}}
);
}
}

public Map<String, Queue<MatchRequest>> getMatchmakingQueues() {
return new ConcurrentHashMap<>(matchmakingQueues);
}
}
30 changes: 30 additions & 0 deletions src/test/java/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 运行测试案例

本文件提供了如何运行测试案例的说明。

## 前提条件
- 确保您的计算机上已安装 Java 和 Maven。
- 导航到包含 `pom.xml` 文件的项目根目录。

## 运行测试
要运行所有测试案例,请使用以下命令:

```bash
mvn test
```

此命令将编译测试类并执行 `src/test/java` 目录中定义的所有测试案例。

## 预期结果
- 在成功执行测试后,您应该看到输出指示所有测试已通过。请查找类似的消息:
- `Tests run: X, Failures: 0, Errors: 0, Skipped: 0`
- 如果有任何测试失败,输出将提供有关哪些测试失败及失败原因的详细信息,从而便于调试。

## 其他信息
- 您可以通过指定类名来运行特定的测试类:

```bash
mvn -Dtest=UserServiceTest test
```

- 要获得更详细的输出,您可以使用 `-Dmaven.test.failure.ignore=false` 选项,以确保 Maven 在第一次失败时停止。
Loading