forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
f8314e7de1
commit
1fedb9368d
76 files changed
+20556
-2523
No files matched your search
@@ -27,6 +27,8 @@ const ARTIFACTS = new Map([
|
||||
["party_configurations.csv", "text/csv; charset=utf-8"],
|
||||
["class_specs_across_parties.csv", "text/csv; charset=utf-8"],
|
||||
["class_abilities_across_parties.csv", "text/csv; charset=utf-8"],
|
||||
["npc_class_specs_across_parties.csv", "text/csv; charset=utf-8"],
|
||||
["npc_class_abilities_across_parties.csv", "text/csv; charset=utf-8"],
|
||||
["class_spec_by_boss.csv", "text/csv; charset=utf-8"],
|
||||
["bosses_across_parties.csv", "text/csv; charset=utf-8"],
|
||||
["boss_by_party.csv", "text/csv; charset=utf-8"],
|
||||
@@ -55,6 +57,9 @@ export function normalizeBalanceLabJobSpec(input) {
|
||||
if (!SPEC_SELECTIONS.has(specSelection)) {
|
||||
throw new GameDatabaseError("Class/spec selection must be random, all, or specific.", 400, "invalid_balance_lab_job");
|
||||
}
|
||||
if (input?.includeBetaSpecs !== undefined && typeof input.includeBetaSpecs !== "boolean") {
|
||||
throw new GameDatabaseError("Include Beta Specs must be boolean.", 400, "invalid_balance_lab_job");
|
||||
}
|
||||
const rawBossKeys = Array.isArray(input?.bossKeys) ? input.bossKeys : [];
|
||||
if (rawBossKeys.length > 500) {
|
||||
throw new GameDatabaseError("Select no more than 500 bosses.", 400, "invalid_balance_lab_job");
|
||||
@@ -85,6 +90,8 @@ export function normalizeBalanceLabJobSpec(input) {
|
||||
partySeed: integer(input?.partySeed ?? 1, "Party seed", -2_147_483_648, 2_147_483_647),
|
||||
bossCategory,
|
||||
bossKeys: Object.freeze(bossKeys),
|
||||
seatSweep: input?.seatSweep === true,
|
||||
includeBetaSpecs: input?.includeBetaSpecs === true,
|
||||
});
|
||||
const sourceCount = spec.source === "all" ? 3 : 1;
|
||||
const bossEstimate = Math.max(1, spec.bossKeys.length || (spec.bossCategory === "all" ? 500 : 300));
|
||||
@@ -93,7 +100,7 @@ export function normalizeBalanceLabJobSpec(input) {
|
||||
: spec.specSelection === "specific"
|
||||
? Math.max(spec.partyConfigurations, spec.selectedBuildIds.length)
|
||||
: Math.max(spec.partyConfigurations, spec.source === "all" ? 100 : 50);
|
||||
const estimatedRuns = partyEstimate * spec.simulationsPerParty * bossEstimate;
|
||||
const estimatedRuns = partyEstimate * (spec.seatSweep ? 5 : 1) * spec.simulationsPerParty * bossEstimate;
|
||||
if (estimatedRuns > 250_000) {
|
||||
throw new GameDatabaseError(
|
||||
"That job is too large for one server request. Reduce parties, simulations, or selected bosses.",
|
||||
@@ -136,6 +143,10 @@ export function balanceLabCommand(spec, outputDir, options = {}) {
|
||||
];
|
||||
for (const buildId of spec.selectedBuildIds) args.push("--spec", buildId);
|
||||
for (const bossKey of spec.bossKeys) args.push("--boss", bossKey);
|
||||
if (spec.seatSweep) args.push("--seat-sweep");
|
||||
if (spec.includeBetaSpecs) args.push("--include-beta-specs");
|
||||
if (options.cooldownPolicyPath) args.push("--cooldown-policy", options.cooldownPolicyPath);
|
||||
if (options.readinessPolicyPath) args.push("--companion-readiness-policy", options.readinessPolicyPath);
|
||||
return { executable, args, cwd: projectRoot };
|
||||
}
|
||||
|
||||
@@ -198,6 +209,8 @@ function reportSummary(outputDir) {
|
||||
runs: Number(summary.runs) || 0,
|
||||
classSpecs: Number(summary.classSpecs) || 0,
|
||||
classAbilities: Number(summary.classAbilities) || 0,
|
||||
npcClassSpecs: Number(summary.npcClassSpecs) || 0,
|
||||
npcClassAbilities: Number(summary.npcClassAbilities) || 0,
|
||||
bossPressureMedianDtps: Number(summary.bossPressureMedianDtps) || 0,
|
||||
};
|
||||
} catch {
|
||||
@@ -206,9 +219,10 @@ function reportSummary(outputDir) {
|
||||
}
|
||||
|
||||
function expectedPartyConfigurations(spec) {
|
||||
return spec.specSelection === "random"
|
||||
const parties = spec.specSelection === "random"
|
||||
? spec.partyConfigurations * (spec.source === "all" ? 3 : 1)
|
||||
: spec.partyConfigurations;
|
||||
return parties * (spec.seatSweep ? 5 : 1);
|
||||
}
|
||||
|
||||
function lineCollector(onLine) {
|
||||
@@ -249,6 +263,8 @@ export function createBalanceLabJobService(options = {}) {
|
||||
? Math.min(200, Math.floor(configuredQueueLimit))
|
||||
: 100;
|
||||
const launch = options.spawnProcess ?? spawn;
|
||||
const cooldownPolicyProvider = options.cooldownPolicyProvider;
|
||||
const readinessPolicyProvider = options.readinessPolicyProvider;
|
||||
const pythonExecutable = String(options.pythonExecutable
|
||||
?? process.env.BALANCE_LAB_PYTHON
|
||||
?? (process.platform === "win32" ? "python" : "python3"));
|
||||
@@ -390,6 +406,8 @@ export function createBalanceLabJobService(options = {}) {
|
||||
const command = balanceLabCommand(job.spec, job.outputDir, {
|
||||
projectRoot,
|
||||
pythonExecutable,
|
||||
cooldownPolicyPath: job.cooldownPolicyPath,
|
||||
readinessPolicyPath: job.readinessPolicyPath,
|
||||
});
|
||||
const child = launch(command.executable, command.args, {
|
||||
cwd: command.cwd,
|
||||
@@ -467,6 +485,16 @@ export function createBalanceLabJobService(options = {}) {
|
||||
const id = randomUUID();
|
||||
const outputDir = path.join(jobsDir, id);
|
||||
mkdirSync(outputDir, { recursive: true });
|
||||
const cooldownPolicyPath = path.join(outputDir, "companion-cooldown-policy.json");
|
||||
if (cooldownPolicyProvider) {
|
||||
const published = cooldownPolicyProvider();
|
||||
writeFileSync(cooldownPolicyPath, `${JSON.stringify(published.config ?? published, null, 2)}\n`, "utf8");
|
||||
}
|
||||
const readinessPolicyPath = path.join(outputDir, "companion-spec-readiness.json");
|
||||
if (readinessPolicyProvider) {
|
||||
const published = readinessPolicyProvider();
|
||||
writeFileSync(readinessPolicyPath, `${JSON.stringify(published, null, 2)}\n`, "utf8");
|
||||
}
|
||||
const totalParties = expectedPartyConfigurations(spec);
|
||||
const job = {
|
||||
id,
|
||||
@@ -488,6 +516,8 @@ export function createBalanceLabJobService(options = {}) {
|
||||
logTail: [],
|
||||
summary: null,
|
||||
outputDir,
|
||||
cooldownPolicyPath: cooldownPolicyProvider ? cooldownPolicyPath : null,
|
||||
readinessPolicyPath: readinessPolicyProvider ? readinessPolicyPath : null,
|
||||
};
|
||||
jobs.set(id, job);
|
||||
persistJob(job);
|
||||
|
||||
Reference in new issue
Block a user