Refactor game area resolution and argument parsing for game commands
This commit is contained in:
@@ -31,6 +31,20 @@ export async function resolveGuildAreaWithFallback(guildId: string, areaKey: str
|
|||||||
return { area: null, source: 'none' };
|
return { area: null, source: 'none' };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function resolveAreaByType(guildId: string, type: string): Promise<ResolvedAreaInfo> {
|
||||||
|
const guildArea = await prisma.gameArea.findFirst({ where: { type, guildId }, orderBy: [{ createdAt: 'asc' }] });
|
||||||
|
if (guildArea) {
|
||||||
|
return { area: guildArea, source: 'guild' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalArea = await prisma.gameArea.findFirst({ where: { type, guildId: null }, orderBy: [{ createdAt: 'asc' }] });
|
||||||
|
if (globalArea) {
|
||||||
|
return { area: globalArea, source: 'global' };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { area: null, source: 'none' };
|
||||||
|
}
|
||||||
|
|
||||||
export async function getDefaultLevel(userId: string, guildId: string, areaId: string): Promise<number> {
|
export async function getDefaultLevel(userId: string, guildId: string, areaId: string): Promise<number> {
|
||||||
const prog = await prisma.playerProgress.findUnique({ where: { userId_guildId_areaId: { userId, guildId, areaId } } });
|
const prog = await prisma.playerProgress.findUnique({ where: { userId_guildId_areaId: { userId, guildId, areaId } } });
|
||||||
return Math.max(1, prog?.highestLevel ?? 1);
|
return Math.max(1, prog?.highestLevel ?? 1);
|
||||||
@@ -51,24 +65,24 @@ export async function findBestToolKey(userId: string, guildId: string, toolType:
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ParsedGameArgs {
|
export interface ParsedGameArgs {
|
||||||
areaKey: string;
|
|
||||||
levelArg: number | null;
|
levelArg: number | null;
|
||||||
providedTool: string | null;
|
providedTool: string | null;
|
||||||
|
areaOverride: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AREA_OVERRIDE_PREFIX = 'area:';
|
const AREA_OVERRIDE_PREFIX = 'area:';
|
||||||
|
|
||||||
export function parseGameArgs(args: string[], defaultAreaKey: string): ParsedGameArgs {
|
export function parseGameArgs(args: string[]): ParsedGameArgs {
|
||||||
const tokens = args.filter((arg): arg is string => typeof arg === 'string' && arg.trim().length > 0);
|
const tokens = args.filter((arg): arg is string => typeof arg === 'string' && arg.trim().length > 0);
|
||||||
|
|
||||||
let areaKey = defaultAreaKey;
|
|
||||||
let levelArg: number | null = null;
|
let levelArg: number | null = null;
|
||||||
let providedTool: string | null = null;
|
let providedTool: string | null = null;
|
||||||
|
let areaOverride: string | null = null;
|
||||||
|
|
||||||
for (const token of tokens) {
|
for (const token of tokens) {
|
||||||
if (token.startsWith(AREA_OVERRIDE_PREFIX)) {
|
if (token.startsWith(AREA_OVERRIDE_PREFIX)) {
|
||||||
const override = token.slice(AREA_OVERRIDE_PREFIX.length).trim();
|
const override = token.slice(AREA_OVERRIDE_PREFIX.length).trim();
|
||||||
if (override) areaKey = override;
|
if (override) areaOverride = override;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +96,6 @@ export function parseGameArgs(args: string[], defaultAreaKey: string): ParsedGam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return { areaKey, levelArg, providedTool };
|
return { levelArg, providedTool, areaOverride };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
import { runMinigame } from '../../../game/minigames/service';
|
||||||
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers';
|
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback, resolveAreaByType } from './_helpers';
|
||||||
import { updateStats } from '../../../game/stats/service';
|
import { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -16,15 +16,24 @@ export const command: CommandMessage = {
|
|||||||
run: async (message, args, _client: Amayo) => {
|
run: async (message, args, _client: Amayo) => {
|
||||||
const userId = message.author.id;
|
const userId = message.author.id;
|
||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'mine.cavern');
|
const { levelArg, providedTool, areaOverride } = parseGameArgs(args);
|
||||||
|
|
||||||
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
const areaInfo = areaOverride
|
||||||
if (!area) {
|
? await resolveGuildAreaWithFallback(guildId, areaOverride)
|
||||||
await message.reply(`⚠️ Área de mina no configurada. Pide a un admin crear \`gameArea\` con key \`${areaKey}\` en este servidor.`);
|
: await resolveAreaByType(guildId, 'MINE');
|
||||||
|
|
||||||
|
if (!areaInfo.area) {
|
||||||
|
if (areaOverride) {
|
||||||
|
await message.reply(`⚠️ No existe un área con key \`${areaOverride}\` para este servidor.`);
|
||||||
|
} else {
|
||||||
|
await message.reply('⚠️ No hay un área de tipo **MINE** configurada. Crea una con `!area-crear` o especifica `area:<key>`.');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { area, source } = areaInfo;
|
||||||
const globalNotice = source === 'global'
|
const globalNotice = source === 'global'
|
||||||
? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.`
|
? `ℹ️ Usando configuración global para \`${area.key}\`. Puedes crear \`gameArea\` tipo **MINE** para personalizarla en este servidor.`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
import { runMinigame } from '../../../game/minigames/service';
|
||||||
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers';
|
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback, resolveAreaByType } from './_helpers';
|
||||||
import { updateStats } from '../../../game/stats/service';
|
import { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -16,15 +16,24 @@ export const command: CommandMessage = {
|
|||||||
run: async (message, args, _client: Amayo) => {
|
run: async (message, args, _client: Amayo) => {
|
||||||
const userId = message.author.id;
|
const userId = message.author.id;
|
||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'fight.arena');
|
const { levelArg, providedTool, areaOverride } = parseGameArgs(args);
|
||||||
|
|
||||||
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
const areaInfo = areaOverride
|
||||||
if (!area) {
|
? await resolveGuildAreaWithFallback(guildId, areaOverride)
|
||||||
await message.reply(`⚠️ Área de arena no configurada. Crea \`gameArea\` con key \`${areaKey}\` en este servidor.`);
|
: await resolveAreaByType(guildId, 'FIGHT');
|
||||||
|
|
||||||
|
if (!areaInfo.area) {
|
||||||
|
if (areaOverride) {
|
||||||
|
await message.reply(`⚠️ No existe un área con key \`${areaOverride}\` para este servidor.`);
|
||||||
|
} else {
|
||||||
|
await message.reply('⚠️ No hay un área de tipo **FIGHT** configurada. Crea una con `!area-crear` o especifica `area:<key>`.');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { area, source } = areaInfo;
|
||||||
const globalNotice = source === 'global'
|
const globalNotice = source === 'global'
|
||||||
? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.`
|
? `ℹ️ Usando configuración global para \`${area.key}\`. Puedes crear \`gameArea\` tipo **FIGHT** para personalizarla en este servidor.`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CommandMessage } from '../../../core/types/commands';
|
import type { CommandMessage } from '../../../core/types/commands';
|
||||||
import type Amayo from '../../../core/client';
|
import type Amayo from '../../../core/client';
|
||||||
import { runMinigame } from '../../../game/minigames/service';
|
import { runMinigame } from '../../../game/minigames/service';
|
||||||
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback } from './_helpers';
|
import { getDefaultLevel, findBestToolKey, parseGameArgs, resolveGuildAreaWithFallback, resolveAreaByType } from './_helpers';
|
||||||
import { updateStats } from '../../../game/stats/service';
|
import { updateStats } from '../../../game/stats/service';
|
||||||
import { updateQuestProgress } from '../../../game/quests/service';
|
import { updateQuestProgress } from '../../../game/quests/service';
|
||||||
import { checkAchievements } from '../../../game/achievements/service';
|
import { checkAchievements } from '../../../game/achievements/service';
|
||||||
@@ -16,15 +16,24 @@ export const command: CommandMessage = {
|
|||||||
run: async (message, args, _client: Amayo) => {
|
run: async (message, args, _client: Amayo) => {
|
||||||
const userId = message.author.id;
|
const userId = message.author.id;
|
||||||
const guildId = message.guild!.id;
|
const guildId = message.guild!.id;
|
||||||
const { areaKey, levelArg, providedTool } = parseGameArgs(args, 'lagoon.shore');
|
const { levelArg, providedTool, areaOverride } = parseGameArgs(args);
|
||||||
|
|
||||||
const { area, source } = await resolveGuildAreaWithFallback(guildId, areaKey);
|
const areaInfo = areaOverride
|
||||||
if (!area) {
|
? await resolveGuildAreaWithFallback(guildId, areaOverride)
|
||||||
await message.reply(`⚠️ Área de laguna no configurada. Crea \`gameArea\` con key \`${areaKey}\` en este servidor.`);
|
: await resolveAreaByType(guildId, 'LAGOON');
|
||||||
|
|
||||||
|
if (!areaInfo.area) {
|
||||||
|
if (areaOverride) {
|
||||||
|
await message.reply(`⚠️ No existe un área con key \`${areaOverride}\` para este servidor.`);
|
||||||
|
} else {
|
||||||
|
await message.reply('⚠️ No hay un área de tipo **LAGOON** configurada. Crea una con `!area-crear` o especifica `area:<key>`.');
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { area, source } = areaInfo;
|
||||||
const globalNotice = source === 'global'
|
const globalNotice = source === 'global'
|
||||||
? `ℹ️ Usando configuración global para \`${areaKey}\`. Puedes crear \`gameArea\` para personalizarla en este servidor.`
|
? `ℹ️ Usando configuración global para \`${area.key}\`. Puedes crear \`gameArea\` tipo **LAGOON** para personalizarla en este servidor.`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
const level = levelArg ?? await getDefaultLevel(userId, guildId, area.id);
|
||||||
|
|||||||
Reference in New Issue
Block a user