Last active
August 21, 2024 16:16
-
-
Save jtrussell/7539395bfc7b84888425b2f3c9c97ef7 to your computer and use it in GitHub Desktop.
TCO Tracker Lite
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name TCO Tracker Lite | |
// @namespace http://tampermonkey.net/ | |
// @version 0.2 | |
// @description Track your game states in TCO | |
// @author jtrussell | |
// @match https://thecrucible.online | |
// @match https://thecrucible.online/* | |
// @grant none | |
// ==/UserScript== | |
;(function () { | |
'use strict' | |
/** | |
* Flag to indicate whether or note we're currently tracking | |
*/ | |
let isTracking = false | |
/** | |
* The TCO Redux store | |
*/ | |
let theStore = null | |
// The socket.io instance that we'll be listening to | |
let theSocket = null | |
/** | |
* Grab the state of the game when tracking begins | |
* | |
* We may start tracking after the start of the game, when this happens our | |
* "updates" will be incomplete. | |
* */ | |
const initialGameState = {} | |
/** | |
* All game state events that come down the socket | |
* | |
* We'll ignore events that contain only log updates | |
*/ | |
const gameEvents = [] | |
window.SLW = window.SLW || {} | |
window.SLW.tcoTrackedInfo = gameEvents | |
const handleSocketEvent = (event) => { | |
const { messages, ...gameStateEvent } = event | |
if (Object.keys(gameStateEvent).length) { | |
gameEvents.push(gameStateEvent) | |
} | |
} | |
const isInGame = () => !!document.querySelector('.player-home-row-container') | |
const isGameOver = () => | |
document | |
.querySelector('.messages.panel') | |
?.textContent?.includes('has won the game') | |
const initStore = () => { | |
const el = document.querySelector('.gravatar') | |
const key = Object.keys(el).find((k) => /__reactInternalInstance/.test(k)) | |
let target = el[key] | |
let store | |
while (target.return) { | |
if (target.memoizedProps && target.memoizedProps.store) { | |
store = target.memoizedProps.store | |
break | |
} | |
target = target.return | |
} | |
theStore = store | |
window.SLW.theStore = theStore | |
} | |
const getSocketAsync = () => { | |
return new Promise((resolve, reject) => { | |
const interval = setInterval(() => { | |
try { | |
const state = theStore?.getState() | |
if (state?.games?.socket) { | |
clearInterval(interval) | |
const socket = state.games.socket | |
if (theSocket && socket !== theSocket) { | |
console.log('TCO Tracker Lite - Switching Game Sockets') | |
theSocket.off('gamestate', handleSocketEvent) | |
} | |
theSocket = socket | |
return resolve(socket) | |
} else { | |
return reject(new Error('Cannot find socket on state')) | |
} | |
} catch (e) { | |
reject(e) | |
} | |
}, 500) | |
}) | |
} | |
const startupTracker = () => { | |
try { | |
initStore() | |
return getSocketAsync().then((socket) => { | |
if (!isTracking) { | |
isTracking = true | |
console.log( | |
'TCO Tracker Lite - Tracking Events', | |
gameEvents, | |
theStore, | |
theSocket | |
) | |
socket.on('gamestate', handleSocketEvent) | |
} | |
}) | |
} catch (err) { | |
isTracking = false | |
theStore = null | |
theSocket = null | |
console.error('TCO Tracker Lite startup error') | |
console.error(err) | |
} | |
} | |
const shutdownTracker = () => { | |
isTracking = false | |
try { | |
initStore() | |
return getSocketAsync().then((socket) => { | |
if (isTracking) { | |
console.log('TCO Tracker Lite - Stopping Events') | |
socket.off('gamestate', handleSocketEvent) | |
} | |
}) | |
} catch (err) { | |
theSocket?.off('gamestate', handleSocketEvent) | |
console.error('TCO Tracker Lite shutdown error') | |
console.error(err) | |
} | |
} | |
const ensureTrackerIsRunning = () => { | |
if (!isTracking) { | |
startupTracker() | |
} | |
} | |
const ensureTrackerIsNotRunning = () => { | |
if (isTracking) { | |
shutdownTracker() | |
} | |
} | |
const stopTrackerAndSubmitData = () => { | |
shutdownTracker().then(() => { | |
console.log('TCO Tracker Lite - Stopping Events') | |
console.log(gameEvents, theStore) | |
}) | |
} | |
setInterval(() => { | |
if (isInGame()) { | |
if (!isGameOver()) { | |
ensureTrackerIsRunning() | |
} else if (isTracking) { | |
stopTrackerAndSubmitData() | |
} | |
} else { | |
ensureTrackerIsNotRunning() | |
} | |
}, 500) | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment