From 4eaeb481368348a42b2a093f613dcecc514d0ae5 Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Sat, 9 Sep 2023 10:27:59 +0300 Subject: [PATCH] Alternative login flow (magic link via bot) (#1488) * Log in link creation initial * Add global name to update all command * Remove left over log * Login command * Update command * Add todos * TODOs * Migration file fix order --- .../layout/LogInButtonContainer.tsx | 7 +- app/db/models/users/queries.server.ts | 15 + app/db/models/users/upsertLite.sql | 22 + app/db/types.ts | 6 + app/features/info/routes/support.tsx | 5 + app/modules/auth/index.ts | 2 + .../auth/queries/createLogInLink.server.ts | 30 + .../queries/deleteLogInLinkByCode.server.ts | 10 + .../queries/userIdByLogInLinkCode.server.ts | 18 + app/modules/auth/routes.server.ts | 83 ++- app/routes/auth/create-link.tsx | 1 + app/routes/auth/login.tsx | 1 + discord-bot/commands/index.ts | 3 + discord-bot/commands/login.ts | 96 +++ discord-bot/commands/updateall.ts | 3 +- discord-bot/package-lock.json | 597 +++++++----------- discord-bot/package.json | 10 +- migrations/035-log-in-link.js | 12 + public/locales/da/common.json | 1 - public/locales/da/faq.json | 1 - public/locales/de/common.json | 1 - public/locales/de/faq.json | 1 - public/locales/en/common.json | 4 +- public/locales/en/faq.json | 2 +- public/locales/es-ES/faq.json | 3 +- public/locales/es-US/faq.json | 3 +- public/locales/fr/common.json | 1 - public/locales/fr/faq.json | 1 - public/locales/he/common.json | 1 - public/locales/he/faq.json | 1 - public/locales/it/common.json | 1 - public/locales/it/faq.json | 1 - public/locales/ja/common.json | 1 - public/locales/ja/faq.json | 1 - public/locales/ko/common.json | 1 - public/locales/ko/faq.json | 3 +- public/locales/nl/faq.json | 3 +- public/locales/pl/common.json | 1 - public/locales/pl/faq.json | 1 - public/locales/ru/common.json | 1 - public/locales/ru/faq.json | 1 - public/locales/zh/common.json | 1 - public/locales/zh/faq.json | 1 - scripts/create-analyzer-json.ts | 1 - 44 files changed, 539 insertions(+), 420 deletions(-) create mode 100644 app/db/models/users/upsertLite.sql create mode 100644 app/modules/auth/queries/createLogInLink.server.ts create mode 100644 app/modules/auth/queries/deleteLogInLinkByCode.server.ts create mode 100644 app/modules/auth/queries/userIdByLogInLinkCode.server.ts create mode 100644 app/routes/auth/create-link.tsx create mode 100644 app/routes/auth/login.tsx create mode 100644 discord-bot/commands/login.ts create mode 100644 migrations/035-log-in-link.js diff --git a/app/components/layout/LogInButtonContainer.tsx b/app/components/layout/LogInButtonContainer.tsx index 17752c915f..b34d9a47d5 100644 --- a/app/components/layout/LogInButtonContainer.tsx +++ b/app/components/layout/LogInButtonContainer.tsx @@ -1,6 +1,6 @@ import { useSearchParams } from "@remix-run/react"; import { useTranslation } from "~/hooks/useTranslation"; -import { LOG_IN_URL } from "~/utils/urls"; +import { LOG_IN_URL, SENDOU_INK_DISCORD_URL } from "~/utils/urls"; import { Button } from "../Button"; import { Dialog } from "../Dialog"; @@ -51,7 +51,10 @@ function AuthenticationErrorHelp({ errorCode }: { errorCode: string }) { return ( <>

{t("auth.errors.failed")}

- {t("auth.errors.unknown")} + {t("auth.errors.unknown")}{" "} + + {SENDOU_INK_DISCORD_URL} + ); } diff --git a/app/db/models/users/queries.server.ts b/app/db/models/users/queries.server.ts index 3fe4c0e32f..dc60807e56 100644 --- a/app/db/models/users/queries.server.ts +++ b/app/db/models/users/queries.server.ts @@ -27,6 +27,7 @@ import updateByDiscordIdSql from "./updateByDiscordId.sql"; import updateDiscordIdSql from "./updateDiscordId.sql"; import updateProfileSql from "./updateProfile.sql"; import upsertSql from "./upsert.sql"; +import upsertLiteSql from "./upsertLite.sql"; import addUserWeaponSql from "./addUserWeapon.sql"; import deleteUserWeaponsSql from "./deleteUserWeapons.sql"; import wipePlusTiersSql from "./wipePlusTiers.sql"; @@ -54,6 +55,20 @@ export function upsert( return upsertStm.get(input) as User; } +const upsertLiteStm = sql.prepare(upsertLiteSql); +export function upsertLite( + input: Pick< + User, + | "discordId" + | "discordName" + | "discordDiscriminator" + | "discordAvatar" + | "discordUniqueName" + >, +) { + return upsertLiteStm.get(input) as User; +} + const updateProfileStm = sql.prepare(updateProfileSql); const addUserWeaponStm = sql.prepare(addUserWeaponSql); const deleteUserWeaponsStm = sql.prepare(deleteUserWeaponsSql); diff --git a/app/db/models/users/upsertLite.sql b/app/db/models/users/upsertLite.sql new file mode 100644 index 0000000000..1cd1c45b33 --- /dev/null +++ b/app/db/models/users/upsertLite.sql @@ -0,0 +1,22 @@ +insert into + "User" ( + "discordId", + "discordName", + "discordDiscriminator", + "discordAvatar", + "discordUniqueName" + ) +values + ( + @discordId, + @discordName, + @discordDiscriminator, + @discordAvatar, + @discordUniqueName + ) on conflict("discordId") do +update +set + "discordName" = excluded."discordName", + "discordDiscriminator" = excluded."discordDiscriminator", + "discordAvatar" = excluded."discordAvatar", + "discordUniqueName" = excluded."discordUniqueName" returning * diff --git a/app/db/types.ts b/app/db/types.ts index e56df03b82..66540c4068 100644 --- a/app/db/types.ts +++ b/app/db/types.ts @@ -55,6 +55,12 @@ export interface UserWeapon { isFavorite: number; } +export interface LogInLink { + code: string; + expiresAt: number; + userId: number; +} + export interface PlusSuggestion { id: number; text: string; diff --git a/app/features/info/routes/support.tsx b/app/features/info/routes/support.tsx index 0c91b5e4bf..15f4f2ed00 100644 --- a/app/features/info/routes/support.tsx +++ b/app/features/info/routes/support.tsx @@ -47,6 +47,11 @@ const PERKS = [ name: "privateDiscord", extraInfo: true, }, + { + tier: 2, + name: "prioritySupport", + extraInfo: true, + }, { tier: 2, name: "customizedColorsUser", diff --git a/app/modules/auth/index.ts b/app/modules/auth/index.ts index 1d54244440..8c6f6f3366 100644 --- a/app/modules/auth/index.ts +++ b/app/modules/auth/index.ts @@ -4,6 +4,8 @@ export { stopImpersonatingAction, logInAction, logOutAction, + createLogInLinkAction, + logInViaLinkLoader, } from "./routes.server"; export { getUser, requireUser } from "./user.server"; diff --git a/app/modules/auth/queries/createLogInLink.server.ts b/app/modules/auth/queries/createLogInLink.server.ts new file mode 100644 index 0000000000..c3ac5463f7 --- /dev/null +++ b/app/modules/auth/queries/createLogInLink.server.ts @@ -0,0 +1,30 @@ +import { nanoid } from "nanoid"; +import { sql } from "~/db/sql"; +import type { LogInLink } from "~/db/types"; +import { dateToDatabaseTimestamp } from "~/utils/dates"; + +const stm = sql.prepare(/* sql */ ` + insert into "LogInLink" ( + "userId", + "expiresAt", + "code" + ) values ( + @userId, + @expiresAt, + @code + ) returning * +`); + +// 10 minutes +const LOG_IN_LINK_VALID_FOR = 10 * 60 * 1000; +const LOG_IN_LINK_LENGTH = 12; + +export function createLogInLink(userId: number) { + return stm.get({ + userId, + expiresAt: dateToDatabaseTimestamp( + new Date(Date.now() + LOG_IN_LINK_VALID_FOR), + ), + code: nanoid(LOG_IN_LINK_LENGTH), + }) as LogInLink; +} diff --git a/app/modules/auth/queries/deleteLogInLinkByCode.server.ts b/app/modules/auth/queries/deleteLogInLinkByCode.server.ts new file mode 100644 index 0000000000..0c9bc80954 --- /dev/null +++ b/app/modules/auth/queries/deleteLogInLinkByCode.server.ts @@ -0,0 +1,10 @@ +import { sql } from "~/db/sql"; + +const stm = sql.prepare(/* sql */ ` + delete from "LogInLink" + where "code" = @code +`); + +export function deleteLogInLinkByCode(code: string) { + return stm.run({ code }); +} diff --git a/app/modules/auth/queries/userIdByLogInLinkCode.server.ts b/app/modules/auth/queries/userIdByLogInLinkCode.server.ts new file mode 100644 index 0000000000..461c2d0992 --- /dev/null +++ b/app/modules/auth/queries/userIdByLogInLinkCode.server.ts @@ -0,0 +1,18 @@ +import { sql } from "~/db/sql"; +import { dateToDatabaseTimestamp } from "~/utils/dates"; + +const stm = sql.prepare(/* sql */ ` + select "userId" + from "LogInLink" + where "code" = @code + and "expiresAt" > @now +`); + +export function userIdByLogInLinkCode(code: string) { + return ( + stm.get({ + code, + now: dateToDatabaseTimestamp(new Date()), + }) as any + )?.userId as number | undefined; +} diff --git a/app/modules/auth/routes.server.ts b/app/modules/auth/routes.server.ts index 1c871155c5..fd6b821058 100644 --- a/app/modules/auth/routes.server.ts +++ b/app/modules/auth/routes.server.ts @@ -1,15 +1,21 @@ import type { ActionFunction, LoaderFunction } from "@remix-run/node"; import { redirect } from "@remix-run/node"; -import { canPerformAdminActions } from "~/permissions"; +import { canAccessLohiEndpoint, canPerformAdminActions } from "~/permissions"; import { ADMIN_PAGE, authErrorUrl } from "~/utils/urls"; import { authenticator, DISCORD_AUTH_KEY, IMPERSONATED_SESSION_KEY, + SESSION_KEY, } from "./authenticator.server"; import { authSessionStorage } from "./session.server"; import { getUserId } from "./user.server"; -import { validate } from "~/utils/remix"; +import { parseSearchParams, validate } from "~/utils/remix"; +import { z } from "zod"; +import { createLogInLink } from "./queries/createLogInLink.server"; +import { userIdByLogInLinkCode } from "./queries/userIdByLogInLinkCode.server"; +import { deleteLogInLinkByCode } from "./queries/deleteLogInLinkByCode.server"; +import { db } from "~/db"; const throwOnAuthErrors = process.env["THROW_ON_AUTH_ERROR"] === "true"; @@ -80,3 +86,76 @@ export const stopImpersonatingAction: ActionFunction = async ({ request }) => { headers: { "Set-Cookie": await authSessionStorage.commitSession(session) }, }); }; + +// below is alternative log-in flow that is operated via the Lohi Discord bot +// this is intended primarily as a workaround when website is having problems communicating +// with the Discord due to rate limits or other reasons + +// only light validation here as we generally trust Lohi +const createLogInLinkActionSchema = z.object({ + discordId: z.string(), + discordAvatar: z.string(), + discordName: z.string(), + discordUniqueName: z.string(), + updateOnly: z.enum(["true", "false"]), +}); + +export const createLogInLinkAction: ActionFunction = ({ request }) => { + const data = parseSearchParams({ + request, + schema: createLogInLinkActionSchema, + }); + + if (!canAccessLohiEndpoint(request)) { + throw new Response(null, { status: 403 }); + } + + const user = db.users.upsertLite({ + discordAvatar: data.discordAvatar, + discordDiscriminator: "0", + discordId: data.discordId, + discordName: data.discordName, + discordUniqueName: data.discordUniqueName, + }); + + if (data.updateOnly === "true") return null; + + const createdLink = createLogInLink(user.id); + + return { + code: createdLink.code, + }; +}; + +const logInViaLinkActionSchema = z.object({ + code: z.string(), +}); + +export const logInViaLinkLoader: LoaderFunction = async ({ request }) => { + const data = parseSearchParams({ + request, + schema: logInViaLinkActionSchema, + }); + const user = await getUserId(request); + + if (user) { + throw redirect("/"); + } + + const userId = userIdByLogInLinkCode(data.code); + if (!userId) { + throw new Response("Invalid log in link", { status: 400 }); + } + + const session = await authSessionStorage.getSession( + request.headers.get("Cookie"), + ); + + session.set(SESSION_KEY, userId); + + deleteLogInLinkByCode(data.code); + + throw redirect("/", { + headers: { "Set-Cookie": await authSessionStorage.commitSession(session) }, + }); +}; diff --git a/app/routes/auth/create-link.tsx b/app/routes/auth/create-link.tsx new file mode 100644 index 0000000000..5a7501a677 --- /dev/null +++ b/app/routes/auth/create-link.tsx @@ -0,0 +1 @@ +export { createLogInLinkAction as action } from "~/modules/auth"; diff --git a/app/routes/auth/login.tsx b/app/routes/auth/login.tsx new file mode 100644 index 0000000000..da07d6fc33 --- /dev/null +++ b/app/routes/auth/login.tsx @@ -0,0 +1 @@ +export { logInViaLinkLoader as loader } from "~/modules/auth"; diff --git a/discord-bot/commands/index.ts b/discord-bot/commands/index.ts index afed8ea010..e85a97797c 100644 --- a/discord-bot/commands/index.ts +++ b/discord-bot/commands/index.ts @@ -5,6 +5,7 @@ import { plusCommand } from "./plus"; import { updateAllCommand } from "./updateall"; import { pingRolesCommand } from "./pings"; import { colorCommand } from "./color"; +import { loginCommand, updateProfileCommand } from "./login"; import type { BotCommand } from "../types"; export const commands = [ @@ -15,6 +16,8 @@ export const commands = [ updateAllCommand, pingRolesCommand, colorCommand, + loginCommand, + updateProfileCommand, ]; export const commandsMap = Object.fromEntries(commands.map((c) => [c.name, c])); diff --git a/discord-bot/commands/login.ts b/discord-bot/commands/login.ts new file mode 100644 index 0000000000..1c3804a0a8 --- /dev/null +++ b/discord-bot/commands/login.ts @@ -0,0 +1,96 @@ +import { SlashCommandBuilder } from "@discordjs/builders"; +import type { CommandInteraction, User } from "discord.js"; +import ids from "../ids"; +import type { BotCommand } from "../types"; +import { sendouInkFetch } from "../utils"; + +const LOGIN_COMMAND_NAME = "login"; +const UPDATE_PROFILE_COMMAND_NAME = "update-profile"; + +export const loginCommand: BotCommand = { + guilds: [ids.guilds.plusServer, ids.guilds.sendou], + name: LOGIN_COMMAND_NAME, + builder: new SlashCommandBuilder() + .setName(LOGIN_COMMAND_NAME) + .setDescription("Get log in link for sendou.ink"), + execute: async ({ interaction }) => { + await execute(interaction, false); + }, +}; + +export const updateProfileCommand: BotCommand = { + guilds: [ids.guilds.plusServer, ids.guilds.sendou], + name: UPDATE_PROFILE_COMMAND_NAME, + builder: new SlashCommandBuilder() + .setName(UPDATE_PROFILE_COMMAND_NAME) + .setDescription("Update your username and profile picture on sendou.ink"), + execute: async ({ interaction }) => { + await execute(interaction, true); + }, +}; + +async function execute( + interaction: CommandInteraction, + updateOnly: boolean, +) { + const user = interaction.member?.user as User; + if (!user) { + return interaction.reply({ + content: "Something went wrong", + }); + } + + const hasUniqueUsername = user.discriminator === "0"; + + const discordName = hasUniqueUsername ? user.globalName : user.username; + const discordUniqueName = hasUniqueUsername ? user.username : null; + if (!discordName || !discordUniqueName) { + return interaction.reply({ + content: + "Can't do this with an account that is missing the new kind of Discord username", + }); + } + + const searchParams = new URLSearchParams( + user.avatar + ? { + discordAvatar: user.avatar, + discordId: user.id, + discordName, + discordUniqueName, + updateOnly: String(updateOnly), + } + : { + discordId: user.id, + discordName, + discordUniqueName, + updateOnly: String(updateOnly), + }, + ); + + const response = await sendouInkFetch(`/auth/create-link?${searchParams}`, { + method: "post", + }); + + if (updateOnly) { + if (!response.ok) { + return interaction.reply({ + content: "Something went wrong when updating", + ephemeral: true, + }); + } + + return interaction.reply({ + content: "Updated your profile on sendou.ink", + ephemeral: true, + }); + } + + const { code } = await response.json(); + + return interaction.reply({ + content: + "Use the link below to log in to sendou.ink. It's active for 10 minutes. ⚠️ Don't share this link with others as it will allow them to log in to your account.\n\n[log in link](https://sendou.ink/auth/login?code=${code})", + ephemeral: true, + }); +} diff --git a/discord-bot/commands/updateall.ts b/discord-bot/commands/updateall.ts index 2143a9576c..dcca1973ff 100644 --- a/discord-bot/commands/updateall.ts +++ b/discord-bot/commands/updateall.ts @@ -53,11 +53,10 @@ async function getUsersToUpdate(client: Client) { const hasUniqueUsername = user.discriminator === "0"; - // TODO: global_name when discord.js supports it userUpdates.push({ discordId: user.id, discordAvatar: user.avatar, - discordName: hasUniqueUsername ? null : user.username, + discordName: hasUniqueUsername ? user.globalName : user.username, discordUniqueName: hasUniqueUsername ? user.username : null, }); diff --git a/discord-bot/package-lock.json b/discord-bot/package-lock.json index a6eed33170..10508f0198 100644 --- a/discord-bot/package-lock.json +++ b/discord-bot/package-lock.json @@ -7,14 +7,14 @@ "": { "name": "lohi", "dependencies": { - "@discordjs/rest": "^1.7.1", - "discord-api-types": "^0.37.45", - "discord.js": "^14.11.0", - "dotenv": "^16.3.0", + "@discordjs/rest": "^2.0.1", + "discord-api-types": "^0.37.56", + "discord.js": "^14.13.0", + "dotenv": "^16.3.1", "tiny-invariant": "^1.3.1", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", - "typescript": "^5.1.3" + "typescript": "^5.2.2" } }, "node_modules/@cspotcode/source-map-support": { @@ -29,86 +29,107 @@ } }, "node_modules/@discordjs/builders": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.3.tgz", - "integrity": "sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.5.tgz", + "integrity": "sha512-SdweyCs/+mHj+PNhGLLle7RrRFX9ZAhzynHahMCLqp5Zeq7np7XC6/mgzHc79QoVlQ1zZtOkTTiJpOZu5V8Ufg==", "dependencies": { - "@discordjs/formatters": "^0.3.1", - "@discordjs/util": "^0.3.1", - "@sapphire/shapeshift": "^3.8.2", - "discord-api-types": "^0.37.41", + "@discordjs/formatters": "^0.3.2", + "@discordjs/util": "^1.0.1", + "@sapphire/shapeshift": "^3.9.2", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.3", - "tslib": "^2.5.0" + "tslib": "^2.6.1" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, + "node_modules/@discordjs/builders/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, "node_modules/@discordjs/collection": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.1.tgz", - "integrity": "sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==", "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/formatters": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz", - "integrity": "sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.2.tgz", + "integrity": "sha512-lE++JZK8LSSDRM5nLjhuvWhGuKiXqu+JZ/DsOR89DVVia3z9fdCJVcHF2W/1Zxgq0re7kCzmAJlCMMX3tetKpA==", "dependencies": { - "discord-api-types": "^0.37.41" + "discord-api-types": "0.37.50" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, + "node_modules/@discordjs/formatters/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, "node_modules/@discordjs/rest": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz", - "integrity": "sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.1.tgz", + "integrity": "sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==", "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/util": "^0.3.0", + "@discordjs/collection": "^1.5.3", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.4.2", - "discord-api-types": "^0.37.41", - "file-type": "^18.3.0", - "tslib": "^2.5.0", - "undici": "^5.22.0" + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "magic-bytes.js": "^1.0.15", + "tslib": "^2.6.1", + "undici": "5.22.1" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, + "node_modules/@discordjs/rest/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, "node_modules/@discordjs/util": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz", - "integrity": "sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.1.tgz", + "integrity": "sha512-d0N2yCxB8r4bn00/hvFZwM7goDcUhtViC5un4hPj73Ba4yrChLSJD8fy7Ps5jpTLg1fE9n4K0xBLc1y9WGwSsA==", "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, "node_modules/@discordjs/ws": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-0.8.3.tgz", - "integrity": "sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.1.tgz", + "integrity": "sha512-avvAolBqN3yrSvdBPcJ/0j2g42ABzrv3PEL76e3YTp2WYMGH7cuspkjfSyNWaqYl1J+669dlLp+YFMxSVQyS5g==", "dependencies": { - "@discordjs/collection": "^1.5.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", + "@discordjs/collection": "^1.5.3", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.4", - "@vladfrangu/async_event_emitter": "^2.2.1", - "discord-api-types": "^0.37.41", - "tslib": "^2.5.0", + "@types/ws": "^8.5.5", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "tslib": "^2.6.1", "ws": "^8.13.0" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, + "node_modules/@discordjs/ws/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", @@ -162,11 +183,6 @@ "npm": ">=7.0.0" } }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -258,38 +274,43 @@ } }, "node_modules/discord-api-types": { - "version": "0.37.45", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.45.tgz", - "integrity": "sha512-r9m/g+YQfo7XWMrl645jvMlYoWF8lvns/ch4NCxsz/FbingrECu97LFSD2zKOvgHaSc90BHP8wgshaMcA2/c6Q==" + "version": "0.37.56", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.56.tgz", + "integrity": "sha512-Ih3wj0ZTaQxaJRqUEXHMIXfXB86bwMGC0wc2nNsyCJqeo3lC4qnxXtFIsC+IGI46+dSIinuayCAZ6sLEEM02Bw==" }, "node_modules/discord.js": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.11.0.tgz", - "integrity": "sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.13.0.tgz", + "integrity": "sha512-Kufdvg7fpyTEwANGy9x7i4od4yu5c6gVddGi5CKm4Y5a6sF0VBODObI3o0Bh7TGCj0LfNT8Qp8z04wnLFzgnbA==", "dependencies": { - "@discordjs/builders": "^1.6.3", - "@discordjs/collection": "^1.5.1", - "@discordjs/formatters": "^0.3.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", - "@discordjs/ws": "^0.8.3", - "@sapphire/snowflake": "^3.4.2", - "@types/ws": "^8.5.4", - "discord-api-types": "^0.37.41", + "@discordjs/builders": "^1.6.5", + "@discordjs/collection": "^1.5.3", + "@discordjs/formatters": "^0.3.2", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", + "@discordjs/ws": "^1.0.1", + "@sapphire/snowflake": "^3.5.1", + "@types/ws": "^8.5.5", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.5.0", - "undici": "^5.22.0", + "tslib": "^2.6.1", + "undici": "5.22.1", "ws": "^8.13.0" }, "engines": { - "node": ">=16.9.0" + "node": ">=16.11.0" } }, + "node_modules/discord.js/node_modules/discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + }, "node_modules/dotenv": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.0.tgz", - "integrity": "sha512-tHB+hmf8MRCkT3VVivGiG8kq9HiGTmQ3FzOKgztfpJQH1IWuZTOvKSJmHNnQPowecAmkCJhLrxdPhOr06LLqIQ==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "engines": { "node": ">=12" }, @@ -302,46 +323,6 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "node_modules/file-type": { - "version": "18.5.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.5.0.tgz", - "integrity": "sha512-yvpl5U868+V6PqXHMmsESpg6unQ5GfnPssl4dxdJudBrr9qy7Fddt7EVX1VLlddFfe8Gj9N7goCZH22FXuSQXQ==", - "dependencies": { - "readable-web-to-node-stream": "^3.0.2", - "strtok3": "^7.0.0", - "token-types": "^5.0.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -363,6 +344,11 @@ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" }, + "node_modules/magic-bytes.js": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.0.15.tgz", + "integrity": "sha512-bpRmwbRHqongRhA+mXzbLWjVy7ylqmfMBYaQkSs6pac0z6hBTvsgrH0r4FBYd/UYVJBmS6Rp/O+oCCQVLzKV1g==" + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -373,65 +359,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, - "node_modules/peek-readable": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", - "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "dependencies": { - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -440,14 +367,6 @@ "node": ">=10.0.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -456,43 +375,11 @@ "node": ">=4" } }, - "node_modules/strtok3": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", - "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.0.0" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, - "node_modules/token-types": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", - "dependencies": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/ts-mixer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", @@ -554,14 +441,14 @@ } }, "node_modules/tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -581,20 +468,15 @@ "node": ">=14.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.0.tgz", + "integrity": "sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg==", "engines": { "node": ">=10.0.0" }, @@ -630,66 +512,95 @@ } }, "@discordjs/builders": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.3.tgz", - "integrity": "sha512-CTCh8NqED3iecTNuiz49mwSsrc2iQb4d0MjMdmS/8pb69Y4IlzJ/DIy/p5GFlgOrFbNO2WzMHkWKQSiJ3VNXaw==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.6.5.tgz", + "integrity": "sha512-SdweyCs/+mHj+PNhGLLle7RrRFX9ZAhzynHahMCLqp5Zeq7np7XC6/mgzHc79QoVlQ1zZtOkTTiJpOZu5V8Ufg==", "requires": { - "@discordjs/formatters": "^0.3.1", - "@discordjs/util": "^0.3.1", - "@sapphire/shapeshift": "^3.8.2", - "discord-api-types": "^0.37.41", + "@discordjs/formatters": "^0.3.2", + "@discordjs/util": "^1.0.1", + "@sapphire/shapeshift": "^3.9.2", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "ts-mixer": "^6.0.3", - "tslib": "^2.5.0" + "tslib": "^2.6.1" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + } } }, "@discordjs/collection": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.1.tgz", - "integrity": "sha512-aWEc9DCf3TMDe9iaJoOnO2+JVAjeRNuRxPZQA6GVvBf+Z3gqUuWYBy2NWh4+5CLYq5uoc3MOvUQ5H5m8CJBqOA==" + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz", + "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==" }, "@discordjs/formatters": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.1.tgz", - "integrity": "sha512-M7X4IGiSeh4znwcRGcs+49B5tBkNDn4k5bmhxJDAUhRxRHTiFAOTVUNQ6yAKySu5jZTnCbSvTYHW3w0rAzV1MA==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.3.2.tgz", + "integrity": "sha512-lE++JZK8LSSDRM5nLjhuvWhGuKiXqu+JZ/DsOR89DVVia3z9fdCJVcHF2W/1Zxgq0re7kCzmAJlCMMX3tetKpA==", "requires": { - "discord-api-types": "^0.37.41" + "discord-api-types": "0.37.50" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + } } }, "@discordjs/rest": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-1.7.1.tgz", - "integrity": "sha512-Ofa9UqT0U45G/eX86cURQnX7gzOJLG2oC28VhIk/G6IliYgQF7jFByBJEykPSHE4MxPhqCleYvmsrtfKh1nYmQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.0.1.tgz", + "integrity": "sha512-/eWAdDRvwX/rIE2tuQUmKaxmWeHmGealttIzGzlYfI4+a7y9b6ZoMp8BG/jaohs8D8iEnCNYaZiOFLVFLQb8Zg==", "requires": { - "@discordjs/collection": "^1.5.1", - "@discordjs/util": "^0.3.0", + "@discordjs/collection": "^1.5.3", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@sapphire/snowflake": "^3.4.2", - "discord-api-types": "^0.37.41", - "file-type": "^18.3.0", - "tslib": "^2.5.0", - "undici": "^5.22.0" + "@sapphire/snowflake": "^3.5.1", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "magic-bytes.js": "^1.0.15", + "tslib": "^2.6.1", + "undici": "5.22.1" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + } } }, "@discordjs/util": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-0.3.1.tgz", - "integrity": "sha512-HxXKYKg7vohx2/OupUN/4Sd02Ev3PBJ5q0gtjdcvXb0ErCva8jNHWfe/v5sU3UKjIB/uxOhc+TDOnhqffj9pRA==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.0.1.tgz", + "integrity": "sha512-d0N2yCxB8r4bn00/hvFZwM7goDcUhtViC5un4hPj73Ba4yrChLSJD8fy7Ps5jpTLg1fE9n4K0xBLc1y9WGwSsA==" }, "@discordjs/ws": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-0.8.3.tgz", - "integrity": "sha512-hcYtppanjHecbdNyCKQNH2I4RP9UrphDgmRgLYrATEQF1oo4sYSve7ZmGsBEXSzH72MO2tBPdWSThunbxUVk0g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.0.1.tgz", + "integrity": "sha512-avvAolBqN3yrSvdBPcJ/0j2g42ABzrv3PEL76e3YTp2WYMGH7cuspkjfSyNWaqYl1J+669dlLp+YFMxSVQyS5g==", "requires": { - "@discordjs/collection": "^1.5.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", + "@discordjs/collection": "^1.5.3", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", "@sapphire/async-queue": "^1.5.0", - "@types/ws": "^8.5.4", - "@vladfrangu/async_event_emitter": "^2.2.1", - "discord-api-types": "^0.37.41", - "tslib": "^2.5.0", + "@types/ws": "^8.5.5", + "@vladfrangu/async_event_emitter": "^2.2.2", + "discord-api-types": "0.37.50", + "tslib": "^2.6.1", "ws": "^8.13.0" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + } } }, "@jridgewell/resolve-uri": { @@ -730,11 +641,6 @@ "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.1.tgz", "integrity": "sha512-BxcYGzgEsdlG0dKAyOm0ehLGm2CafIrfQTZGWgkfKYbj+pNNsorZ7EotuZukc2MT70E0UbppVbtpBrqpzVzjNA==" }, - "@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" - }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -807,61 +713,48 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "discord-api-types": { - "version": "0.37.45", - "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.45.tgz", - "integrity": "sha512-r9m/g+YQfo7XWMrl645jvMlYoWF8lvns/ch4NCxsz/FbingrECu97LFSD2zKOvgHaSc90BHP8wgshaMcA2/c6Q==" + "version": "0.37.56", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.56.tgz", + "integrity": "sha512-Ih3wj0ZTaQxaJRqUEXHMIXfXB86bwMGC0wc2nNsyCJqeo3lC4qnxXtFIsC+IGI46+dSIinuayCAZ6sLEEM02Bw==" }, "discord.js": { - "version": "14.11.0", - "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.11.0.tgz", - "integrity": "sha512-CkueWYFQ28U38YPR8HgsBR/QT35oPpMbEsTNM30Fs8loBIhnA4s70AwQEoy6JvLcpWWJO7GY0y2BUzZmuBMepQ==", + "version": "14.13.0", + "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.13.0.tgz", + "integrity": "sha512-Kufdvg7fpyTEwANGy9x7i4od4yu5c6gVddGi5CKm4Y5a6sF0VBODObI3o0Bh7TGCj0LfNT8Qp8z04wnLFzgnbA==", "requires": { - "@discordjs/builders": "^1.6.3", - "@discordjs/collection": "^1.5.1", - "@discordjs/formatters": "^0.3.1", - "@discordjs/rest": "^1.7.1", - "@discordjs/util": "^0.3.1", - "@discordjs/ws": "^0.8.3", - "@sapphire/snowflake": "^3.4.2", - "@types/ws": "^8.5.4", - "discord-api-types": "^0.37.41", + "@discordjs/builders": "^1.6.5", + "@discordjs/collection": "^1.5.3", + "@discordjs/formatters": "^0.3.2", + "@discordjs/rest": "^2.0.1", + "@discordjs/util": "^1.0.1", + "@discordjs/ws": "^1.0.1", + "@sapphire/snowflake": "^3.5.1", + "@types/ws": "^8.5.5", + "discord-api-types": "0.37.50", "fast-deep-equal": "^3.1.3", "lodash.snakecase": "^4.1.1", - "tslib": "^2.5.0", - "undici": "^5.22.0", + "tslib": "^2.6.1", + "undici": "5.22.1", "ws": "^8.13.0" + }, + "dependencies": { + "discord-api-types": { + "version": "0.37.50", + "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.37.50.tgz", + "integrity": "sha512-X4CDiMnDbA3s3RaUXWXmgAIbY1uxab3fqe3qwzg5XutR3wjqi7M3IkgQbsIBzpqBN2YWr/Qdv7JrFRqSgb4TFg==" + } } }, "dotenv": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.0.tgz", - "integrity": "sha512-tHB+hmf8MRCkT3VVivGiG8kq9HiGTmQ3FzOKgztfpJQH1IWuZTOvKSJmHNnQPowecAmkCJhLrxdPhOr06LLqIQ==" + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==" }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, - "file-type": { - "version": "18.5.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-18.5.0.tgz", - "integrity": "sha512-yvpl5U868+V6PqXHMmsESpg6unQ5GfnPssl4dxdJudBrr9qy7Fddt7EVX1VLlddFfe8Gj9N7goCZH22FXuSQXQ==", - "requires": { - "readable-web-to-node-stream": "^3.0.2", - "strtok3": "^7.0.0", - "token-types": "^5.0.1" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -877,6 +770,11 @@ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==" }, + "magic-bytes.js": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.0.15.tgz", + "integrity": "sha512-bpRmwbRHqongRhA+mXzbLWjVy7ylqmfMBYaQkSs6pac0z6hBTvsgrH0r4FBYd/UYVJBmS6Rp/O+oCCQVLzKV1g==" + }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -887,75 +785,21 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, - "peek-readable": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", - "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==" - }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readable-web-to-node-stream": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", - "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", - "requires": { - "readable-stream": "^3.6.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" }, - "strtok3": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", - "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", - "requires": { - "@tokenizer/token": "^0.3.0", - "peek-readable": "^5.0.0" - } - }, "tiny-invariant": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" }, - "token-types": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", - "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", - "requires": { - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - } - }, "ts-mixer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.3.tgz", @@ -992,14 +836,14 @@ } }, "tslib": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", - "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, "typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==" + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==" }, "undici": { "version": "5.22.1", @@ -1009,20 +853,15 @@ "busboy": "^1.6.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" }, "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.0.tgz", + "integrity": "sha512-WR0RJE9Ehsio6U4TuM+LmunEsjQ5ncHlw4sn9ihD6RoJKZrVyH9FWV3dmnwu8B2aNib1OvG2X6adUCyFpQyWcg==", "requires": {} }, "yn": { diff --git a/discord-bot/package.json b/discord-bot/package.json index 43bf9e769a..c6e2e3bb46 100644 --- a/discord-bot/package.json +++ b/discord-bot/package.json @@ -7,13 +7,13 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@discordjs/rest": "^1.7.1", - "discord-api-types": "^0.37.45", - "discord.js": "^14.11.0", - "dotenv": "^16.3.0", + "@discordjs/rest": "^2.0.1", + "discord-api-types": "^0.37.56", + "discord.js": "^14.13.0", + "dotenv": "^16.3.1", "tiny-invariant": "^1.3.1", "ts-node": "^10.9.1", "tsconfig-paths": "^4.2.0", - "typescript": "^5.1.3" + "typescript": "^5.2.2" } } diff --git a/migrations/035-log-in-link.js b/migrations/035-log-in-link.js new file mode 100644 index 0000000000..8479753d01 --- /dev/null +++ b/migrations/035-log-in-link.js @@ -0,0 +1,12 @@ +module.exports.up = function (db) { + db.prepare( + /*sql*/ ` + create table "LogInLink" ( + "code" text unique not null, + "expiresAt" integer not null, + "userId" integer not null, + foreign key ("userId") references "User"("id") on delete cascade + ) strict + `, + ).run(); +}; diff --git a/public/locales/da/common.json b/public/locales/da/common.json index 9844d6c84d..cab40a84ac 100644 --- a/public/locales/da/common.json +++ b/public/locales/da/common.json @@ -30,7 +30,6 @@ "auth.errors.aborted": "logindforsøg afbrudt", "auth.errors.failed": "Loginforsøg fejlet", "auth.errors.discordPermissions": "Før at du kan oprette en profil på Sendou.ink, skal Sendou.ink have adgang til din Discordprofils navn, brugerbillede og sociale forbindelser (de sociale medier, som du har tilknyttet din discordprofil).", - "auth.errors.unknown": "Loginforsøget via discord fejlede grundet en ukendt årsag. Hvis dette bliver ved med at ske, så spørg om hjælp (på engelsk) på discord-serveren https://discord.gg/sendou via #helpdesk-chatten.", "footer.github.subtitle": "Kildekode", "footer.twitter.subtitle": "Opdateringer", diff --git a/public/locales/da/faq.json b/public/locales/da/faq.json index 3523e9875f..316318914f 100644 --- a/public/locales/da/faq.json +++ b/public/locales/da/faq.json @@ -6,7 +6,6 @@ "a2": "Du afgiver bestillingen af mærket til borzoic#1991. Prisen er mellem 10 til 30€ afhængig af detaljegraden af mærket. Derefter skal du kontakte Sendou for at få den tilføjet til hjemmesiden.\n\nEnhver turnering kan have et mærke som en præmie. Hvis du ønsker at tildele mærker for andre præstationer, så anbefales det, at du først kontakter Sendou og fortæller om din ide.", "q3": "Hvordan opdaterer jeg min avatar eller brugernavn?", - "a3": "Ændringer af brugernavn eller avatar på Discord bliver ikke synkroniseret til Sendou.ink med det samme. For at synkroniserer ændringerne med det samme har du 2 muligheder:\n\n1) Hvis du er medlem af hjemmesidens Discord-server eller Plus-serveren, så kan du blot vente, da der kører en synkronisering 1 gang om dagen, der håndterer ændringer af din Discord-profil.\n\n2) Du kan også logge af og på hjemmesiden, så sker synkroniseringen med det samme.", "q4": "Jeg tegnede et abonnement til sendou.ink via Patreon, men jeg kan ikke se nogle forandringer på hjemmesiden. ", "a4": "Sørg for at forbinde din Discord-bruger til Patreaon.com. Derefter vil der gå op til 2 timer, før Sendou.ink registrerer det og opdaterer hjemmesiden. Hvis du oplever nogle problemer. Send en direkte besked til Sendou for at få hjælp. (Korrespondancen skal foregå på engelsk) ", diff --git a/public/locales/de/common.json b/public/locales/de/common.json index 580cf51249..53372860ff 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -28,7 +28,6 @@ "auth.errors.aborted": "Einloggen abgebrochen", "auth.errors.failed": "Einloggen fehlgeschlagen", "auth.errors.discordPermissions": "Für dein sendou.ink-Profil benötigt die Seite Zugriff auf den Namen, Avatar und verbundene Social-Media-Accounts in deinem Discord-Profil.", - "auth.errors.unknown": "Das Einloggen via Discord ist aus unbekannten Gründen fehlgeschlagen. Falls dies wiederholt auftritt, kontaktiere uns bitte.", "footer.github.subtitle": "Sourcecode", "footer.twitter.subtitle": "Updates", diff --git a/public/locales/de/faq.json b/public/locales/de/faq.json index 04fb237e17..841fbd7128 100644 --- a/public/locales/de/faq.json +++ b/public/locales/de/faq.json @@ -6,7 +6,6 @@ "a2": "Du beauftragst borzoic#1991 das Abzeichen zu erstellen. Der Preis beträgt 10-30 €, je nach Komplexität. Danach kontaktierst du Sendou, um das Abzeichen zur Webseite hinzuzufügen.\n\nJedes Turnier kann ein Abzeichen als Preis haben. Wenn du Abzeichen für andere Leistungen vergeben willst, sprich am besten zuerst mit Sendou über deine Idee.", "q3": "Wie aktualisiere ich meinen Avatar oder Nutzernamen?", - "a3": "Wenn du deinen Benutzernamen oder Avatar auf Discord aktualisierst, werden sie nicht sofort auf sendou.ink aktualisiert. Um dies zu erreichen, hast du zwei Möglichkeiten:\n\n1) Wenn du Mitglied im Discord oder auf dem Plus-Server dieser Website bist, kannst du einfach warten. Es gibt eine Routine, die einmal täglich gestartet wird und sich um die Aktualisierung kümmert.\n\n2) Wenn du sie sofort aktualisieren willst, kannst du dich ausloggen und wieder auf sendou.ink einloggen.", "q4": "Ich habe auf Patreon abonniert, sehe aber keine Änderung auf der Webseite?", "a4": "Stelle sicher, dass dein Discord auf Patreon.com verknüpft ist. Danach kann es bis zu 2 Stunden dauern, bis der Status auf der Webseite aktualisiert wird. Sende bei Problemen eine DM an Sendou, um Hilfe zu erhalten.", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index c38e87239d..685db8096d 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -33,7 +33,7 @@ "auth.errors.aborted": "Login Aborted", "auth.errors.failed": "Login Failed", "auth.errors.discordPermissions": "For your sendou.ink profile, the site needs access to your Discord profile's name, avatar and social connections.", - "auth.errors.unknown": "The login via Discord failed for an unknown reason. If this keeps happening, please reach out for help.", + "auth.errors.unknown": "The login failed due to a server error. Please try again later or use the /login command via the Lohi bot. The bot can be found on sendou.ink's Discord:", "footer.github.subtitle": "Source code", "footer.twitter.subtitle": "Updates", @@ -169,6 +169,8 @@ "support.perk.customizedColorsTeam.extra": "It is enough that one member of the team is a patron to get this perk.", "support.perk.privateDiscord": "Access to an exclusive Discord channel", "support.perk.privateDiscord.extra": "Used to share occasional WIP updates, receive priority support and prioritized feature requests.", + "support.perk.prioritySupport": "Priority support", + "support.perk.prioritySupport.extra": "Access to a separate helpdesk that I prioritize for support requests", "custom.colors.title": "Custom colors", "custom.colors.bg": "Background", diff --git a/public/locales/en/faq.json b/public/locales/en/faq.json index 347a890510..0994052ecb 100644 --- a/public/locales/en/faq.json +++ b/public/locales/en/faq.json @@ -6,7 +6,7 @@ "a2": "You commission borzoic#1991 to make the badge. The price is 10-30€ depending on the complexity. Afterward, contact Sendou to get it added to the web page.\n\nAny tournament can have a badge as a prize. If you want to award badges for other feats it's best to consult Sendou first about your idea.", "q3": "How to update my avatar or username?", - "a3": "Updating username or avatar on Discord doesn't right away update them on sendou.ink. To make that happen you have two options:\n\n1) If you are a member of this website's Discord or the Plus Server you can simply wait. There is a routine that runs once a day that handles the updating.\n\n2) Alternatively if you want to update them right away you can log out and back in on sendou.ink.", + "a3": "Updating username or avatar on Discord doesn't right away update them on sendou.ink. To make that happen you have two options:\n\n1) If you are a member of this website's Discord or the Plus Server you can simply wait. There is a routine that runs once a day that handles the updating.\n\n2) To get them to update right away you can use the /update-profile command of the Lohi Discord bot.", "q4": "I subscribed on Patreon but I don't see any changes on the website?", "a4": "Make sure to connect your Discord on Patreon.com. After doing so it will take up to 2 hours for the status to update on the site. If you are having problems DM Sendou directly for help.", diff --git a/public/locales/es-ES/faq.json b/public/locales/es-ES/faq.json index 22bdd83fc7..7f64fc9608 100644 --- a/public/locales/es-ES/faq.json +++ b/public/locales/es-ES/faq.json @@ -5,6 +5,5 @@ "q2": "¿Cómo puedo obtener un premio de insignia para mi evento?", "a2": "Puedes contratar a borzoic#1991 para hacer tu insignia. El precio es de 10-30€, dependiendo de lo complejo que sea. Despues, contacta a Sendou para añadirlo al sitio.\n\nCualquier torneo puede tener una insignia como premio. Si quieres entregar insignias por otras hazañas, es mejor consultar primero a Sendou sobre tu idea.", - "q3": "¿Cómo puedo actualizar mi avatar o nombre de usuario?", - "a3": "Si actualizas tu nombre de usuario o avatar en Discord, no cambian de inmediato en sendou.ink. Para que eso suceda tienes dos opciones:\n\n1) Si eres miembro del Discord de este sitio o del Plus Server, simplemente puedes esperar. Hay una rutina diaria que se encarga de la actualización.\n\n2) Alternativamente, si deseas actualizarlos de inmediato, puede cerrar la sesión y reiniciarla en sendou.ink." + "q3": "¿Cómo puedo actualizar mi avatar o nombre de usuario?" } diff --git a/public/locales/es-US/faq.json b/public/locales/es-US/faq.json index 22bdd83fc7..7f64fc9608 100644 --- a/public/locales/es-US/faq.json +++ b/public/locales/es-US/faq.json @@ -5,6 +5,5 @@ "q2": "¿Cómo puedo obtener un premio de insignia para mi evento?", "a2": "Puedes contratar a borzoic#1991 para hacer tu insignia. El precio es de 10-30€, dependiendo de lo complejo que sea. Despues, contacta a Sendou para añadirlo al sitio.\n\nCualquier torneo puede tener una insignia como premio. Si quieres entregar insignias por otras hazañas, es mejor consultar primero a Sendou sobre tu idea.", - "q3": "¿Cómo puedo actualizar mi avatar o nombre de usuario?", - "a3": "Si actualizas tu nombre de usuario o avatar en Discord, no cambian de inmediato en sendou.ink. Para que eso suceda tienes dos opciones:\n\n1) Si eres miembro del Discord de este sitio o del Plus Server, simplemente puedes esperar. Hay una rutina diaria que se encarga de la actualización.\n\n2) Alternativamente, si deseas actualizarlos de inmediato, puede cerrar la sesión y reiniciarla en sendou.ink." + "q3": "¿Cómo puedo actualizar mi avatar o nombre de usuario?" } diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 37cf229738..eba8b64dd5 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -32,7 +32,6 @@ "auth.errors.aborted": "Connexion abandonnée", "auth.errors.failed": "Connexion échouée", "auth.errors.discordPermissions": "Pour mettre en place votre profil, sendou.ink a besoin de votre nom de profil Discord, de votre avatar et de vos réseaux connectés.", - "auth.errors.unknown": "La connexion à Discord a échoué pour une raison inconnue. Si l'erreur persiste, n'hésitez pas à demander de l'aide.", "footer.github.subtitle": "Code source", "footer.twitter.subtitle": "Mises à jour", diff --git a/public/locales/fr/faq.json b/public/locales/fr/faq.json index ffccc0244c..8e95de65c6 100644 --- a/public/locales/fr/faq.json +++ b/public/locales/fr/faq.json @@ -6,7 +6,6 @@ "a2": "Il vous faudra commissionner borzoic#1991 pour créer un badge. Le prix peut varier entre 10€ et 30€ en fonction de la complexité. Après ça, contactez Sendou pour que le badge soit ajouté à la page web.\n\nTous les tournois peuvent avoir un badge pour récompense. Si vous voulez récompenser d'autres actions avec un badge, contactez tout d'abord Sendou avec votre idée.", "q3": "Comment mettre à jour mon pseudo ou mon avatar ?", - "a3": "Mettre à jour son pseudo ou avatar sur Discord ne se reflète pas immédiatement sur sendou.ink. Pour voir ce changement, vous avez deux options :\n\n1) Si vous êtes un membre du Discord de sendou.ink ou du Plus Server, il vous suffit d'attendre. Le site se mettra à jour automatiquement dans les 24 heures.\n\n2) Alternativement, si vous voulez les mettre à jour immédiatement, vous pouvez vous déconnecter et vous reconnecter sur sendou.ink.", "q4": "Je me suis abonné au Patreon mais je ne vois pas de changement, c'est normal ?", "a4": "Assurez-vous d'avoir lié votre compte Discord sur Patreon.com. Après avoir fait ça, votre statut peut mettre jusqu'à 2 heures à se mettre à jour sur le site. Si vous avez encore des soucis, n'hésitez pas à envoyer un MP à Sendou directement.", diff --git a/public/locales/he/common.json b/public/locales/he/common.json index f7bfcefedc..8d65d08cb5 100644 --- a/public/locales/he/common.json +++ b/public/locales/he/common.json @@ -32,7 +32,6 @@ "auth.errors.aborted": "הכניסה בוטלה", "auth.errors.failed": "הכניסה נכשלה", "auth.errors.discordPermissions": "עבור פרופיל sendou.ink שלך, האתר זקוק לגישה לשם, הפרופיל והקשרים החברתיים של פרופיל ה-Discord שלך.", - "auth.errors.unknown": "הכניסה דרך Discord נכשלה מסיבה לא ידועה. אם זה ממשיך לקרות, אנא פנו לעזרה.", "footer.github.subtitle": "קוד מקור", "footer.twitter.subtitle": "עדכונים", diff --git a/public/locales/he/faq.json b/public/locales/he/faq.json index 9722597bcd..9ac7ad3e1b 100644 --- a/public/locales/he/faq.json +++ b/public/locales/he/faq.json @@ -6,7 +6,6 @@ "a2": "צריך להזמין מ-borzoic#1991 ליצור את התג. המחיר הוא 10-30€ תלוי במורכבות. לאחר מכן, צרו קשר עם Sendou כדי להוסיף אותו לדף האינטרנט.\n\nכל טורניר יכול לקבל תג כפרס. אם הנכם רוצים להעניק תגים עבור הישגים אחרים, עדיף להתייעץ קודם עם Sendou לגבי זה.", "q3": "איך לעדכן את הפרופיל או את שם המשתמש שלי?", - "a3": "עדכון שם משתמש או פרופיל ב-Discord לא מתעדכן מיד ב- sendou.ink. כדי לגרום לזה לקרות יש לכם שתי אפשרויות:\n\n1) אם אתם חברים ב-Discord או בשרת הפלוס של אתר זה, אתם יכולים פשוט לחכות. יש בדיקה שפועלת פעם ביום שמטפלת בעדכון.\n\n2) לחילופין אם ברצונכם לעדכן מיד, תוכלו להתנתק ולהתחבר חזרה ל- sendou.ink.", "q4": "נרשמתי ב-Patreon אבל אני לא רואה שינויים באתר?", "a4": "יש לוודא את חיבור הדיסקורד שלכם ל-Patreon.com. לאחר מכן, זה יקח שעתיים עד שהסטטוס יתעדכן באתר. אם הנכם נתקלים בבעיות שלחו הודעה פרטית DM ל-Sendou לעזרה.", diff --git a/public/locales/it/common.json b/public/locales/it/common.json index d07b2ef3e1..eeb6f7dda5 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -22,7 +22,6 @@ "auth.errors.aborted": "Accesso cancellato", "auth.errors.failed": "Accesso fallito", "auth.errors.discordPermissions": "Per il tuo profilo di sendou.ink, il sito ha bisogno di accesso al nome utente, avatar e connessioni social del tuo profilo Discord.", - "auth.errors.unknown": "L'accesso tramite Discord ha fallito per una ragione sconosciuta. Se continua a succedere, conttattaci per un pò di aiuto.", "footer.github.subtitle": "Codice sorgente", "footer.twitter.subtitle": "Aggiornamenti", "footer.discord.subtitle": "Aiuto & feedback", diff --git a/public/locales/it/faq.json b/public/locales/it/faq.json index a5c6a8fbe0..cbfb9e4184 100644 --- a/public/locales/it/faq.json +++ b/public/locales/it/faq.json @@ -6,7 +6,6 @@ "a2": "Contatta borzoic#1991 per creare il tuo badge. Il prezzo è 10-30€ e dipende dalla complessità della medaglia. In seguito, contatta Sendou per aggiungere la medaglia alla pagina. \n\nTutti i tornei possono avere una medaglia come premio in palio. Se vuoi premiare una medaglia per altre imprese, è raccomandato prima contattare Sendou con la tua idea.", "q3": "Come faccio ad aggiornare il mio nome utente o avatar?", - "a3": "Aggiornare il nome utente o avatar su Discord non li aggiorna instantaneamente su sendou.ink. Per aggiornarli hai due opzioni: \n\n1) Se sei un membro del server Discord pubblico di questo sito o il Server Plus, puoi semplicemente aspettare. Una volta al giorno, tutti i profili dei membri connessi vengono aggiornati.\n\n2) Alternativamente, se vuoi aggiornarli subito, puoi semplicemente uscire e riaccedere su sendou.ink.", "q4": "Sono diventato un sostenitore su Patreon, come mai non vedo nessun cambiamento sul sito?", "a4": "Assicurati di aver connesso il tuo account Discord con quello Patreon. Dopo averli sincronizzati, l'aggiornamento dei dati sul sito potrebbe impiegare fino a 2 ore. Se stai avendo problemi, scrivi direttamente a Sendou.", diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json index 2ca77b7692..eb04b95215 100644 --- a/public/locales/ja/common.json +++ b/public/locales/ja/common.json @@ -33,7 +33,6 @@ "auth.errors.aborted": "ログインを中断しました", "auth.errors.failed": "ログインに失敗しました", "auth.errors.discordPermissions": "sendou.ink は、Discord のプロファイル名、アバター、SNS連携をサイトのプロファイルに使用します。", - "auth.errors.unknown": "Discord 経由でのログインに失敗しました。この減少が続くようであれば、サポートに連絡してください。", "footer.github.subtitle": "ソースコード", "footer.twitter.subtitle": "最新情報", diff --git a/public/locales/ja/faq.json b/public/locales/ja/faq.json index 8ba91d3f2d..d25bbc55ef 100644 --- a/public/locales/ja/faq.json +++ b/public/locales/ja/faq.json @@ -6,7 +6,6 @@ "a2": "borzoic#1991 にバッジの作成を依頼してください。 値段は複雑さの度合いによって異なりますが、10-30ユーロくらいです。 その後、Sendou にバッジをウェブサイトに追加するよう連絡をとってください。\n\n どのようなトーナメントもバッジを賞品とすることができます。 その他の功績などにバッジを賞品として与えたい場合は、その案をまず Sendou に相談してください", "q3": "アバターとユーザー名はどうやって更新すればよいですか?", - "a3": "ユーザー名とDiscord のアバターの更新は sendou.ink 上では即時に反映されません。更新を完了するためには、以下の2つの方法があります:\n\n1) あなたがこのウェブサイトの Discord または Plus Server のメンバーの場合は、単純にすこし待ってください。1日に1回、それらの更新を実行するタスクがあります。\n\n2) また、一旦 sendou.ink をログアウトしてログインし直すことで即時に反映することもできます。", "q4": "Patreon をサブスクライブしたけれど、このウェブサイトに何も変更がないのですが..?", "a4": "Discord 上で Patreon.com を設定しているか確認してください。設定後、最大2時間後にはウェブサイト上に反映されます。もし問題があれば、Sendou に直接 DM を送ってください。", diff --git a/public/locales/ko/common.json b/public/locales/ko/common.json index c3aac73e31..e63866ef3c 100644 --- a/public/locales/ko/common.json +++ b/public/locales/ko/common.json @@ -32,7 +32,6 @@ "auth.errors.aborted": "로그인 중단됨", "auth.errors.failed": "로그인 실패", "auth.errors.discordPermissions": "sendou.ink 프로필을 위해 디스코드 프로필의 이름, 아바타와 연락처에 대한 접근이 필요합니다.", - "auth.errors.unknown": "알 수 없는 이유로 디스코드를 통한 로그인이 실패했습니다. 계속되면 도움을 청하세요.", "footer.github.subtitle": "소스 코드", "footer.twitter.subtitle": "업데이트들", diff --git a/public/locales/ko/faq.json b/public/locales/ko/faq.json index 3d0647acb6..73d7fb9754 100644 --- a/public/locales/ko/faq.json +++ b/public/locales/ko/faq.json @@ -3,6 +3,5 @@ "a1": "Plus Server는 서양 고랭크 플레이어들이 같이 플레이어하고 상대할 사람들을 찾는 디스코드 서버입니다. 2017년 9월에 시작되었습니다. 세 티어로 나뉘고 +1이 가장 높습니다. 서버에 있는 멤버에게서 추천을 받고 매달있는 투표를 동과하면 자격을 얻습니다.\n\n투표에서는 결과에 따라 퍼센트 비율을 받습니다. 0%라면 투표에 참여한 모두가 반대했다는 뜻이고 100%는 그 반대입니다. 투표를 통과하려면 50%가 필요합니다. 멤버가 50% 이하의 점수를 받으면 티어가 내려가거나 +3의 경우 퇴출됩니다.", "q2": "제 이벤트에 어떻게 배지 상품을 받을 수 있죠?", "a2": "배지를 만들려면 borzoic#1991에게 커미션을 줍니다. 가격은 복잡한 정도에 따라 10-30€입니다. 그 다음 Sendou에게 연락해서 사이트에 추가합니다.\n\n어떤 토너먼트도 상품으로 배지를 가질 수 있습니다. 다른 위업으로 배지를 수여하고 싶다면 우선 Sendou에게 아이디어를 상의하는 것이 좋습니다.", - "q3": "어떻게 제 아바타 또는 닉네임을 변경할 수 있죠?", - "a3": "디스코드에서 닉네임 또는 아바타를 변경해도 sendou.ink에 곧바로 적용되지 않습니다. 그러려면 두 가지 방법이 있습니다:\n\n1) 사이트의 디스코드 또는 Plus Server의 멤버라면 단순히 기다리면 됩니다. 매일 업데이트하는 루틴이 있습니다.\n\n2) 또는 곧바로 업데이트하고 싶다면 sendou.ink에서 로그아웃하고 다시 로그인하면 됩니다." + "q3": "어떻게 제 아바타 또는 닉네임을 변경할 수 있죠?" } diff --git a/public/locales/nl/faq.json b/public/locales/nl/faq.json index 5d559bb906..daa2e85eb8 100644 --- a/public/locales/nl/faq.json +++ b/public/locales/nl/faq.json @@ -5,6 +5,5 @@ "q2": "Hoe krijg ik een badge prijs voor mijn evenement?", "a2": "Je moet een badge bij borzoic#1991 bestellen en die voor je laten maken, de prijs is €10-€30 afhankelijk van de complexiteit. Neem naderhand contact op met Sendou om de badge toe te voegen aan de website. Elk evenement mag een badge als prijs hebben. Als je badges wilt uitreiken voor andere prestaties is het beter om het eerst met Sendou te overleggen.", - "q3": "Hoe update ik mijn avatar of gebruikersnaam?", - "a3": "Als je je naam of avatar update op Discord veranderd hij niet meteen op sendou.ink. Als je lid bent van de sendou.ink Discord of de Plus Server moet je even wachten, er is een routine die eens per dag de namen en avatars updatet. Als je ze liever meteen wilt updaten kun je ook uit- en weer inloggen op sendou.ink." + "q3": "Hoe update ik mijn avatar of gebruikersnaam?" } diff --git a/public/locales/pl/common.json b/public/locales/pl/common.json index 6120ac1435..2e519ad564 100644 --- a/public/locales/pl/common.json +++ b/public/locales/pl/common.json @@ -27,7 +27,6 @@ "auth.errors.aborted": "Logowanie przerwane", "auth.errors.failed": "Logowanie nieudane", "auth.errors.discordPermissions": "Do twojego profilu sendou.ink, ta strona potrzebuje dostęp do twojej nazwy, avataru i połączeń konta Discord.", - "auth.errors.unknown": "Logowanie poprzez Discorda nie udało się. Jeśli problem się nie naprawi, sięgnij po pomoc.", "footer.github.subtitle": "Kod", "footer.twitter.subtitle": "Aktualizacje", diff --git a/public/locales/pl/faq.json b/public/locales/pl/faq.json index 0947d960a7..e95a30d9c1 100644 --- a/public/locales/pl/faq.json +++ b/public/locales/pl/faq.json @@ -6,7 +6,6 @@ "a2": "Musisz zamówić odznakę od borzoic#1991. Cena to 10-30€ w zależności od kompleksowości. Potem napisz do Sendou, by dodał na strone.\n\nKażdy turniej może mieć odznake jako nagrode. Jeśli chcesz dodać odznake za coś innego, skonsultuj się z Sendou'em.", "q3": "Jak zaktualizować nazwę/avatar na stronie?", - "a3": "Zaktualizowanie nazwy lub avataru na Discordzie nie aktualizuje też automatycznie tego na sendou.ink. Jeśli chcesz zaktualizować, masz dwie opcje:\n\n1) Jeśli jesteś członkiem Plus Server lub servera tej strony po prostu poczekaj. Raz dziennie jest rutyna, która te dane aktualizuje na stronie.\n\n2) Jeśli chcesz, by się zaktualizowały od razu, wystarczy się wylogować i ponownie zalogować na stronę.", "q4": "Zostałem Patronem ale nie widzę żadnych zmian na stronie?", "a4": "Upewnij się, że twoje konto Patreon jest połączone z twoim kontem Discord. Po zrobieniu tego zajmie do 2 godzin by się strona zaktualizowała. Jeśli masz problemy napisz prywatnie do Sendou.", diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 00904ff5ae..5bde2d8d5b 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -27,7 +27,6 @@ "auth.errors.aborted": "Вход отменён", "auth.errors.failed": "Ошибка входа", "auth.errors.discordPermissions": "Для вашего профиля на sendou.ink странице нужет доступ к вашему имени, аватару и привязанным аккаунтам соц. сетей в Discord.", - "auth.errors.unknown": "Вход через Discord не удался по неизвестной причине. Если это продолжается — обратитесь за помощью.", "footer.github.subtitle": "Исходный код", "footer.twitter.subtitle": "Обновления", diff --git a/public/locales/ru/faq.json b/public/locales/ru/faq.json index 802d112abe..5ebee2f1ca 100644 --- a/public/locales/ru/faq.json +++ b/public/locales/ru/faq.json @@ -6,7 +6,6 @@ "a2": "Вы можете заказать значок у borzoic#1991. Цена — 10-30€ в зависимости от сложности. После этого связитесь с Sendou, чтобы добавить её на страницу.\n\nЛюбой турнир может иметь значок в качестве награды. Если вы хотите награждать значком за какие-то другие достижения — то лучше сначала обсудить эту идею с Sendou.", "q3": "Как обновить мой аватар или ник?", - "a3": "Обновление ника или аватара в Discord не сразу обновляет их на sendou.ink. Есть два варианта, когда это произойдёт:\n\n1) Если вы есть на Discord-сервере этого сайта или Plus Server, то вы можете просто подожать. Ежедневно запускается специальная процедура, которая занимается обновлением.\n\n2) Если вы хотите обновиться прямо сейчас, то вы можете разлогиниться и залогиниться обратно на sendou.ink.", "q4": "Я подписался на Patreon, но не вижу изменений на вебсайте?", "a4": "Убедитесь, что вы подключили учетную запись Discord на Patreon.com. Обычно после этого нужно подождать до двух часов для обновления статуса на странице. Если у вас возникли проблемы — отправьте личное сообщение Sendou для помощи.", diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json index 1f16e841ef..6849e65cd8 100644 --- a/public/locales/zh/common.json +++ b/public/locales/zh/common.json @@ -32,7 +32,6 @@ "auth.errors.aborted": "登录中止", "auth.errors.failed": "登录失败", "auth.errors.discordPermissions": "为了完善您的sendou.ink个人资料,网站需要获取您的Discord名字、头像和社交链接。", - "auth.errors.unknown": "通过Discord登录因未知原因失败。如果该错误持续发生,请寻求帮助。", "footer.github.subtitle": "源代码", "footer.twitter.subtitle": "更新", diff --git a/public/locales/zh/faq.json b/public/locales/zh/faq.json index 8b8f15193f..e6b44c9a46 100644 --- a/public/locales/zh/faq.json +++ b/public/locales/zh/faq.json @@ -6,7 +6,6 @@ "a2": "可以委托borzoic#1991制作徽章。价格在10至30欧元之间,价格根据复杂程度变化。之后联系Sendou将徽章添加到网页。\n\n任何比赛都可以添加徽章作为奖品。如想添加其他用途的徽章,请先联系Sendou。", "q3": "如何更新我的头像与用户名?", - "a3": "在Discord上修改头像和用户名之后不会立刻在sendou.ink上更新。两种方法更新头像与用户名:\n\n1) 如果您在本网站的Discord服务器中,或在Plus Server中,稍作等待即可。每天例行更新。\n\n2) 如果想立即更新,可以登出再登陆sendou.ink.", "q4": "我是Patreon上的订阅者,但是网站没有变化。", "a4": "请确定您的Discord绑定了Patreon.com。绑定好后,大概需要两个小时来更新网站。如果您还有其他问题,请直接私信Sendou。", diff --git a/scripts/create-analyzer-json.ts b/scripts/create-analyzer-json.ts index 6a9edf6262..e123805259 100644 --- a/scripts/create-analyzer-json.ts +++ b/scripts/create-analyzer-json.ts @@ -784,7 +784,6 @@ function subWeaponShouldBeSkipped(subWeapon: SubWeapon) { } function specialWeaponShouldBeSkipped(specialWeapon: SpecialWeapon) { - console.log({ specialWeapon }); if (WEAPON_TYPES_TO_IGNORE.some((val) => specialWeapon.Type.includes(val))) { return true; }