-
Notifications
You must be signed in to change notification settings - Fork 1
/
dominion-log.js
120 lines (99 loc) · 2.9 KB
/
dominion-log.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
113
114
115
116
117
118
119
120
// ==UserScript==
// @name Dominion deck tracker
// @namespace https://ntsd.dev
// @version 0.1
// @description track dominion players deck by log
// @author ntsd
// @match https://dominion.games*
// @icon https://www.google.com/s2/favicons?sz=64&domain=dominion.games
// @grant none
// ==/UserScript==
const groupPlayer = 'player';
const groupAction = 'action';
const groupCount = 'count';
const groupCard = 'card';
const actionRegex = `(?<player>[A-Za-z ]+) (?<action>starts with|gains|trashes) (?<count>[0-9]+|a|an) (?<card>[A-Za-z\s]+).`;
const victoryScore = {
'curse': -1,
'estate': 1,
'duchy': 3,
'province': 6,
'colony': 12,
}
const treasure = {
'copper': 1,
'silver': 2,
'gold': 3,
'platinum': 4,
};
const matchAll = (str, re) => {
return [...str.matchAll(re)];
};
const parseCount = (str) => {
if (str === 'a' || str === 'an') return 1;
return parseInt(str);
}
const parseCard = (str) => {
// remove plural
if (str.at(-1) === 's') {
str = str.slice(0, -1);
}
return str.toLowerCase();
}
const run = () => {
const logContainer = document.getElementsByClassName('log-scroll-container')[0];
const chatContainer = document.getElementsByClassName('chat-scroll-container')[0];
let players = {};
const actions = matchAll(logContainer.textContent, actionRegex);
actions.forEach((matched) => {
let player = matched.groups[groupPlayer];
// the player suffic with ` buys and` when the action is `buy and gains`
if (player.endsWith(' buys and')) {
player = player.split(' buys and')[0]
}
// add player if not existing
if (!players[player]) {
players[player] = {
cards: {},
score: 0,
};
}
const action = matched.groups[groupAction];
let count = parseCount(matched.groups[groupCount]);
const card = parseCard(matched.groups[groupCard]);
// deduct if the action is `trashes`
if (action === 'trashes') {
count = -count;
}
// add card
if (players[player].cards[card]) {
players[player].cards[card] += count;
} else {
players[player].cards[card] = count;
}
// calculate score
if (victoryScore[card]) {
players[player].score += victoryScore[card] * count;
}
})
chatContainer.innerHTML = ''
for (const [name, player] of Object.entries(players)) {
chatContainer.innerHTML += `
<b>${name} (${player.score})</b>
<br/>
${JSON.stringify(player.cards)}
<br/>
`;
}
return players;
}
(function () {
'use strict';
setInterval(function () {
try {
run();
} catch (error) {
console.error(error);
}
}, 5000);
})();