mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-03 20:38:17 +03:00
Fixes Poor Code and Data Structures in common/class and ugs-class #88
This commit is contained in:
Generated
+3
-3
@@ -61,7 +61,7 @@ dependencies:
|
||||
express-session: 1.17.1
|
||||
fast-json-stable-hash: 1.0.2
|
||||
fast-xml-parser: 3.19.0
|
||||
kamaitachi-common: github.com/zkldi/Kamaitachi-common/dc01eb5b4759ce1e228b1aa204c4cc445954b70f
|
||||
kamaitachi-common: github.com/zkldi/Kamaitachi-common/5d9c31ce0b9b309182d40191ae3000a3e9083336
|
||||
mongodb: 3.6.6
|
||||
monk: 7.3.4
|
||||
multer: 1.4.2
|
||||
@@ -4344,8 +4344,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
github.com/zkldi/Kamaitachi-common/dc01eb5b4759ce1e228b1aa204c4cc445954b70f:
|
||||
resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/dc01eb5b4759ce1e228b1aa204c4cc445954b70f}
|
||||
github.com/zkldi/Kamaitachi-common/5d9c31ce0b9b309182d40191ae3000a3e9083336:
|
||||
resolution: {tarball: https://codeload.github.com/zkldi/Kamaitachi-common/tar.gz/5d9c31ce0b9b309182d40191ae3000a3e9083336}
|
||||
name: kamaitachi-common
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
|
||||
@@ -17,9 +17,9 @@ t.test("#UpdateUGSClasses", (t) => {
|
||||
});
|
||||
|
||||
t.test("Should call and merge the ClassHandler", async (t) => {
|
||||
const res = await UpdateUGSClasses("iidx", "SP", 1, {}, () => ({ foo: "bar" }), logger);
|
||||
const res = await UpdateUGSClasses("iidx", "SP", 1, {}, () => ({ dan: 2 }), logger);
|
||||
|
||||
t.strictSame(res, { foo: "bar" });
|
||||
t.strictSame(res, { dan: 2 });
|
||||
|
||||
t.end();
|
||||
});
|
||||
@@ -48,14 +48,14 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
t.beforeEach(ResetDBState);
|
||||
|
||||
t.test("Should return improved classes from null", (t) => {
|
||||
const res = CalculateClassDeltas("iidx", "SP", { dan: "kaiden" }, null, logger);
|
||||
const res = CalculateClassDeltas("SP", { dan: 18 }, null, logger);
|
||||
|
||||
t.strictSame(res, [
|
||||
{
|
||||
set: "dan",
|
||||
playtype: "SP",
|
||||
old: null,
|
||||
new: "kaiden",
|
||||
new: 18,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -64,9 +64,8 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
|
||||
t.test("Should return improved classes from null class", (t) => {
|
||||
const res = CalculateClassDeltas(
|
||||
"iidx",
|
||||
"SP",
|
||||
{ dan: "kaiden" },
|
||||
{ dan: 18 },
|
||||
{ classes: {} } as UserGameStats,
|
||||
logger
|
||||
);
|
||||
@@ -76,7 +75,7 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
set: "dan",
|
||||
playtype: "SP",
|
||||
old: null,
|
||||
new: "kaiden",
|
||||
new: 18,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -85,10 +84,9 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
|
||||
t.test("Should return improved classes", (t) => {
|
||||
const res = CalculateClassDeltas(
|
||||
"iidx",
|
||||
"SP",
|
||||
{ dan: "kaiden" },
|
||||
({ classes: { dan: "chuuden" } } as unknown) as UserGameStats,
|
||||
{ dan: 18 },
|
||||
({ classes: { dan: 17 } } as unknown) as UserGameStats,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -96,8 +94,8 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
{
|
||||
set: "dan",
|
||||
playtype: "SP",
|
||||
old: "chuuden",
|
||||
new: "kaiden",
|
||||
old: 17,
|
||||
new: 18,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -106,10 +104,9 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
|
||||
t.test("Should not return identical classes", (t) => {
|
||||
const res = CalculateClassDeltas(
|
||||
"iidx",
|
||||
"SP",
|
||||
{ dan: "kaiden" },
|
||||
({ classes: { dan: "kaiden" } } as unknown) as UserGameStats,
|
||||
{ dan: 18 },
|
||||
({ classes: { dan: 18 } } as unknown) as UserGameStats,
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -120,10 +117,9 @@ t.test("#CalculateClassDeltas", (t) => {
|
||||
|
||||
t.test("Should not return worse classes", (t) => {
|
||||
const res = CalculateClassDeltas(
|
||||
"iidx",
|
||||
"SP",
|
||||
{ dan: "10" },
|
||||
({ classes: { dan: "kaiden" } } as unknown) as UserGameStats,
|
||||
{ dan: 16 },
|
||||
({ classes: { dan: 18 } } as unknown) as UserGameStats,
|
||||
logger
|
||||
);
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Game, Playtypes, integer, UserGameStats, ClassDelta } from "kamaitachi-common";
|
||||
import { gameClassValues } from "kamaitachi-common/js/game-classes";
|
||||
import { Game, Playtypes, integer, UserGameStats, ClassDelta, IDStrings } from "kamaitachi-common";
|
||||
import deepmerge from "deepmerge";
|
||||
import { KtLogger } from "../../../logger/logger";
|
||||
import { CalculateGitadoraColour, CalculateJubeatColour } from "./builtin-class-handlers";
|
||||
import { ReturnClassIfGreater } from "../../../../utils/class";
|
||||
import { GameClasses } from "kamaitachi-common/js/game-classes";
|
||||
|
||||
type ScoreClasses = Partial<GameClasses<IDStrings>>;
|
||||
|
||||
export interface ClassHandler {
|
||||
(
|
||||
@@ -12,7 +14,7 @@ export interface ClassHandler {
|
||||
userID: integer,
|
||||
customRatings: Record<string, number>,
|
||||
logger: KtLogger
|
||||
): Promise<Record<string, string>> | Record<string, string> | undefined;
|
||||
): Promise<ScoreClasses> | ScoreClasses | undefined;
|
||||
}
|
||||
|
||||
type ClassHandlerMap = {
|
||||
@@ -79,8 +81,8 @@ export async function UpdateUGSClasses(
|
||||
customRatings: Record<string, number>,
|
||||
ClassHandler: ClassHandler | null,
|
||||
logger: KtLogger
|
||||
): Promise<Record<string, string>> {
|
||||
let classes: Record<string, string> = {};
|
||||
): Promise<ScoreClasses> {
|
||||
let classes: ScoreClasses = {};
|
||||
|
||||
// @ts-expect-error This one sucks - I need to look into a better way of representing these types
|
||||
if (STATIC_CLASS_HANDLERS[game] && STATIC_CLASS_HANDLERS[game][playtype]) {
|
||||
@@ -112,55 +114,42 @@ export async function UpdateUGSClasses(
|
||||
* so that other services can listen for it. In the future we might allow webhooks, too.
|
||||
*/
|
||||
export function CalculateClassDeltas(
|
||||
game: Game,
|
||||
playtype: Playtypes[Game],
|
||||
classes: Record<string, string>,
|
||||
classes: ScoreClasses,
|
||||
userGameStats: UserGameStats | null,
|
||||
logger: KtLogger
|
||||
): ClassDelta[] {
|
||||
// @ts-expect-error It's complaining about Game+PT permutations instead of Game->PT permutations.
|
||||
const gcv = gameClassValues[game]?.[playtype];
|
||||
|
||||
if (Object.keys(classes).length !== 0 && !gcv) {
|
||||
logger.severe(
|
||||
`Classes were attempted to be processed for ${game} ${playtype}, but no class values exist for this.`,
|
||||
{
|
||||
classes,
|
||||
}
|
||||
);
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
const deltas = [];
|
||||
|
||||
for (const setName in classes) {
|
||||
for (const s in classes) {
|
||||
const classSet = s as keyof GameClasses<IDStrings>;
|
||||
const classVal = classes[classSet];
|
||||
|
||||
if (classVal === undefined) {
|
||||
logger.debug(`Skipped deltaing-class ${classSet}.`);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const isGreater = ReturnClassIfGreater(
|
||||
game,
|
||||
playtype,
|
||||
setName,
|
||||
classes[setName],
|
||||
userGameStats
|
||||
);
|
||||
const isGreater = ReturnClassIfGreater(classSet, classVal, userGameStats);
|
||||
|
||||
if (isGreater === false) {
|
||||
continue;
|
||||
} else if (isGreater === null) {
|
||||
// @todo #99 REDISIPC-New Class Achieved
|
||||
deltas.push({
|
||||
set: setName,
|
||||
set: classSet,
|
||||
playtype,
|
||||
old: null,
|
||||
new: classes[setName],
|
||||
new: classVal,
|
||||
});
|
||||
} else {
|
||||
// @todo #99 REDISIPC-Class Improved!
|
||||
deltas.push({
|
||||
set: setName,
|
||||
set: classSet,
|
||||
playtype,
|
||||
old: userGameStats!.classes[setName],
|
||||
new: classes[setName],
|
||||
old: userGameStats!.classes[classSet]!,
|
||||
new: classVal,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -110,7 +110,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
"iidx",
|
||||
"SP",
|
||||
1,
|
||||
() => ({ dan: "kaiden" }), // lmao
|
||||
() => ({ dan: 18 }), // lmao
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -121,7 +121,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
set: "dan",
|
||||
playtype: "SP",
|
||||
old: null,
|
||||
new: "kaiden",
|
||||
new: 18,
|
||||
},
|
||||
],
|
||||
"Should return the class delta"
|
||||
@@ -141,7 +141,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
BPI: 0,
|
||||
},
|
||||
classes: {
|
||||
dan: "kaiden",
|
||||
dan: 18,
|
||||
},
|
||||
} as any,
|
||||
"Should update the game-stats object"
|
||||
@@ -161,7 +161,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
BPI: 0,
|
||||
},
|
||||
classes: {
|
||||
dan: "chuuden",
|
||||
dan: 17,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -169,7 +169,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
"iidx",
|
||||
"SP",
|
||||
1,
|
||||
() => ({ dan: "kaiden" }), // lmao
|
||||
() => ({ dan: 18 }), // lmao
|
||||
logger
|
||||
);
|
||||
|
||||
@@ -179,8 +179,8 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
{
|
||||
set: "dan",
|
||||
playtype: "SP",
|
||||
old: "chuuden",
|
||||
new: "kaiden",
|
||||
old: 17,
|
||||
new: 18,
|
||||
},
|
||||
],
|
||||
"Should return the updated class delta"
|
||||
@@ -200,7 +200,7 @@ t.test("#UpdateUsersGamePlaytypeStats", (t) => {
|
||||
BPI: 0,
|
||||
},
|
||||
classes: {
|
||||
dan: "kaiden",
|
||||
dan: 18,
|
||||
},
|
||||
} as any,
|
||||
"Should update the game-stats object"
|
||||
|
||||
@@ -41,7 +41,7 @@ export async function UpdateUsersGamePlaytypeStats(
|
||||
|
||||
logger.debug(`Calculating Class Deltas...`);
|
||||
|
||||
const deltas = CalculateClassDeltas(game, playtype, classes, userGameStats, logger);
|
||||
const deltas = CalculateClassDeltas(playtype, classes, userGameStats, logger);
|
||||
|
||||
logger.debug(`Had ${deltas.length} deltas.`);
|
||||
|
||||
|
||||
+11
-47
@@ -1,61 +1,25 @@
|
||||
import { Game, integer, Playtypes, UserGameStats } from "kamaitachi-common";
|
||||
import { ClassData, gameClassValues } from "kamaitachi-common/js/game-classes";
|
||||
import { Game, integer, IDStrings, Playtypes, UserGameStats } from "kamaitachi-common";
|
||||
import db from "../external/mongo/db";
|
||||
import CreateLogCtx from "../lib/logger/logger";
|
||||
import { GameClassSets } from "kamaitachi-common/js/game-classes";
|
||||
|
||||
const logger = CreateLogCtx(__filename);
|
||||
|
||||
export function GetClassSetsForGamePT(game: Game, playtype: Playtypes[Game]) {
|
||||
// @ts-expect-error its confused about game+pt permutations
|
||||
return gameClassValues[game]?.[playtype] as Record<string, ClassData> | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provided class if it is greater than the one in userGameStats
|
||||
* @returns The provided class if it is greater, NULL if there is nothing
|
||||
* to compare to, and FALSE if it is worse or equal.
|
||||
*/
|
||||
export function ReturnClassIfGreater(
|
||||
game: Game,
|
||||
playtype: Playtypes[Game],
|
||||
setName: string,
|
||||
newClass: string,
|
||||
classSet: GameClassSets[IDStrings],
|
||||
classVal: integer,
|
||||
userGameStats?: UserGameStats | null
|
||||
) {
|
||||
const classSets = GetClassSetsForGamePT(game, playtype);
|
||||
|
||||
if (!classSets) {
|
||||
logger.error(`${game} ${playtype} Does not have any classes.`);
|
||||
throw new Error(`${game} ${playtype} Does not have any classes.`);
|
||||
}
|
||||
|
||||
const gcv: ClassData = classSets[setName];
|
||||
|
||||
if (gcv === undefined) {
|
||||
logger.error(`Invalid classKey ${setName}. Cannot process class.`);
|
||||
throw new Error(`Invalid classKey ${setName}. Cannot process class.`);
|
||||
}
|
||||
|
||||
const newClassInfo = gcv[newClass];
|
||||
|
||||
if (!userGameStats) {
|
||||
if (!userGameStats || userGameStats.classes[classSet] === undefined) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const val = newClassInfo.index;
|
||||
const pastClass = userGameStats.classes[setName];
|
||||
|
||||
if (!pastClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pastVal = gcv[pastClass].index;
|
||||
|
||||
if (val > pastVal) {
|
||||
return newClass;
|
||||
}
|
||||
|
||||
return false;
|
||||
return classVal > userGameStats.classes[classSet]!;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,11 +34,11 @@ export async function UpdateClassIfGreater(
|
||||
userID: integer,
|
||||
game: Game,
|
||||
playtype: Playtypes[Game],
|
||||
classKey: string,
|
||||
newClass: string
|
||||
classSet: GameClassSets[IDStrings],
|
||||
classVal: integer
|
||||
) {
|
||||
const userGameStats = await db["game-stats"].findOne({ userID, game, playtype });
|
||||
const isGreater = ReturnClassIfGreater(game, playtype, classKey, newClass, userGameStats);
|
||||
const isGreater = ReturnClassIfGreater(classSet, classVal, userGameStats);
|
||||
|
||||
if (isGreater === false) {
|
||||
return false;
|
||||
@@ -83,7 +47,7 @@ export async function UpdateClassIfGreater(
|
||||
if (userGameStats) {
|
||||
await db["game-stats"].update(
|
||||
{ userID, game, playtype },
|
||||
{ $set: { [`classes.${classKey}`]: newClass } }
|
||||
{ $set: { [`classes.${classSet}`]: classVal } }
|
||||
);
|
||||
} else {
|
||||
// insert new game stats for this user - this is an awkward place
|
||||
@@ -96,7 +60,7 @@ export async function UpdateClassIfGreater(
|
||||
lampRating: 0,
|
||||
rating: 0,
|
||||
classes: {
|
||||
classKey: newClass,
|
||||
[classSet]: classVal,
|
||||
},
|
||||
});
|
||||
logger.info(`Created new player gamestats for ${userID} ${game} (${playtype})`);
|
||||
|
||||
Reference in New Issue
Block a user