"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var battlesearch_exports = {}; __export(battlesearch_exports, { PM: () => PM, commands: () => commands, pages: () => pages, runBattleSearch: () => runBattleSearch }); module.exports = __toCommonJS(battlesearch_exports); var import_lib = require("../../lib"); var import_config_loader = require("../config-loader"); var path = __toESM(require("path")); var child_process = __toESM(require("child_process")); const BATTLESEARCH_PROCESS_TIMEOUT = 3 * 60 * 60 * 1e3; const MAX_BATTLESEARCH_PROCESSES = 1; async function runBattleSearch(userids, month, tierid, turnLimit) { const useRipgrep = await (0, import_config_loader.checkRipgrepAvailability)(); const pathString = `${month}/${tierid}/`; const results = {}; let files = []; try { files = await Monitor.logPath(pathString).readdir(); } catch (err) { if (err.code === "ENOENT") { return results; } throw err; } const [userid] = userids; files = files.filter((item) => item.startsWith(month)).map((item) => Monitor.logPath(`${month}/${tierid}/${item}`).path); if (useRipgrep) { const userUnion = userids.map((id) => `${[...id].join("[^a-zA-Z0-9]*")}[^a-zA-Z0-9]*`).join("|"); const regexString = userids.map((id) => `(.*?("p(1|2)":"(${userUnion})"))`).join(""); let output; try { output = await import_lib.ProcessManager.exec(["rg", "-i", regexString, "--no-line-number", "-tjson", ...files]); } catch { return results; } for (const line of output.stdout.split("\n").reverse()) { const [file, raw] = import_lib.Utils.splitFirst(line, ":"); if (!raw || !line) continue; const data = JSON.parse(raw); const day = file.split("/")[3]; if (!results[day]) { results[day] = { totalBattles: 0, totalWins: {}, totalOutcomes: userids.length > 1 ? [] : null, totalLosses: {}, totalTies: 0, timesBattled: {} }; } const p1id = toID(data.p1); const p2id = toID(data.p2); if (userids.length > 1) { if (userids.filter((item) => [p1id, p2id].includes(item)).length < userids.length) continue; } else { if (!(p1id === userid || p2id === userid)) continue; } if (turnLimit && data.turns > turnLimit) continue; if (!results[day]) { results[day] = { totalBattles: 0, totalWins: {}, totalOutcomes: userids.length > 1 ? [] : null, totalLosses: {}, totalTies: 0, timesBattled: {} }; } results[day].totalBattles++; const winnerid = toID(data.winner); const loser = winnerid === p1id ? p2id : p1id; if (userids.includes(winnerid)) { if (!results[day].totalWins[winnerid]) results[day].totalWins[winnerid] = 0; results[day].totalWins[winnerid]++; } else if (data.winner) { if (!results[day].totalLosses[loser]) results[day].totalLosses[loser] = 0; results[day].totalLosses[loser]++; } else { results[day].totalTies++; } for (const id of userids) { if (!results[day].totalLosses[id]) results[day].totalLosses[id] = 0; if (!results[day].totalWins[id]) results[day].totalWins[id] = 0; } const outcomes = results[day].totalOutcomes; if (outcomes) { outcomes.push({ won: winnerid, lost: loser, turns: data.turns }); } const foe = userids.length > 1 ? null : userid === toID(data.p1) ? toID(data.p2) : toID(data.p1); if (foe) { if (!results[day].timesBattled[foe]) results[day].timesBattled[foe] = 0; results[day].timesBattled[foe]++; } } return results; } for (const file of files) { const subFiles = (0, import_lib.FS)(`${file}`).readdirSync(); const day = file.split("/")[3]; for (const dayFile of subFiles) { const json = (0, import_lib.FS)(`${file}/${dayFile}`).readIfExistsSync(); const data = JSON.parse(json); const p1id = toID(data.p1); const p2id = toID(data.p2); if (userids.length > 1) { if (userids.filter((item) => item === p1id || item === p2id).length < userids.length) continue; } else { if (!(p1id === userid || p2id === userid)) continue; } if (turnLimit && data.turns > turnLimit) continue; if (!results[day]) { results[day] = { totalBattles: 0, totalWins: {}, totalOutcomes: [], totalLosses: {}, totalTies: 0, timesBattled: {} }; } results[day].totalBattles++; const winnerid = toID(data.winner); const loser = winnerid === p1id ? p2id : p1id; if (userids.includes(winnerid)) { if (!results[day].totalWins[winnerid]) results[day].totalWins[winnerid] = 0; results[day].totalWins[winnerid]++; } else if (data.winner) { if (!results[day].totalLosses[loser]) results[day].totalLosses[loser] = 0; results[day].totalLosses[loser]++; } else { results[day].totalTies++; } for (const id of userids) { if (!results[day].totalLosses[id]) results[day].totalLosses[id] = 0; if (!results[day].totalWins[id]) results[day].totalWins[id] = 0; } const outcomes = results[day].totalOutcomes; if (outcomes) { outcomes.push({ won: winnerid, lost: loser, turns: data.turns }); } const foe = userids.length > 1 ? null : userid === p1id ? p2id : p1id; if (foe) { if (!results[day].timesBattled[foe]) results[day].timesBattled[foe] = 0; results[day].timesBattled[foe]++; } } } return results; } function buildResults(data, userids, month, tierid, turnLimit) { let buf = `>view-battlesearch-${userids.join("-")}--${turnLimit}--${month}--${tierid}--confirm |init|html |title|[Battle Search][${userids.join("-")}][${tierid}][${month}] `; buf += `|pagehtml|
`; buf += `${tierid} battles on ${month} where `; buf += userids.length > 1 ? `the users ${userids.join(", ")} were players` : `the user ${userids[0]} was a player`; buf += turnLimit ? ` and the battle lasted less than ${turnLimit} turn${Chat.plural(turnLimit)}` : ""; buf += `:
Won | Lost | Turns |
---|---|---|
${won} | ${lost} | ${turns} |
`; const { totalWins, totalLosses } = dayStats; buf += `
${day}`; buf += ` | |
---|---|
Category | Number |
Total Battles | ${dayStats.totalBattles} |
Total Wins${userids.length > 1 ? ` (${id}) ` : ""} | ${totalWins[id]} |
Total Losses${userids.length > 1 ? ` (${id}) ` : ""} | ${totalLosses[id]} |
Opponent | Times Battled |
`; buf += `${foe}`; buf += ` | ${dayStats.timesBattled[foe]} |
Searching...
`; buf += `Userid${Chat.plural(userids)}: ${userids.join(", ")}
`; if (turnLimit) { buf += `Maximum Turns: ${turnLimit}`; } buf += `
`; const months = import_lib.Utils.sortBy( (await Monitor.logPath("/").readdir()).filter((f) => f.length === 7 && f.includes("-")), (name) => ({ reverse: name }) ); if (!month) { buf += `Please select a month:
Please select the tier to search:
Are you sure you want to run a battle search for for ${tierid} battles on ${month} `; buf += `where the ${userids.length > 1 ? `user(s) ${userids.join(", ")} were players` : `the user ${userid} was a player`}`; if (turnLimit) buf += ` and the battle lasted less than ${turnLimit} turn${Chat.plural(turnLimit)}`; buf += `?
`; return `${buf}`; } void fsBattleSearch(connection, userids, month, tierid, turnLimit); return `Searching for ${tierid} battles on ${month} where the ${userids.length > 1 ? `user(s) ${userids.join(", ")} were players` : `the user ${userid} was a player`} ` + (turnLimit ? `and the battle lasted less than ${turnLimit} turn${Chat.plural(turnLimit)}.` : "") + `
Loading... (this will take a while)