Skip to content

Instantly share code, notes, and snippets.

@jswny
Created May 31, 2022 04:18
Show Gist options
  • Save jswny/623a4c7678ba6cd0966b7f2c9e8acedb to your computer and use it in GitHub Desktop.
Save jswny/623a4c7678ba6cd0966b7f2c9e8acedb to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Poker Now HUD
// @namespace http://j1.io/
// @version 0.1
// @description HUD for Poker Now
// @author You
// @match https://www.pokernow.club/games/*
// @icon https://cdn.pokernow.club/favicon-cd2bc2773f4f49ce85f0.png
// @grant none
// ==/UserScript==
(function () {
"use strict";
console.debug("Loading HUD...");
const gameId = getGameId();
console.debug(`Game ID: ${gameId}`);
const inititalInterval = 500;
const regularInterval = 5000;
setTimeout(setPlayerInfoOverflows, inititalInterval);
setTimeout(refreshHud, inititalInterval, gameId);
setInterval(refreshHud, regularInterval, gameId);
})();
function getGameId() {
const path = window.location.pathname;
const gameIdRegex = /\/games\/(.*)/;
const matches = path.match(gameIdRegex);
return matches[1];
}
function getPlayerElements() {
return document.getElementsByClassName("table-player");
}
function setPlayerInfoOverflows() {
const playerInfoElements = document.querySelectorAll(
".table-player-infos-ctn"
);
playerInfoElements.forEach((element) => {
element.style.overflow = "visible";
});
}
function refreshHud(gameId) {
fetchLogEntries(gameId)
.then(parseBeginningOfHandIndex)
.then(([entries, index]) => parseStreets(entries, index))
.then(parseMovesByPlayer)
.then(hydrateHud);
}
function fetchLogEntries(gameId) {
const logUrl = `https://www.pokernow.club/games/${gameId}/log?before_at=&after_at=&mm=false&v=2`;
return fetch(logUrl)
.then((response) => response.json())
.then((data) => data.logs);
}
function parseBeginningOfHandIndex(entries) {
const beginningOfHandEntryIndex = entries.findIndex((entry) =>
entry.msg.includes("-- starting hand")
);
const numMoves = beginningOfHandEntryIndex + 1;
console.debug(`Found ${numMoves} moves from the current hand`);
return [entries, beginningOfHandEntryIndex];
}
function parseStreets(entries, beginningOfHandEntryIndex) {
console.debug("Parsing streets...");
let movesByStreet = new Map();
let currentStreet = "PF";
let currentStreetMoves = [];
for (let i = beginningOfHandEntryIndex; i >= 0; i--) {
const entryMessage = entries[i].msg;
let streetChange = false;
let previousStreet = currentStreet;
if (entryMessage.includes("Flop: ")) {
currentStreet = "FL";
streetChange = true;
} else if (entryMessage.includes("Turn: ")) {
currentStreet = "TU";
streetChange = true;
} else if (entryMessage.includes("River: ")) {
currentStreet = "RV";
streetChange = true;
}
if (streetChange) {
movesByStreet.set(previousStreet, currentStreetMoves);
currentStreetMoves = [];
} else {
currentStreetMoves.push(entryMessage);
}
}
movesByStreet.set(currentStreet, currentStreetMoves);
return movesByStreet;
}
function parseMovesByPlayer(movesByStreet) {
console.debug("Parsing player moves...");
let movesByPlayer = new Map();
const nameRegex = /"([^|]+)"/;
for (const [streetName, moves] of movesByStreet) {
for (const move of moves) {
const nameMatches = move.match(nameRegex);
if (nameMatches != null) {
const playerName = nameMatches[1];
let playerMovesByStreet = movesByPlayer.get(playerName);
if (playerMovesByStreet) {
const playerStreetMoves = playerMovesByStreet.get(streetName);
if (playerStreetMoves) {
playerStreetMoves.push(move);
} else {
playerMovesByStreet.set(streetName, [move]);
}
} else {
playerMovesByStreet = new Map();
playerMovesByStreet.set(streetName, [move]);
movesByPlayer.set(playerName, playerMovesByStreet);
}
}
}
}
console.debug(movesByPlayer);
return movesByPlayer;
}
function hydrateHud(movesByPlayer) {
const playerElements = getPlayerElements();
console.debug(`Hydrating HUD for ${playerElements.length} players...`);
const nameRegex = /(.*) @/;
for (const playerElement of playerElements) {
const playerName =
playerElement.querySelector(".table-player-name").innerText;
let playerMoves = [];
for (const [playerNameWithId, playerMovesByStreet] of movesByPlayer) {
const nameMatches = playerNameWithId.match(nameRegex);
if (nameMatches != null && nameMatches[1] == playerName) {
const existingMovesElement =
playerElement.querySelector("#player-moves");
if (existingMovesElement) {
existingMovesElement.remove();
}
const movesElement = buildMovesElementForPlayer(playerMovesByStreet);
const playerInfoElement = playerElement.querySelector(
".table-player-infos-ctn"
);
playerInfoElement.appendChild(movesElement);
}
}
}
}
function parseMoveToShorthand(move) {
const checkRegex = /.* checks/;
const betRegex = /.* bets (\d+)/;
const callRegex = /.* calls (\d+)/;
const raiseRegex = /.* raises to (\d+)/;
const checkMatch = move.match(checkRegex);
const betMatch = move.match(betRegex);
const callMatch = move.match(callRegex);
const raiseMatch = move.match(raiseRegex);
let shorthand = null;
if (checkMatch) {
shorthand = "Check";
} else if (betMatch) {
shorthand = `Bet ${betMatch[1]}`;
} else if (callMatch) {
shorthand = `Call ${callMatch[1]}`;
} else if (raiseMatch) {
shorthand = `Raise ${raiseMatch[1]}`;
}
return shorthand;
}
function buildMovesElementForPlayer(playerMovesByStreet) {
const movesElement = document.createElement("div");
movesElement.id = "player-moves";
movesElement.style.position = "absolute";
movesElement.style.left = "5.2rem";
movesElement.style.top = "2.6rem";
movesElement.style.width = "4.7rem";
movesElement.style.textAlign = "left";
movesElement.style.margin = "0px";
movesElement.style.right = "0px";
movesElement.style.lineHeight = "0.6rem";
movesElement.style.fontSize = "0.5rem";
movesElement.style.color = "rgb(232, 230, 227)";
movesElement.style.width = "auto";
addMovesElementContentForPlayer(playerMovesByStreet, movesElement);
return movesElement;
}
function addMovesElementContentForPlayer(playerMovesByStreet, movesElement) {
for (const [street, playerStreetMoves] of playerMovesByStreet) {
const shorthandMoves = playerStreetMoves
.slice()
.map(parseMoveToShorthand)
.filter((m) => m != null)
.join(", ");
let color;
switch (street) {
case "PF":
color = "lightblue";
break;
case "FL":
color = "green";
break;
case "TU":
color = "orange";
break;
case "RV":
color = "red";
break;
}
const shorthandMovesWithStreet = `${street}: ${shorthandMoves}`;
const playerStreetMovesElement = document.createElement("p");
playerStreetMovesElement.innerText = shorthandMovesWithStreet;
playerStreetMovesElement.style.color = color;
movesElement.appendChild(playerStreetMovesElement);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment