reconexio
This commit is contained in:
@@ -115,8 +115,12 @@ onMounted(async () => {
|
||||
const room = await colyseusService.joinLobby();
|
||||
colorInput.value = colyseusService.playerColor.value || '#667eea';
|
||||
|
||||
let resumed = false;
|
||||
const guardResume = () => { if (resumed) return true; resumed = true; return false; };
|
||||
|
||||
// Prefer reconnection token path to bypass locked rooms
|
||||
room.onMessage("resumeReconnection", async (data: any) => {
|
||||
if (guardResume()) return;
|
||||
try {
|
||||
await colyseusService.reconnectWithToken(data.token);
|
||||
// Leave lobby before navigating
|
||||
@@ -132,6 +136,7 @@ onMounted(async () => {
|
||||
|
||||
// Listen for server-initiated resume to existing game (fallback joinById)
|
||||
room.onMessage("resumeGame", async (data: any) => {
|
||||
if (guardResume()) return;
|
||||
try {
|
||||
const gameRoom = await colyseusService.joinGameRoom(data.roomId);
|
||||
// Leave lobby before navigating
|
||||
|
||||
@@ -368,12 +368,18 @@ adminRouter.post("/admin/shuffle-players", async (req: Request, res: Response) =
|
||||
|
||||
// 6. Assign players to rooms and roles randomly
|
||||
const assignments: { [roomId: string]: { p1: any; p2: any } } = {};
|
||||
// Shuffle rooms so pairs go to random rooms
|
||||
const shuffledRooms = [...roomsInfo];
|
||||
for (let i = shuffledRooms.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[shuffledRooms[i], shuffledRooms[j]] = [shuffledRooms[j], shuffledRooms[i]];
|
||||
}
|
||||
|
||||
for (let i = 0; i < playerGroups.length && i < roomsInfo.length; i++) {
|
||||
for (let i = 0; i < playerGroups.length && i < shuffledRooms.length; i++) {
|
||||
const group = playerGroups[i];
|
||||
const roomInfo = roomsInfo[i];
|
||||
const roomInfo = shuffledRooms[i];
|
||||
|
||||
// Randomly assign P1 and P2 roles
|
||||
// Randomize roles P1/P2
|
||||
const [player1, player2] = Math.random() < 0.5 ? [group[0], group[1]] : [group[1], group[0]];
|
||||
|
||||
assignments[roomInfo.roomId] = {
|
||||
@@ -393,6 +399,17 @@ adminRouter.post("/admin/shuffle-players", async (req: Request, res: Response) =
|
||||
.catch(error => console.error(`Failed to clear room ${room.roomId}:`, error))
|
||||
);
|
||||
|
||||
// Clear current-room and reconnection tokens for all players to avoid resume during shuffle
|
||||
try {
|
||||
allPlayers.forEach(p => {
|
||||
const u = p.uuid;
|
||||
if (u) {
|
||||
NameManager.getInstance().clearCurrentRoom(u);
|
||||
(NameManager.getInstance() as any).clearReconnectToken?.(u);
|
||||
}
|
||||
});
|
||||
} catch {}
|
||||
|
||||
await Promise.allSettled(clearPromises);
|
||||
|
||||
// 8. Wait a bit for rooms to clear, then assign new players
|
||||
|
||||
@@ -49,7 +49,7 @@ export class LobbyRoom extends Room<LobbyState> {
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
onJoin(client: Client, options: any) {
|
||||
async onJoin(client: Client, options: any) {
|
||||
console.log(`[LobbyRoom] ${client.sessionId} joined lobby with UUID: ${options.uuid}`);
|
||||
// Enforce UUID presence and allowlist (if configured)
|
||||
if (!options.uuid || !isUuidAllowed(options.uuid)) {
|
||||
@@ -62,32 +62,7 @@ export class LobbyRoom extends Room<LobbyState> {
|
||||
if (options.uuid) {
|
||||
this.sessionToUuid.set(client.sessionId, options.uuid);
|
||||
|
||||
// If this UUID has a current active game room assignment, redirect there
|
||||
try {
|
||||
const currentRoomId = NameManager.getInstance().getCurrentRoom(options.uuid);
|
||||
if (currentRoomId) {
|
||||
// Verify room exists and is not finished
|
||||
matchMaker.query({ roomId: currentRoomId }).then((rooms) => {
|
||||
const room = rooms[0];
|
||||
const status = room?.metadata?.gameStatus || "waiting";
|
||||
if (room && status !== "finished") {
|
||||
const token = NameManager.getInstance().getReconnectToken(options.uuid);
|
||||
if (token) {
|
||||
// Prefer reconnection token to bypass room lock
|
||||
client.send("resumeReconnection", { token });
|
||||
} else {
|
||||
// Fallback to joinById path
|
||||
client.send("resumeGame", { roomId: currentRoomId });
|
||||
}
|
||||
// Mark as in game on lobby state to avoid duplicate quickPlay
|
||||
const p = this.state.players.get(client.sessionId);
|
||||
if (p) p.inGame = true;
|
||||
return;
|
||||
}
|
||||
}).catch(() => {});
|
||||
}
|
||||
} catch {}
|
||||
|
||||
// (duplicate resume check removed; handled below with await)
|
||||
// Check for shuffle redirect FIRST
|
||||
if (NameManager.getInstance().isShuffleInProgress()) {
|
||||
const assignment = NameManager.getInstance().getPlayerRoomAssignment(options.uuid);
|
||||
@@ -123,6 +98,25 @@ export class LobbyRoom extends Room<LobbyState> {
|
||||
}
|
||||
}
|
||||
|
||||
// If not in shuffle, check if UUID has active current room to resume
|
||||
try {
|
||||
const currentRoomId = NameManager.getInstance().getCurrentRoom(options.uuid);
|
||||
if (currentRoomId) {
|
||||
const rooms = await matchMaker.query({ roomId: currentRoomId });
|
||||
const room = rooms[0];
|
||||
const status = room?.metadata?.gameStatus || "waiting";
|
||||
if (room && status !== "finished") {
|
||||
const token = NameManager.getInstance().getReconnectToken(options.uuid);
|
||||
if (token) {
|
||||
client.send("resumeReconnection", { token });
|
||||
} else {
|
||||
client.send("resumeGame", { roomId: currentRoomId });
|
||||
}
|
||||
return; // Don't proceed with normal lobby join
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
// Normal lobby join flow
|
||||
// Check if this UUID already has a name
|
||||
const existingName = NameManager.getInstance().getPlayerName(options.uuid);
|
||||
|
||||
@@ -45,7 +45,11 @@ export class LobbyState extends Schema {
|
||||
}
|
||||
|
||||
removePlayer(sessionId: string): void {
|
||||
this.players.delete(sessionId);
|
||||
try {
|
||||
if (this.players.has(sessionId)) {
|
||||
this.players.delete(sessionId);
|
||||
}
|
||||
} catch {}
|
||||
this.totalPlayers = this.players.size;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user