SyntaxSquad/DADProject#16 fix: i forgot this
This commit is contained in:
+135
-115
@@ -5,134 +5,154 @@ import axios from "axios";
|
||||
const API_URL = "http://localhost:8000/api/v1";
|
||||
|
||||
export default (io, socket) => {
|
||||
const createMatchEmitter = (matchId) => (eventName, payload) => {
|
||||
io.to(`match_${matchId}`).emit(eventName, payload);
|
||||
};
|
||||
|
||||
const broadcastMatchUpdate = (matchId, match) => {
|
||||
const roomName = `match_${matchId}`;
|
||||
const room = io.sockets.adapter.rooms.get(roomName);
|
||||
if (room) {
|
||||
for (const socketId of room) {
|
||||
const clientSocket = io.sockets.sockets.get(socketId);
|
||||
if (!clientSocket || !clientSocket.user) continue;
|
||||
const userId = clientSocket.user.id;
|
||||
const publicState = match.getPublicState();
|
||||
const gameState = match.getGameState(userId);
|
||||
clientSocket.emit("match:update", { ...publicState, game: gameState });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
socket.on("match:enter", async (data) => {
|
||||
const { matchId } = data;
|
||||
const createMatchEmitter = (matchId) => (eventName, payload) => {
|
||||
const match = getMatch(matchId);
|
||||
if (!match) return;
|
||||
|
||||
if (!socket.user || !socket.user.id) {
|
||||
return socket.emit("error", { message: "User not authenticated" });
|
||||
}
|
||||
if (eventName === 'match:new-round-start' || eventName === 'match:ended-signal') {
|
||||
broadcastMatchUpdate(matchId, match);
|
||||
} else if (eventName === 'match:round-ended') {
|
||||
io.to(`match_${matchId}`).emit('match:round-ended', payload);
|
||||
} else {
|
||||
io.to(`match_${matchId}`).emit(eventName, payload);
|
||||
}
|
||||
};
|
||||
|
||||
const userId = socket.user.id;
|
||||
const room = `match_${matchId}`;
|
||||
// --- FIX: Timer Callback ---
|
||||
const handleAutoPlay = (matchId) => (userId, cardId) => {
|
||||
const match = getMatch(matchId);
|
||||
if (!match || match.status !== "Playing") return;
|
||||
|
||||
let match = getMatch(matchId);
|
||||
console.log(`[Match ${matchId}] Auto-playing for User ${userId}`);
|
||||
const result = match.playCard(userId, cardId);
|
||||
|
||||
if (!match) {
|
||||
try {
|
||||
console.log(`A pedir match ${matchId} à API...`);
|
||||
const res = await axios.get(`${API_URL}/matches/${matchId}`, {
|
||||
headers: { Authorization: socket.token },
|
||||
});
|
||||
if (result && result.action === "trick_resolved") {
|
||||
io.to(`match_${matchId}`).emit("game:trick-end", result.trickResult);
|
||||
setTimeout(() => { broadcastMatchUpdate(matchId, match); }, 1500);
|
||||
} else {
|
||||
broadcastMatchUpdate(matchId, match);
|
||||
}
|
||||
};
|
||||
|
||||
const matchData = res.data.data || res.data;
|
||||
socket.on("match:enter", async (data) => {
|
||||
const { matchId } = data;
|
||||
if (!socket.user || !socket.user.id) return socket.emit("error", { message: "Auth failed" });
|
||||
const userId = socket.user.id;
|
||||
socket.activeMatchId = matchId;
|
||||
|
||||
match = new BiscaMatch(
|
||||
matchData,
|
||||
createMatchEmitter(matchId),
|
||||
socket.token
|
||||
);
|
||||
addMatch(match);
|
||||
console.log(`Match ${matchId} carregado em memória.`);
|
||||
} catch (e) {
|
||||
console.error("Erro ao carregar Match da API:", e.message);
|
||||
socket.emit("error", "Match not found or API error");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
match.token = socket.token;
|
||||
}
|
||||
const room = `match_${matchId}`;
|
||||
let match = getMatch(matchId);
|
||||
|
||||
if (match) {
|
||||
match.token = socket.token;
|
||||
}
|
||||
if (!match) {
|
||||
try {
|
||||
const res = await axios.get(`${API_URL}/matches/${matchId}`, {
|
||||
headers: { Authorization: socket.token || socket.handshake.auth.token },
|
||||
});
|
||||
const matchData = res.data.data || res.data;
|
||||
|
||||
// Pass handleAutoPlay to constructor
|
||||
match = new BiscaMatch(
|
||||
matchData,
|
||||
createMatchEmitter(matchId),
|
||||
socket.token,
|
||||
handleAutoPlay(matchId)
|
||||
);
|
||||
addMatch(match);
|
||||
} catch (e) {
|
||||
return socket.emit("error", "Match not found");
|
||||
}
|
||||
}
|
||||
match.emitStateCallback = createMatchEmitter(matchId);
|
||||
if (userId !== match.player1Id && match.player2Id === 1) await match.joinPlayer(userId, socket.user);
|
||||
|
||||
match.emitStateCallback = createMatchEmitter(matchId);
|
||||
socket.join(room);
|
||||
const publicState = match.getPublicState();
|
||||
const gameState = match.getGameState(userId);
|
||||
socket.emit("match:update", { ...publicState, game: gameState });
|
||||
if (match.status === 'Playing') broadcastMatchUpdate(matchId, match);
|
||||
});
|
||||
|
||||
if (userId !== match.player1Id && match.player2Id === 1) {
|
||||
console.log(`User ${userId} a substituir o Ghost no Match ${matchId}`);
|
||||
await match.joinPlayer(userId);
|
||||
}
|
||||
socket.on("game:play-card", (data) => {
|
||||
const { matchId, cardId } = data;
|
||||
const match = getMatch(matchId);
|
||||
if (!match || match.status !== "Playing") return;
|
||||
const result = match.playCard(socket.user.id, cardId);
|
||||
if (result && result.error) return socket.emit("error", { message: result.error });
|
||||
if (result && result.action === "trick_resolved") {
|
||||
io.to(`match_${matchId}`).emit("game:trick-end", result.trickResult);
|
||||
setTimeout(() => { broadcastMatchUpdate(matchId, match); }, 1500);
|
||||
} else {
|
||||
broadcastMatchUpdate(matchId, match);
|
||||
}
|
||||
});
|
||||
|
||||
socket.join(room);
|
||||
console.log(`Socket ${socket.id} entrou na sala ${room}`);
|
||||
socket.on("game:surrender", async ({ matchId }) => {
|
||||
const match = getMatch(matchId);
|
||||
if(!match || match.status !== "Playing") return;
|
||||
const userId = socket.user.id;
|
||||
console.log(`[Match ${matchId}] User ${userId} surrendered ROUND.`);
|
||||
const opponentId = match.player1Id == userId ? match.player2Id : match.player1Id;
|
||||
const result = {
|
||||
winnerId: opponentId,
|
||||
loserId: userId,
|
||||
isDraw: false,
|
||||
player1_id: match.player1Id,
|
||||
player2_id: match.player2Id,
|
||||
player1_points: match.player1Id == opponentId ? 91 : 0,
|
||||
player2_points: match.player2Id == opponentId ? 91 : 0,
|
||||
reason: 'surrender'
|
||||
};
|
||||
await match.handleGameEnd(result);
|
||||
});
|
||||
|
||||
if (match.status === "Playing") {
|
||||
socket.emit("match:update", match.getState());
|
||||
} else {
|
||||
socket.emit("match:waiting", { msg: "Waiting for opponent..." });
|
||||
}
|
||||
});
|
||||
socket.on("match:surrender", async ({ matchId }) => {
|
||||
const match = getMatch(matchId);
|
||||
if(!match || match.status !== "Playing") return;
|
||||
const userId = socket.user.id;
|
||||
|
||||
// FIX: Abort current game to remove ghost
|
||||
await match.abortCurrentGame(userId);
|
||||
|
||||
socket.on("game:play-card", (data) => {
|
||||
const { matchId, cardId } = data;
|
||||
const match = getMatch(matchId);
|
||||
console.log(`[Match ${matchId}] User ${userId} surrendered MATCH.`);
|
||||
const opponentId = match.player1Id == userId ? match.player2Id : match.player1Id;
|
||||
match.marks[opponentId] = 4;
|
||||
await match.finishMatch();
|
||||
broadcastMatchUpdate(matchId, match);
|
||||
});
|
||||
|
||||
if (!match || match.status !== "Playing") {
|
||||
console.log(
|
||||
"Tentativa de jogar sem match ativo ou match não encontrado."
|
||||
);
|
||||
return;
|
||||
}
|
||||
socket.on("disconnect", async () => {
|
||||
if (socket.activeMatchId) {
|
||||
const match = getMatch(socket.activeMatchId);
|
||||
if (match && match.status === 'Playing') {
|
||||
const userId = socket.user?.id;
|
||||
if (userId === match.player1Id || userId === match.player2Id) {
|
||||
console.log(`[Match ${match.id}] Player ${userId} disconnected.`);
|
||||
|
||||
// FIX: Abort current game
|
||||
await match.abortCurrentGame(userId);
|
||||
|
||||
const result = match.playCard(socket.user.id, cardId);
|
||||
|
||||
if (result && result.error) {
|
||||
console.log(
|
||||
`❌ [Erro Jogo] User ${socket.user.id} tentou jogar carta ${cardId} mas: ${result.error}`
|
||||
);
|
||||
|
||||
socket.emit("error", { message: result.error });
|
||||
return;
|
||||
}
|
||||
|
||||
if (match.currentGame) {
|
||||
io.to(`match_${matchId}`).emit(
|
||||
"game:update",
|
||||
match.currentGame.getStateForPlayer(socket.user.id)
|
||||
);
|
||||
}
|
||||
});
|
||||
socket.on("debug:end-game", async (data) => {
|
||||
const { matchId } = data;
|
||||
const match = getMatch(matchId);
|
||||
if (match) {
|
||||
console.log(`[DEBUG] User ${socket.user.id} a forçar fim de jogo.`);
|
||||
// Simula que o user que clicou ganhou 120 pontos
|
||||
const winnerId = socket.user.id;
|
||||
const loserId =
|
||||
winnerId == match.player1Id ? match.player2Id : match.player1Id;
|
||||
|
||||
// Objeto de resultado falso para fechar o jogo
|
||||
const fakeResult = {
|
||||
winnerId: winnerId,
|
||||
loserId: loserId,
|
||||
isDraw: false,
|
||||
player1_points: winnerId == match.player1Id ? 120 : 0,
|
||||
player2_points: winnerId == match.player2Id ? 120 : 0,
|
||||
player1_id: match.player1Id,
|
||||
player2_id: match.player2Id,
|
||||
};
|
||||
|
||||
await match.handleGameEnd(fakeResult);
|
||||
}
|
||||
});
|
||||
|
||||
// DEBUG: Forçar fim do Match Completo
|
||||
socket.on("debug:end-match", async (data) => {
|
||||
const { matchId } = data;
|
||||
const match = getMatch(matchId);
|
||||
if (match) {
|
||||
console.log(`[DEBUG] User ${socket.user.id} a forçar fim de MATCH.`);
|
||||
// Dá 4 marcas a quem clicou
|
||||
match.marks[socket.user.id] = 4;
|
||||
await match.finishMatch();
|
||||
|
||||
// Emite o estado final
|
||||
io.to(`match_${matchId}`).emit("match:ended", match.getState());
|
||||
}
|
||||
});
|
||||
const opponentId = match.player1Id == userId ? match.player2Id : match.player1Id;
|
||||
match.marks[opponentId] = 4;
|
||||
await match.finishMatch();
|
||||
broadcastMatchUpdate(match.id, match);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user