This commit is contained in:
2026-01-03 17:22:09 +00:00
parent 5ea8c0df23
commit 5b504d10bd
13 changed files with 581 additions and 480 deletions
+102 -66
View File
@@ -1,13 +1,13 @@
import BiscaGame from "../classes/BiscaGame.js";
import axios from "axios";
const API_URL = "http://localhost:8000/api/v1";
const API_URL = process.env.API_URL || "http://localhost:8000/api/v1";
class BiscaMatch {
constructor(apiData, emitStateCallback, token, autoPlayCallback) {
this.id = apiData.id;
this.emitStateCallback = emitStateCallback;
this.autoPlayCallback = autoPlayCallback;
this.autoPlayCallback = autoPlayCallback;
this.token = token;
this.stake = apiData.stake;
this.type = apiData.type;
@@ -52,10 +52,10 @@ class BiscaMatch {
getAuthHeaders() {
return {
headers: {
Authorization: this.token,
"Content-Type": "application/json",
"Accept": "application/json"
headers: {
Authorization: this.token,
"Content-Type": "application/json",
Accept: "application/json",
},
};
}
@@ -72,8 +72,12 @@ class BiscaMatch {
status: "Playing",
began_at: new Date().toISOString(),
};
const res = await axios.post(`${API_URL}/games`, payload, this.getAuthHeaders());
const res = await axios.post(
`${API_URL}/games`,
payload,
this.getAuthHeaders()
);
const gameData = res.data.game || res.data.data || res.data;
newGameDbId = gameData.id;
@@ -86,17 +90,19 @@ class BiscaMatch {
{ id: this.player1Id, name: p1Name },
{ id: this.player2Id, name: p2Name },
newGameDbId,
(result) => { this.handleGameEnd(result); }
(result) => {
this.handleGameEnd(result);
}
);
this.currentGame.init();
this.currentGame.startTurnTimer((uid, cid) => {
if (this.autoPlayCallback) this.autoPlayCallback(uid, cid);
if (this.autoPlayCallback) this.autoPlayCallback(uid, cid);
});
if (this.emitStateCallback) {
this.emitStateCallback("match:new-round-start", null);
this.emitStateCallback("match:new-round-start", null);
}
} catch (e) {
console.error(`❌ Start Game Error: ${e.message}`);
@@ -104,82 +110,104 @@ class BiscaMatch {
}
async abortCurrentGame(loserId) {
if (this.currentGame && this.currentGame.dbId) {
console.log(`[Match ${this.id}] Aborting Game #${this.currentGame.dbId}`);
try {
const winnerId = loserId == this.player1Id ? this.player2Id : this.player1Id;
const payload = {
status: "Ended",
winner_user_id: winnerId,
loser_user_id: loserId,
is_draw: false,
ended_at: new Date().toISOString(),
};
await axios.put(`${API_URL}/games/${this.currentGame.dbId}`, payload, this.getAuthHeaders());
} catch(e) { console.error("Error aborting game:", e.message); }
if (this.currentGame && this.currentGame.dbId) {
console.log(`[Match ${this.id}] Aborting Game #${this.currentGame.dbId}`);
try {
const winnerId =
loserId == this.player1Id ? this.player2Id : this.player1Id;
const payload = {
status: "Ended",
winner_user_id: winnerId,
loser_user_id: loserId,
is_draw: false,
ended_at: new Date().toISOString(),
};
await axios.put(
`${API_URL}/games/${this.currentGame.dbId}`,
payload,
this.getAuthHeaders()
);
} catch (e) {
console.error("Error aborting game:", e.message);
}
}
}
async handleGameEnd(result) {
console.log(`[Match ${this.id}] Round ended. Winner: ${result.winnerId}`);
if (this.points[result.player1_id] !== undefined) this.points[result.player1_id] += result.player1_points;
if (this.points[result.player2_id] !== undefined) this.points[result.player2_id] += result.player2_points;
if (this.points[result.player1_id] !== undefined)
this.points[result.player1_id] += result.player1_points;
if (this.points[result.player2_id] !== undefined)
this.points[result.player2_id] += result.player2_points;
if (this.currentGame && this.currentGame.dbId) {
try {
const payload = {
status: "Ended",
winner_user_id: result.winnerId,
loser_user_id: result.loserId,
is_draw: result.isDraw,
player1_points: result.player1_points,
player2_points: result.player2_points,
ended_at: new Date().toISOString(),
};
await axios.put(`${API_URL}/games/${this.currentGame.dbId}`, payload, this.getAuthHeaders());
} catch (e) { console.error("DB Game Update Error:", e.message); }
try {
const payload = {
status: "Ended",
winner_user_id: result.winnerId,
loser_user_id: result.loserId,
is_draw: result.isDraw,
player1_points: result.player1_points,
player2_points: result.player2_points,
ended_at: new Date().toISOString(),
};
await axios.put(
`${API_URL}/games/${this.currentGame.dbId}`,
payload,
this.getAuthHeaders()
);
} catch (e) {
console.error("DB Game Update Error:", e.message);
}
}
let marksToAdd = 0;
let roundWinnerId = result.winnerId;
if (roundWinnerId) {
const winningScore = roundWinnerId == result.player1_id ? result.player1_points : result.player2_points;
const winningScore =
roundWinnerId == result.player1_id
? result.player1_points
: result.player2_points;
if (winningScore === 120) marksToAdd = 4;
else if (winningScore > 90) marksToAdd = 2;
else if (winningScore >= 60) marksToAdd = 1;
if (this.marks[roundWinnerId] !== undefined) this.marks[roundWinnerId] += marksToAdd;
if (this.marks[roundWinnerId] !== undefined)
this.marks[roundWinnerId] += marksToAdd;
}
if (this.emitStateCallback) {
this.emitStateCallback("match:round-ended", {
winnerId: roundWinnerId,
marksAdded: marksToAdd,
p1Points: result.player1_points,
p2Points: result.player2_points,
p1Marks: this.marks[this.player1Id],
p2Marks: this.marks[this.player2Id],
reason: result.reason || 'points'
});
this.emitStateCallback("match:round-ended", {
winnerId: roundWinnerId,
marksAdded: marksToAdd,
p1Points: result.player1_points,
p2Points: result.player2_points,
p1Marks: this.marks[this.player1Id],
p2Marks: this.marks[this.player2Id],
reason: result.reason || "points",
});
}
if (this.marks[this.player1Id] >= 4 || this.marks[this.player2Id] >= 4) {
await this.finishMatch();
if (this.emitStateCallback) this.emitStateCallback("match:ended-signal", null);
if (this.emitStateCallback)
this.emitStateCallback("match:ended-signal", null);
} else {
setTimeout(() => {
this.startNewGame();
this.startNewGame();
}, 1000);
}
}
async finishMatch() {
this.status = "Ended";
const winnerId = this.marks[this.player1Id] >= 4 ? this.player1Id : this.player2Id;
const loserId = winnerId == this.player1Id ? this.player2Id : this.player1Id;
const winnerId =
this.marks[this.player1Id] >= 4 ? this.player1Id : this.player2Id;
const loserId =
winnerId == this.player1Id ? this.player2Id : this.player1Id;
const payload = {
status: "Ended",
@@ -192,7 +220,11 @@ class BiscaMatch {
};
try {
await axios.put(`${API_URL}/matches/${this.id}`, payload, this.getAuthHeaders());
await axios.put(
`${API_URL}/matches/${this.id}`,
payload,
this.getAuthHeaders()
);
console.log(`[Match ${this.id}] Match Closed in DB.`);
} catch (e) {
console.error(`Match Close Error: ${e.message}`);
@@ -201,21 +233,25 @@ class BiscaMatch {
playCard(userId, cardId) {
if (!this.currentGame || this.status !== "Playing") return;
const result = this.currentGame.playCard(userId, cardId);
if (result && (result.action === 'next_turn' || result.action === 'trick_resolved')) {
this.currentGame.startTurnTimer((uid, cid) => {
if (this.autoPlayCallback) this.autoPlayCallback(uid, cid);
});
if (
result &&
(result.action === "next_turn" || result.action === "trick_resolved")
) {
this.currentGame.startTurnTimer((uid, cid) => {
if (this.autoPlayCallback) this.autoPlayCallback(uid, cid);
});
}
return result;
}
getGameState(userId) {
if (!this.currentGame) return null;
if (this.currentGame.players[userId]) return this.currentGame.getStateForPlayer(userId);
if (this.currentGame.players[userId])
return this.currentGame.getStateForPlayer(userId);
return null;
}
@@ -226,7 +262,7 @@ class BiscaMatch {
marks: this.marks,
points: this.points,
player1: this.player1,
player2: this.player2
player2: this.player2,
};
}
}