Update Healer Man server
This commit is contained in:
1 parent
f90ba7d989
commit
189b94d6b7
51 files changed
+3448
-154
No files matched your search
+24
-4
@@ -699,16 +699,29 @@ export function openGameDatabase(options = {}) {
|
||||
};
|
||||
}
|
||||
|
||||
function onlineGroupCharacterSource(character) {
|
||||
return character.classId.startsWith("rom-") || character.categoryId === "rom" ? "rom" : "wow";
|
||||
}
|
||||
|
||||
function updateOnlineGroupMember(accountId, character, role) {
|
||||
const group = groupMembership(accountId);
|
||||
if (!group) throw new GameDatabaseError("Join or create a group first.", 409, "group_required");
|
||||
if (!["tank", "healer", "damage"].includes(role)) {
|
||||
throw new GameDatabaseError("Choose a valid party role.", 400, "invalid_party_role");
|
||||
}
|
||||
const selectedCharacter = normalizeGroupCharacter(character);
|
||||
const otherMembers = database.prepare(`
|
||||
SELECT character_json FROM online_group_members
|
||||
WHERE group_id = ? AND account_id != ? AND character_json IS NOT NULL
|
||||
`).all(group.id, accountId);
|
||||
if (otherMembers.some((member) => onlineGroupCharacterSource(JSON.parse(member.character_json))
|
||||
!== onlineGroupCharacterSource(selectedCharacter))) {
|
||||
throw new GameDatabaseError("RoM characters cannot join a WoW group, or vice versa.", 409, "mixed_group_sources");
|
||||
}
|
||||
database.prepare(`
|
||||
UPDATE online_group_members SET character_json = ?, role = ?
|
||||
WHERE group_id = ? AND account_id = ?
|
||||
`).run(JSON.stringify(normalizeGroupCharacter(character)), role, group.id, accountId);
|
||||
`).run(JSON.stringify(selectedCharacter), role, group.id, accountId);
|
||||
database.prepare("UPDATE online_groups SET updated_at = ? WHERE id = ?").run(Date.now(), group.id);
|
||||
return onlineGroupState(accountId);
|
||||
}
|
||||
@@ -739,19 +752,26 @@ export function openGameDatabase(options = {}) {
|
||||
if (members.some((member) => !member.character_json || !["tank", "healer", "damage"].includes(member.role))) {
|
||||
throw new GameDatabaseError("Every player must select a character and party role before the group can start.", 409, "group_not_ready");
|
||||
}
|
||||
if (new Set(members.map((member) => onlineGroupCharacterSource(JSON.parse(member.character_json)))).size > 1) {
|
||||
throw new GameDatabaseError("RoM characters cannot join a WoW group, or vice versa.", 409, "mixed_group_sources");
|
||||
}
|
||||
const romGroup = onlineGroupCharacterSource(JSON.parse(members[0].character_json)) === "rom";
|
||||
const randomizedBiteSized = type === "dungeon"
|
||||
&& contentId === "randomized-bite-sized-stormwind-stockade";
|
||||
const fillWithAi = randomizedBiteSized || input?.fillWithAi !== false;
|
||||
if (romGroup && randomizedBiteSized) {
|
||||
throw new GameDatabaseError("This WoW-only activity is unavailable to RoM groups.", 409, "group_source_incompatible");
|
||||
}
|
||||
const fillWithAi = !romGroup && (randomizedBiteSized || input?.fillWithAi !== false);
|
||||
if (input?.includeBetaSpecs !== undefined && typeof input.includeBetaSpecs !== "boolean") {
|
||||
throw new GameDatabaseError("includeBetaSpecs must be boolean.", 400, "invalid_beta_preference");
|
||||
}
|
||||
const includeBetaSpecs = randomizedBiteSized ? false : input?.includeBetaSpecs === true;
|
||||
const includeBetaSpecs = romGroup || randomizedBiteSized ? false : input?.includeBetaSpecs === true;
|
||||
const requestedSize = randomizedBiteSized
|
||||
? 5
|
||||
: Math.max(1, Math.min(5, Math.trunc(Number(input?.partySize) || 5)));
|
||||
const partySize = fillWithAi ? Math.max(members.length, requestedSize) : members.length;
|
||||
const readiness = getCompanionSpecReadiness();
|
||||
const companionSpecializationIds = Object.entries(readiness.config.statuses)
|
||||
const companionSpecializationIds = romGroup ? [] : Object.entries(readiness.config.statuses)
|
||||
.filter(([, status]) => status === "ready" || (includeBetaSpecs && status === "beta"))
|
||||
.map(([specializationId]) => specializationId);
|
||||
const activity = {
|
||||
|
||||
@@ -320,6 +320,37 @@ test("creates online groups through invitations and transfers leadership when th
|
||||
assert.deepEqual(transferred.group.members.map((member) => member.username), ["GroupHealer"]);
|
||||
}));
|
||||
|
||||
test("keeps RoM and WoW characters in separate online groups", () => withDatabase(async (database) => {
|
||||
const leaderAuth = await database.register("SourceLeader", "group-pass");
|
||||
const memberAuth = await database.register("SourceMember", "member-pass");
|
||||
const leader = database.authenticate(leaderAuth.token);
|
||||
const member = database.authenticate(memberAuth.token);
|
||||
database.inviteOnlineGroupMember(leader, member.username);
|
||||
const invite = database.onlineGroupState(member.id).invitations[0];
|
||||
database.respondToOnlineGroupInvite(member.id, invite.id, true);
|
||||
|
||||
const wowCharacter = { id: "wow-priest", name: "Wow Priest", classId: "priest", categoryId: "wow", level: 20 };
|
||||
const romCharacter = { id: "rom-priest", name: "RoM Priest", classId: "rom-priest", categoryId: "rom", level: 20 };
|
||||
database.updateOnlineGroupMember(leader.id, wowCharacter, "healer");
|
||||
assert.throws(() => database.updateOnlineGroupMember(member.id, romCharacter, "healer"),
|
||||
(error) => error instanceof GameDatabaseError && error.code === "mixed_group_sources");
|
||||
assert.equal(database.onlineGroupState(member.id).group.members[1].character, null);
|
||||
|
||||
database.updateOnlineGroupMember(leader.id, romCharacter, "healer");
|
||||
assert.throws(() => database.updateOnlineGroupMember(member.id, wowCharacter, "healer"),
|
||||
(error) => error instanceof GameDatabaseError && error.code === "mixed_group_sources");
|
||||
database.updateOnlineGroupMember(member.id, { ...romCharacter, id: "rom-mage", name: "RoM Mage", classId: "rom-mage" }, "damage");
|
||||
assert.throws(() => database.startOnlineGroupActivity(leader.id, {
|
||||
type: "dungeon", contentId: "randomized-bite-sized-stormwind-stockade", fillWithAi: true, partySize: 5,
|
||||
}), (error) => error instanceof GameDatabaseError && error.code === "group_source_incompatible");
|
||||
const started = database.startOnlineGroupActivity(leader.id, {
|
||||
type: "dungeon", contentId: "wailing-caverns", fillWithAi: true, partySize: 5,
|
||||
});
|
||||
assert.equal(started.group.activity.partySize, 2);
|
||||
assert.equal(started.group.activity.fillWithAi, false);
|
||||
assert.deepEqual(started.group.activity.companionSpecializationIds, []);
|
||||
}));
|
||||
|
||||
test("launches players-only and AI-filled group activities only when every member is ready", () => withDatabase(async (database) => {
|
||||
const leaderAuth = await database.register("ReadyLeader", "group-pass");
|
||||
const memberAuth = await database.register("ReadyMember", "member-pass");
|
||||
|
||||
Reference in new issue
Block a user