-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathrealtimeFileReads.js
112 lines (94 loc) · 3.66 KB
/
realtimeFileReads.js
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
const { SlippiGame } = require("@slippi/slippi-js");
const chokidar = require("chokidar");
const _ = require("lodash");
const listenPath = process.argv[2];
console.log(`Listening at: ${listenPath}`);
const watcher = chokidar.watch(listenPath, {
ignored: "!*.slp", // TODO: This doesn't work. Use regex?
depth: 0,
persistent: true,
usePolling: true,
ignoreInitial: true,
});
const gameByPath = {};
watcher.on("change", (path) => {
const start = Date.now();
let gameState, settings, stats, frames, latestFrame, gameEnd;
try {
let game = _.get(gameByPath, [path, "game"]);
if (!game) {
console.log(`New file at: ${path}`);
// Make sure to enable `processOnTheFly` to get updated stats as the game progresses
game = new SlippiGame(path, { processOnTheFly: true });
gameByPath[path] = {
game: game,
state: {
settings: null,
detectedPunishes: {},
},
};
}
gameState = _.get(gameByPath, [path, "state"]);
settings = game.getSettings();
// You can uncomment the stats calculation below to get complex stats in real-time. The problem
// is that these calculations have not been made to operate only on new data yet so as
// the game gets longer, the calculation will take longer and longer
// stats = game.getStats();
frames = game.getFrames();
latestFrame = game.getLatestFrame();
gameEnd = game.getGameEnd();
} catch (err) {
console.log(err);
return;
}
if (!gameState.settings && settings) {
console.log(`[Game Start] New game has started`);
console.log(settings);
gameState.settings = settings;
}
console.log(`We have ${_.size(frames)} frames.`);
_.forEach(settings.players, (player) => {
const frameData = _.get(latestFrame, ["players", player.playerIndex]);
if (!frameData) {
return;
}
console.log(
`[Port ${player.port}] ${frameData.post.percent.toFixed(1)}% | ` + `${frameData.post.stocksRemaining} stocks`,
);
});
// Uncomment this if you uncomment the stats calculation above. See comment above for details
// // Do some conversion detection logging
// // console.log(stats);
// _.forEach(stats.conversions, conversion => {
// const key = `${conversion.playerIndex}-${conversion.startFrame}`;
// const detected = _.get(gameState, ['detectedPunishes', key]);
// if (!detected) {
// console.log(`[Punish Start] Frame ${conversion.startFrame} by player ${conversion.playerIndex + 1}`);
// gameState.detectedPunishes[key] = conversion;
// return;
// }
// // If punish was detected previously, but just ended, let's output that
// if (!detected.endFrame && conversion.endFrame) {
// const dmg = conversion.endPercent - conversion.startPercent;
// const dur = conversion.endFrame - conversion.startFrame;
// console.log(
// `[Punish End] Player ${conversion.playerIndex + 1}'s punish did ${dmg} damage ` +
// `with ${conversion.moves.length} moves over ${dur} frames`
// );
// }
// gameState.detectedPunishes[key] = conversion;
// });
if (gameEnd) {
// NOTE: These values and the quitter index will not work until 2.0.0 recording code is
// NOTE: used. This code has not been publicly released yet as it still has issues
const endTypes = {
1: "TIME!",
2: "GAME!",
7: "No Contest",
};
const endMessage = _.get(endTypes, gameEnd.gameEndMethod) || "Unknown";
const lrasText = gameEnd.gameEndMethod === 7 ? ` | Quitter Index: ${gameEnd.lrasInitiatorIndex}` : "";
console.log(`[Game Complete] Type: ${endMessage}${lrasText}`);
}
console.log(`Read took: ${Date.now() - start} ms`);
});