-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfirebase-game-flow.js
More file actions
98 lines (87 loc) · 4.05 KB
/
Copy pathfirebase-game-flow.js
File metadata and controls
98 lines (87 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Game-flow methods mixed into RealtimeUpdates.
// These are the methods that own the phase state machine and the
// ready-to-start/stop handshake. This is where the phase-2 start bug lives —
// having it isolated here makes reads and writes of `started` trivially visible.
//
// Depends on: window.grid, window.currentBotId, window.userId,
// window.startMovingBot, window.stopMovingBot,
// window.showWaitModal, window.hideWaitModal, window.body
import { set, update, remove, ref } from "https://www.gstatic.com/firebasejs/9.22.0/firebase-database.js";
import { db } from "./firebase-init.js";
export function mixinGameFlow(RealtimeUpdatesClass) {
const proto = RealtimeUpdatesClass.prototype;
proto.stop_moving_bot = function () {
const body = document.getElementById("body");
body.removeAttribute("show-other-user-ready");
body.removeAttribute("is-waiting-for-users");
const botId = window.currentBotId;
if (botId == null) return;
console.log(`Trying to stop ${botId}`);
if (window.stopMovingBot) window.stopMovingBot(botId, { fromSocket: true });
};
proto.start_game_for_everyone = async function () {
console.log(`[START_GAME] called. curr_page="${this.curr_page}" phaseStartTimeRef=`, this.phaseStartTimeRef ? "set" : "NULL");
if (window.hideWaitModal) window.hideWaitModal();
const body = document.getElementById("body");
body.removeAttribute("show-other-user-ready");
if (this.curr_page === "final_game" && this.phaseStartTimeRef) {
const ts = Date.now();
console.log(`[START_GAME] writing phase_start_time=`, ts);
set(this.phaseStartTimeRef, ts);
} else {
console.warn(`[START_GAME] NOT writing phase_start_time — curr_page="${this.curr_page}" phaseStartTimeRef=`, this.phaseStartTimeRef);
}
if (window.startMovingBot) await window.startMovingBot(window.currentBotId);
};
proto.replace_bot_ready_to_start = function (data) {
const { bot } = data;
const is_ready = bot.is_ready_to_start ? true : null;
update(this.startedGameRef, { [window.userId]: is_ready });
const body = document.getElementById("body");
if (bot.id !== window.currentBotId) {
if (bot.is_ready_to_start) {
body.setAttribute("show-other-user-ready", "");
} else {
body.removeAttribute("show-other-user-ready");
}
}
};
proto.stop_moving = function (_data) {
set(this.startedGameRef, {});
};
proto.claim_bot = function (template_id) {
if (!this.claimedBotsRef) return;
update(this.claimedBotsRef, { [window.userId]: template_id });
};
proto.unclaim_bot = function () {
if (!this.claimedBotsRef) return;
remove(ref(db, `rooms/${this.current_room}/final_game/claimed_bots/${window.userId}`));
};
proto.claim_dijkstra = function () {
if (!this.dijkstraOwnerRef) return;
set(this.dijkstraOwnerRef, window.userId);
};
proto.advance_phase = function (nextPhase) {
console.log(`[ADVANCE_PHASE] advancing to phase`, nextPhase);
// "started" is intentionally NOT cleared here — each client clears only its
// own entry via clear_own_started() when onPhaseChanged fires. Clearing
// everything here caused a race where player A's signal was wiped before
// player B had a chance to see it.
update(ref(db, `rooms/${this.current_room}/final_game`), {
phase: nextPhase,
phase_start_time: null,
dijkstra_owner: null,
}).then(() => console.log(`[ADVANCE_PHASE] Firebase update complete for phase`, nextPhase))
.catch(err => console.error(`[ADVANCE_PHASE] Firebase update FAILED`, err));
};
proto.clear_own_started = function () {
if (!this.startedGameRef) return;
update(this.startedGameRef, { [window.userId]: null });
};
proto.clear_grid = function () {
set(ref(db, `rooms/${this.current_room}/final_game/grid/coins`), {});
set(ref(db, `rooms/${this.current_room}/final_game/grid/obstacles`), {});
set(ref(db, `rooms/${this.current_room}/final_game/grid/bots`), {});
set(ref(db, `rooms/${this.current_room}/final_game/claimed_bots`), {});
};
}