Spaces:
Build error
Build error
// statsHelper.js | |
import { getRequestHeaders, callPopup, token, chat } from "../script.js"; | |
import { humanizeGenTime } from "./RossAscends-mods.js"; | |
let charStats = {}; | |
/** | |
* Creates an HTML stat block. | |
* | |
* @param {string} statName - The name of the stat to be displayed. | |
* @param {number|string} statValue - The value of the stat to be displayed. | |
* @returns {string} - An HTML string representing the stat block. | |
*/ | |
function createStatBlock(statName, statValue) { | |
return `<div class="rm_stat_block"> | |
<div class="rm_stat_name">${statName}:</div> | |
<div class="rm_stat_value">${statValue}</div> | |
</div>`; | |
} | |
/** | |
* Verifies and returns a numerical stat value. If the provided stat is not a number, returns 0. | |
* | |
* @param {number|string} stat - The stat value to be checked and returned. | |
* @returns {number} - The stat value if it is a number, otherwise 0. | |
*/ | |
function verifyStatValue(stat) { | |
return isNaN(stat) ? 0 : stat; | |
} | |
/** | |
* Calculates total stats from character statistics. | |
* | |
* @param {Object} charStats - Object containing character statistics. | |
* @returns {Object} - Object containing total statistics. | |
*/ | |
function calculateTotalStats() { | |
let totalStats = { | |
total_gen_time: 0, | |
user_msg_count: 0, | |
non_user_msg_count: 0, | |
user_word_count: 0, | |
non_user_word_count: 0, | |
total_swipe_count: 0, | |
date_last_chat: 0, | |
date_first_chat: new Date("9999-12-31T23:59:59.999Z").getTime(), | |
}; | |
for (let stats of Object.values(charStats)) { | |
totalStats.total_gen_time += verifyStatValue(stats.total_gen_time); | |
totalStats.user_msg_count += verifyStatValue(stats.user_msg_count); | |
totalStats.non_user_msg_count += verifyStatValue( | |
stats.non_user_msg_count | |
); | |
totalStats.user_word_count += verifyStatValue(stats.user_word_count); | |
totalStats.non_user_word_count += verifyStatValue( | |
stats.non_user_word_count | |
); | |
totalStats.total_swipe_count += verifyStatValue( | |
stats.total_swipe_count | |
); | |
if (verifyStatValue(stats.date_last_chat) != 0) { | |
totalStats.date_last_chat = Math.max( | |
totalStats.date_last_chat, | |
stats.date_last_chat | |
); | |
} | |
if (verifyStatValue(stats.date_first_chat) != 0) { | |
totalStats.date_first_chat = Math.min( | |
totalStats.date_first_chat, | |
stats.date_first_chat | |
); | |
} | |
} | |
return totalStats; | |
} | |
/** | |
* Generates an HTML report of stats. | |
* | |
* This function creates an HTML report from the provided stats, including chat age, | |
* chat time, number of user messages and character messages, word count, and swipe count. | |
* The stat blocks are tailored depending on the stats type ("User" or "Character"). | |
* | |
* @param {string} statsType - The type of stats (e.g., "User", "Character"). | |
* @param {Object} stats - The stats data. Expected keys in this object include: | |
* total_gen_time - total generation time | |
* date_first_chat - timestamp of the first chat | |
* date_last_chat - timestamp of the most recent chat | |
* user_msg_count - count of user messages | |
* non_user_msg_count - count of non-user messages | |
* user_word_count - count of words used by the user | |
* non_user_word_count - count of words used by the non-user | |
* total_swipe_count - total swipe count | |
*/ | |
function createHtml(statsType, stats) { | |
// Get time string | |
let timeStirng = humanizeGenTime(stats.total_gen_time); | |
let chatAge = "Never"; | |
if (stats.date_first_chat < Date.now()) { | |
chatAge = moment | |
.duration(stats.date_last_chat - stats.date_first_chat) | |
.humanize(); | |
} | |
// Create popup HTML with stats | |
let html = `<h3>${statsType} Stats</h3>`; | |
if (statsType === "User") { | |
html += createStatBlock("Chatting Since", `${chatAge} ago`); | |
} else { | |
html += createStatBlock("First Interaction", `${chatAge} ago`); | |
} | |
html += createStatBlock("Chat Time", timeStirng); | |
html += createStatBlock("User Messages", stats.user_msg_count); | |
html += createStatBlock( | |
"Character Messages", | |
stats.non_user_msg_count - stats.total_swipe_count | |
); | |
html += createStatBlock("User Words", stats.user_word_count); | |
html += createStatBlock("Character Words", stats.non_user_word_count); | |
html += createStatBlock("Swipes", stats.total_swipe_count); | |
callPopup(html, "text"); | |
} | |
/** | |
* Handles the user stats by getting them from the server, calculating the total and generating the HTML report. | |
* | |
* @param {Object} charStats - Object containing character statistics. | |
*/ | |
async function userStatsHandler() { | |
// Get stats from server | |
await getStats(); | |
// Calculate total stats | |
let totalStats = calculateTotalStats(charStats); | |
// Create HTML with stats | |
createHtml("User", totalStats); | |
} | |
/** | |
* Handles the character stats by getting them from the server and generating the HTML report. | |
* | |
* @param {Object} charStats - Object containing character statistics. | |
* @param {Object} characters - Object containing character data. | |
* @param {string} this_chid - The character id. | |
*/ | |
async function characterStatsHandler(characters, this_chid) { | |
// Get stats from server | |
await getStats(); | |
// Get character stats | |
let myStats = charStats[characters[this_chid].avatar]; | |
if (myStats === undefined) { | |
myStats = { | |
total_gen_time: 0, | |
user_msg_count: 0, | |
non_user_msg_count: 0, | |
user_word_count: 0, | |
non_user_word_count: countWords(characters[this_chid].first_mes), | |
total_swipe_count: 0, | |
date_last_chat: 0, | |
date_first_chat: new Date("9999-12-31T23:59:59.999Z").getTime(), | |
}; | |
charStats[characters[this_chid].avatar] = myStats; | |
updateStats(); | |
} | |
// Create HTML with stats | |
createHtml("Character", myStats); | |
} | |
/** | |
* Fetches the character stats from the server. | |
* | |
* @param {Object} charStats - Object containing character statistics. | |
* @returns {Object} - Object containing fetched character statistics. | |
*/ | |
async function getStats() { | |
const response = await fetch("/getstats", { | |
method: "POST", | |
headers: getRequestHeaders(), | |
body: JSON.stringify({}), | |
cache: "no-cache", | |
}); | |
if (!response.ok) { | |
toastr.error("Stats could not be loaded. Try reloading the page."); | |
throw new Error("Error getting stats"); | |
} | |
charStats = await response.json(); | |
} | |
/** | |
* Calculates the generation time based on start and finish times. | |
* | |
* @param {string} gen_started - The start time in ISO 8601 format. | |
* @param {string} gen_finished - The finish time in ISO 8601 format. | |
* @returns {number} - The difference in time in milliseconds. | |
*/ | |
function calculateGenTime(gen_started, gen_finished) { | |
if (gen_started === undefined || gen_finished === undefined) { | |
return 0; | |
} | |
let startDate = new Date(gen_started); | |
let endDate = new Date(gen_finished); | |
return endDate - startDate; | |
} | |
/** | |
* Sends a POST request to the server to update the statistics. | |
* | |
* @param {Object} stats - The stats data to update. | |
*/ | |
async function updateStats() { | |
const response = await fetch("/updatestats", { | |
method: "POST", | |
headers: getRequestHeaders(), | |
body: JSON.stringify(charStats), | |
}); | |
if (response.status !== 200) { | |
console.error("Failed to update stats"); | |
console.log(response).status; | |
} | |
} | |
/** | |
* Returns the count of words in the given string. | |
* A word is a sequence of alphanumeric characters (including underscore). | |
* | |
* @param {string} str - The string to count words in. | |
* @returns {number} - Number of words. | |
*/ | |
function countWords(str) { | |
const match = str.match(/\b\w+\b/g); | |
return match ? match.length : 0; | |
} | |
/** | |
* Handles stat processing for messages. | |
* | |
* @param {Object} line - Object containing message data. | |
* @param {string} type - The type of the message processing (e.g., 'append', 'continue', 'appendFinal', 'swipe'). | |
* @param {Object} characters - Object containing character data. | |
* @param {string} this_chid - The character id. | |
* @param {Object} charStats - Object containing character statistics. | |
* @param {string} oldMesssage - The old message that's being processed. | |
*/ | |
async function statMesProcess(line, type, characters, this_chid, oldMesssage) { | |
if (this_chid === undefined) { | |
return; | |
} | |
await getStats(); | |
let stat = charStats[characters[this_chid].avatar]; | |
if (!stat) { | |
stat = { | |
total_gen_time: 0, | |
user_word_count: 0, | |
non_user_msg_count: 0, | |
user_msg_count: 0, | |
non_user_msg_count: 0, | |
total_swipe_count: 0, | |
date_first_chat: Date.now(), | |
date_last_chat: Date.now(), | |
}; | |
} | |
stat.total_gen_time += calculateGenTime( | |
line.gen_started, | |
line.gen_finished | |
); | |
if (line.is_user) { | |
if (type != "append" && type != "continue" && type != "appendFinal") { | |
stat.user_msg_count++; | |
stat.user_word_count += countWords(line.mes); | |
} else { | |
let oldLen = oldMesssage.split(" ").length; | |
stat.user_word_count += countWords(line.mes) - oldLen; | |
} | |
} else { | |
// if continue, don't add a message, get the last message and subtract it from the word count of | |
// the new message | |
if (type != "append" && type != "continue" && type != "appendFinal") { | |
stat.non_user_msg_count++; | |
stat.non_user_word_count += countWords(line.mes); | |
} else { | |
let oldLen = oldMesssage.split(" ").length; | |
stat.non_user_word_count += countWords(line.mes) - oldLen; | |
} | |
} | |
if (type === "swipe") { | |
stat.total_swipe_count++; | |
} | |
stat.date_last_chat = Date.now(); | |
stat.date_first_chat = Math.min( | |
stat.date_first_chat ?? new Date("9999-12-31T23:59:59.999Z").getTime(), | |
Date.now() | |
); | |
updateStats(); | |
} | |
export { userStatsHandler, characterStatsHandler, getStats, statMesProcess, charStats }; | |