diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..0f969bc8b --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +max_line_length = 120 + +[*.{md,markdown}] +trim_trailing_whitespace = false diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..fd1b8c411 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +DOTENV_CONFIG_QUIET=true +HYPIXEL_KEY=HYPIXEL_API_KEY +HYPIXEL_URL=https://api.hypixel.net/v2 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 2196e0fc8..5e7944f5d 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,9 +2,78 @@ If you want to contribute to hypixel-api-reborn, feel free to fork the repository and submit pull request. -## Setup +## Table of contents -1. Fork the repository. -2. Run `npm ci`. -3. Code your idea. -4. Run `npm run eslint` to run ESlint. +- [Requirements](#requirements) +- [Project Setup](#project-setup) +- [Testing your changes](#testing-your-changes) +- [Submitting a pull request](#submitting-a-pull-request) +- [Common issues](#common-issues) + +### Requirements + +- [Node v20.16.0 or higher](https://nodejs.org/en/learn/getting-started/how-to-install-nodejs) +- [pnpm v9.7.1 or higher](https://pnpm.io/installation) + +### Project Setup + +Once you have the requirements installed, you can clone the repository and install the dependencies. + +```bash +pnpm install +``` + +Once you have all the packages installed, you will need to create a `.env` file. This file will contain the Hypixel API +key. You can get one by going to the [Hypixel Developer Portal.](https://developer.hypixel.net/) This key will be used +in the tests. Your `.env` file should look like this: + +```env +HYPIXEL_KEY=HYPIXEL_API_KEY +``` + +**If your using vscode** With vscode we have a few recommended extensions that you can install to help with development. +You will be promoted to install these when you open the project in vscode. If you don't see the prompt, you can install +the extensions manually. Here are the recommended extensions: + +- [Editor Config](https://marketplace.visualstudio.com/items?itemName=editorconfig.editorconfig) +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) +- [Gitlens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) +- [Better Comments](https://marketplace.visualstudio.com/items?itemName=aaron-bond.better-comments) +- [Vitest](https://marketplace.visualstudio.com/items?itemName=vitest.explorer) +- [GitHub Pull Requests](https://marketplace.visualstudio.com/items?itemName=github.vscode-pull-request-github) + +### Testing your changes + +Before submitting a pull request, make sure to test your changes. You can run the tests with the following command: + +```bash +pnpm test +``` + +### Submitting a pull request + +When submitting a pull request, make sure to provide a detailed description of the changes you made. If you are adding a +new feature, make sure to include tests for it. If you are fixing a bug, make sure to include the bug report +information. When making a pull request we have a few requirements: + +- Tests must pass (`pnpm test`) +- Code must be linted (`pnpm eslint`) +- Code must be formatted (`pnpm prettier`) +- A clear and detailed description of the changes that you have done +- Checkboxes for the changes you made +- Screenshots of the code running (if applicable) + +### Common issues + +There are a few common issues that can come up when contributing to the project. Here are a few of them: + +- **Tests failing**: Tests will fail when making a pull request. This is because it's missing an API key set in github + actions. If this is the case, you can ignore the tests and someone will run them for you when reviewing the pull + request. + +- **Code formatting**: Code must be formatted and the github actions will check for this. If the code is not formatted, + the github action will fail and you will need to correct this before the pull request can be merged. + +- **Code using npm**: Any code that includes an npm lock file will not be accepted. This is because we use pnpm for + package management. If you have an npm lock file, you will need to remove it and use pnpm to install the packages. diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md index fcff3ccdc..9a9d6d32d 100644 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ b/.github/ISSUE_TEMPLATE/Bug_report.md @@ -5,5 +5,14 @@ about: Report a bug ### Bug report -- Part of code where error occurred -- What error occurred +- Part of code where error occurred: +- What error occurred: + +### Expected behavior + +- What you expected to happen: + +### Additional context + +- Node version: +- Package version: diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b81bce490..529a93d41 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -14,12 +14,11 @@
Checkboxes -- [x] I've added new features. (methods or parameters) -- [ ] I've added jsdoc and typings. +- [ ] I've added new features. (methods or parameters) - [ ] I've fixed bug. (_optional_ you can mention a issue if there is one) - [ ] I've corrected the spelling in README, documentation, etc. -- [ ] I've tested my code. (`npm run tests`) -- [ ] I've check for issues. (`npm run eslint`) -- [ ] I've fixed my formatting. (`npm run prettier`) +- [ ] I've tested my code. (`pnpm test`) +- [ ] I've check for issues. (`pnpm eslint`) +- [ ] I've fixed my formatting. (`pnpm prettier`)
diff --git a/.github/SECURITY.md b/.github/SECURITY.md index eafeff54f..9e79f949f 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -17,5 +17,5 @@ be no issue and the team will be greatful for your actions. To report a vulnerability you can do so in the [Discord Server](https://discord.gg/NSEBNMM) by openeing a support ticket or you can contact the primary contributor of this repository using the following contact methods: -- @kathund. on Discord +- @.kathund on Discord - @kathundd on Telegram diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 96baa6d25..000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: 2 -updates: - - package-ecosystem: npm - directory: '/' - schedule: - interval: 'weekly' - assignees: - - 'kathund' - reviewers: - - 'kathund' - commit-message: - prefix: '🟨' - prefix-development: '🟦' - open-pull-requests-limit: 10 - labels: - - 'dependencies' - ignore: - - dependency-name: 'chai' - - dependency-name: 'mocha' diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 000000000..79f07a0ae --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,24 @@ +XS: + name: size/XS + lines: 0 + color: 3CBF00 +S: + name: size/S + lines: 50 + color: 5D9801 +M: + name: size/M + lines: 200 + color: 7F7203 +L: + name: size/L + lines: 1000 + color: A14C05 +XL: + name: size/XL + lines: 3000 + color: C32607 +XXL: + name: size/XXL + lines: 7500 + color: E50009 diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 000000000..08f3ae2c3 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["config:recommended", "group:allNonMajor"], + "rebaseWhen": "behind-base-branch", + "ignoreDeps": ["pnpm", "node", "@types/node", "typedoc", "hypixel-api-reborn", "skyhelper-networth"], + "semanticCommits": "enabled", + "labels": ["dependencies"], + "schedule": ["* 0 * * *"], + "enabledManagers": ["npm"], + "rangeStrategy": "bump", + "prConcurrentLimit": 5, + "forkProcessing": "enabled", + "prHourlyLimit": 0, + "timezone": "UTC", + "packageRules": [ + { "matchUpdateTypes": ["minor", "patch"], "matchCurrentVersion": "!/^0/", "commitMessagePrefix": "chore(deps):" } + ] +} diff --git a/.github/scripts/Utils.ts b/.github/scripts/Utils.ts new file mode 100644 index 000000000..99f169383 --- /dev/null +++ b/.github/scripts/Utils.ts @@ -0,0 +1,29 @@ +import { readdir } from 'fs/promises'; + +export interface ScanDirectoryOptions { + goDeep?: boolean; + replaceSrc?: boolean; +} + +export async function scanDirectory(directoryPath: string, options?: ScanDirectoryOptions): Promise { + const parsedOptions: ScanDirectoryOptions = { + goDeep: options?.goDeep ?? true, + replaceSrc: options?.replaceSrc ?? false + }; + const filePaths: string[] = []; + const files = await readdir(directoryPath, { withFileTypes: true }); + + for (const file of files) { + const fullPath = directoryPath + file.name; + if (file.isDirectory() && parsedOptions.goDeep) { + const paths = await scanDirectory(`${fullPath}/`, parsedOptions); + paths.forEach((path) => filePaths.push(path)); + } else { + if (fullPath.endsWith('.test.ts')) continue; + if (fullPath.endsWith('index.ts')) continue; + filePaths.push(fullPath.replaceAll('./src/', parsedOptions.replaceSrc ? './' : './src/')); + } + } + + return filePaths; +} diff --git a/.github/scripts/checkCoverage.ts b/.github/scripts/checkCoverage.ts new file mode 100644 index 000000000..66990138e --- /dev/null +++ b/.github/scripts/checkCoverage.ts @@ -0,0 +1,41 @@ +import { parseStringPromise } from 'xml2js'; +import { readFileSync } from 'fs'; + +const coverageDataFile = readFileSync('./coverage/clover.xml', 'utf-8'); +const parsed = await parseStringPromise(coverageDataFile); + +const codeStats = parsed.coverage.project[0].metrics[0].$; +const info = { + statements: Number(codeStats.statements), + coveredStatements: Number(codeStats.coveredstatements), + conditionals: Number(codeStats.conditionals), + coveredConditionals: Number(codeStats.coveredconditionals), + methods: Number(codeStats.methods), + coveredMethods: Number(codeStats.coveredmethods) +}; + +const baseline = 95; + +const statementsCoverage = (info.coveredStatements / info.statements) * 100; +if (statementsCoverage <= baseline) { + throw new Error(`Statements is required to be ${baseline}% or higher. Currently ${statementsCoverage.toFixed(2)}`); +} + +const conditionalsCoverage = (info.coveredConditionals / info.conditionals) * 100; +if (conditionalsCoverage <= baseline) { + throw new Error( + `Conditionals is required to be ${baseline}% or higher. Currently ${conditionalsCoverage.toFixed(2)}` + ); +} + +const methodsCoverage = (info.coveredMethods / info.methods) * 100; +if (methodsCoverage <= baseline) { + throw new Error(`Methods is required to be ${baseline}% or higher. Currently ${methodsCoverage.toFixed(2)}`); +} + +const combinedCoverage = statementsCoverage + conditionalsCoverage + methodsCoverage; +if (combinedCoverage <= baseline) { + throw new Error( + `Everything Combined is required to be ${baseline}% or higher. Currently ${combinedCoverage.toFixed(2)}` + ); +} diff --git a/.github/scripts/generateAPIIndexFile.ts b/.github/scripts/generateAPIIndexFile.ts new file mode 100644 index 000000000..b93335f01 --- /dev/null +++ b/.github/scripts/generateAPIIndexFile.ts @@ -0,0 +1,32 @@ +import { format } from 'prettier'; +import { readFileSync, writeFileSync } from 'fs'; +import { scanDirectory } from './Utils'; + +const prettierConfig = JSON.parse(readFileSync('.prettierrc').toString('utf-8')); + +(async () => { + const lines: string[] = ['/* v8 ignore next 10000 */', '']; + + const importNames: string[] = []; + + const apiPaths = await scanDirectory('./src/API/', { goDeep: false, replaceSrc: true }); + const fixedAPIPaths: string[] = []; + + apiPaths.forEach((path) => { + const importName = path.split('.ts')[0].split('/')[path.split('.ts')[0].split('/').length - 1]; + importNames.push(importName); + const fixedPath = path.replaceAll('.ts', '.js').replaceAll('./API/', './'); + fixedAPIPaths.push(`import ${importName} from '${fixedPath}';`); + }); + + fixedAPIPaths.sort().forEach((path) => lines.push(path)); + + lines.push(''); + lines.push('export default {'); + importNames.sort().forEach((importName) => lines.push(`${importName},`)); + lines.push('};'); + lines.push(''); + + const formatted = await format(lines.join('\n'), { ...prettierConfig, filepath: './src/API/index.ts' }); + writeFileSync('./src/API/index.ts', formatted); +})(); diff --git a/.github/scripts/generateBasicTests.ts b/.github/scripts/generateBasicTests.ts new file mode 100644 index 000000000..1f59518b2 --- /dev/null +++ b/.github/scripts/generateBasicTests.ts @@ -0,0 +1,300 @@ +import { + ClassDeclaration, + Declaration, + ImportDeclaration, + LeftHandSideExpression, + MethodDeclaration, + ModifierFlags, + Node, + ParameterDeclaration, + PropertyDeclaration, + ScriptTarget, + SourceFile, + SyntaxKind, + createProgram, + createSourceFile, + forEachChild, + getCombinedModifierFlags, + isClassDeclaration, + isEnumDeclaration, + isFunctionDeclaration, + isIdentifier, + isImportDeclaration, + isInterfaceDeclaration, + isMethodDeclaration, + isNamedImports, + isPropertyDeclaration, + isQualifiedName, + isReturnStatement, + isTypeAliasDeclaration, + isVariableStatement +} from 'typescript'; +import { format } from 'prettier'; +import { readFileSync, writeFileSync } from 'node:fs'; +import { scanDirectory } from './Utils'; + +const prettierConfig = JSON.parse(readFileSync('.prettierrc').toString('utf-8')); +const primitiveTypes = new Set(['string', 'number', 'boolean', 'any', 'unknown', 'void']); + +interface ParsedProperty { + name: string; + type: string; + kind: 'primitive' | 'class'; +} + +interface ParsedImport { + module: string; + named?: string[]; + default?: string; +} + +interface ParsedMethod { + name: string; + returnType: string; + parameters: ParsedProperty[]; + body?: string; +} + +interface ParsedClass { + className: string; + properties: ParsedProperty[]; + methods: ParsedMethod[]; + imports: ParsedImport[]; + extending: string; +} + +function handleImportDeclaration(sourceFile: SourceFile, node: ImportDeclaration): ParsedImport { + const importObj: ParsedImport = { module: node.moduleSpecifier.getText(sourceFile).replace(/['"]/g, '') }; + if (!node.importClause) return importObj; + if (node.importClause.name) importObj.default = node.importClause.name.getText(sourceFile); + if (!node.importClause.namedBindings) return importObj; + if (!isNamedImports(node.importClause.namedBindings)) return importObj; + importObj.named = node.importClause.namedBindings.elements.map((element) => element.name.getText(sourceFile)); + return importObj; +} + +function handlePropertyParameterDeclaration( + sourceFile: SourceFile, + property: PropertyDeclaration | ParameterDeclaration +): ParsedProperty { + let type = 'any'; + if (property.type) type = property.type.getText(sourceFile); + return { name: property.name.getText(sourceFile), type, kind: primitiveTypes.has(type) ? 'primitive' : 'class' }; +} + +function extractReturnBody(sourceFile: SourceFile, method: MethodDeclaration): string | undefined { + if (!method.body) return undefined; + const returnStmt = method.body.statements.find((statements) => isReturnStatement(statements)); + if (!returnStmt) return undefined; + const expression = returnStmt.expression; + if (!expression) return undefined; + return expression.getText(sourceFile); +} + +function handleMethodDeclaration(sourceFile: SourceFile, method: MethodDeclaration): ParsedMethod { + let returnType = 'void'; + if (method.type) returnType = method.type.getText(sourceFile); + const parameters = method.parameters.map((parameters) => handlePropertyParameterDeclaration(sourceFile, parameters)); + const info: ParsedMethod = { name: method.name.getText(sourceFile), returnType, parameters }; + if (info.name === 'toString') info.body = extractReturnBody(sourceFile, method); + return info; +} + +function getExtendingName(expr: LeftHandSideExpression): string { + if (isIdentifier(expr)) return expr.text; + if (isQualifiedName(expr)) return expr.right.text; + return 'UNKNOWN'; +} + +function handleClassDeclaration( + sourceFile: SourceFile, + node: ClassDeclaration +): { properties: ParsedProperty[]; methods: ParsedMethod[]; extending: string } { + let extending: string = ''; + if (node.heritageClauses) { + for (const clause of node.heritageClauses) { + if (clause.token === SyntaxKind.ExtendsKeyword) { + const type = clause.types[0]; + if (type) extending = getExtendingName(type.expression); + } + } + } + + const properties: ParsedProperty[] = []; + const methods: ParsedMethod[] = []; + for (const member of node.members) { + if (isPropertyDeclaration(member)) properties.push(handlePropertyParameterDeclaration(sourceFile, member)); + if (isMethodDeclaration(member)) methods.push(handleMethodDeclaration(sourceFile, member)); + } + return { properties, methods, extending }; +} + +function getTypes(filePath: string): ParsedClass { + const imports: ParsedImport[] = []; + let className = 'UNKNOWN'; + let extending = 'UNKNOWN'; + const properties: ParsedProperty[] = []; + const methods: ParsedMethod[] = []; + + const fileContent = readFileSync(filePath, 'utf-8'); + const sourceFile = createSourceFile(filePath, fileContent, ScriptTarget.Latest, true); + function visit(node: Node) { + if (isClassDeclaration(node) && node.name) className = node.name.text; + if (isClassDeclaration(node)) { + const classData = handleClassDeclaration(sourceFile, node); + extending = classData.extending; + classData.properties.forEach((property) => properties.push(property)); + classData.methods.forEach((method) => methods.push(method)); + } + if (isImportDeclaration(node)) imports.push(handleImportDeclaration(sourceFile, node)); + forEachChild(node, visit); + } + + visit(sourceFile); + return { className, properties, methods, imports, extending }; +} + +function getFileName(filePath: string): string { + return filePath.split('/').pop() || 'UNKNOWN'; +} + +function getParentDirPath(filePath: string): string { + return filePath.replaceAll(getFileName(filePath), ''); +} + +function getParentDirName(filePath: string): string { + return getParentDirPath(filePath).slice(0, -1).split('/').reverse()[0]; +} + +const ignoredImportsFolders = ['Utils', 'Private']; +const allowedMethods = ['toString', 'toHex', 'toCode', 'toInGameCode']; + +function parseTypeName(name: string): string { + if (name.includes("'")) return `[${name}]`; + return `.${name}`; +} + +function getExportedNames(filePath: string): string[] { + const program = createProgram([filePath], {}); + const sourceFile = program.getSourceFile(filePath)!; + + const exportedNames: string[] = []; + + function visit(node: Node) { + const isExported = (getCombinedModifierFlags(node as Declaration) & ModifierFlags.Export) !== 0; + + if (isExported) { + if ( + isInterfaceDeclaration(node) || + isTypeAliasDeclaration(node) || + isClassDeclaration(node) || + isEnumDeclaration(node) || + isFunctionDeclaration(node) || + isVariableStatement(node) + ) { + if (isVariableStatement(node)) { + for (const decl of node.declarationList.declarations) { + if (isIdentifier(decl.name)) exportedNames.push(decl.name.text); + } + } else if (node.name && isIdentifier(node.name)) { + exportedNames.push(node.name.text); + } + } + } + + forEachChild(node, visit); + } + + visit(sourceFile); + + return exportedNames; +} + +function validTypeIsClass(type: string, ignoredTypes: string[]): boolean { + if (type.includes('{')) return false; + if (type.includes('[')) return false; + if (type.includes('|')) return false; + if (type.includes("'")) return false; + if (type.includes('"')) return false; + if (type.includes('<')) return false; + if (type.includes(',')) return false; + if (type.includes(';')) return false; + if (type.includes(' ')) return false; + if (ignoredTypes.includes(type)) return false; + return true; +} + +async function parseFile(filePath: string, ignoredTypes: string[]) { + console.log(`Generating Test for ${filePath}`); + const types = getTypes(filePath); + if (types === null) return; + const imports: string[] = [ + '/* eslint-disable @stylistic/max-len */', + `import ${types.className} from './${types.className}.js';` + ]; + const typedImports: string[] = []; + types.imports.forEach((fileImport) => { + fileImport.module = fileImport.module.replaceAll('.js', '.ts'); + if (ignoredImportsFolders.includes(getParentDirName(fileImport.module))) return; + fileImport.module = fileImport.module.replaceAll('.ts', '.js'); + if (types.extending !== '' && types.extending === fileImport.default) return; + if (fileImport.default) imports.push(`import ${fileImport.default} from '${fileImport.module}'`); + if (fileImport.named) typedImports.push(`import type {${fileImport.named.join(', ')}} from '${fileImport.module}'`); + }); + imports.push("import { expect, expectTypeOf, test } from 'vitest';"); + const testCode: string[] = [ + `test('${types.className}', () => {`, + `const data = new ${types.className}({ stats: 'meow' });`, + 'expect(data).toBeDefined();', + `expect(data).toBeInstanceOf(${types.className});`, + `expectTypeOf(data).toEqualTypeOf<${types.className}>();` + ]; + types.properties.forEach((type) => { + type.name = parseTypeName(type.name); + testCode.push(`expect(data${type.name}).toBeDefined();`); + if (type.type === 'number') testCode.push(`expect(data${type.name}).toBeGreaterThanOrEqual(0);`); + if (type.kind === 'class' && validTypeIsClass(type.type, ignoredTypes)) { + testCode.push(`expect(data${type.name}).toBeInstanceOf(${type.type});`); + } + testCode.push(`expectTypeOf(data${type.name}).toEqualTypeOf<${type.type}>();`); + }); + types.methods.forEach((method) => { + if (!allowedMethods.includes(method.name)) return; + testCode.push(`expect(data.${method.name}).toBeDefined();`); + testCode.push(`expectTypeOf(data.${method.name}).toEqualTypeOf<() => ${method.returnType}>();`); + testCode.push(`expect(data.${method.name}()).toBeDefined();`); + if (method.name === 'toString' && method.body) { + testCode.push(`expect(data.${method.name}()).toBe(${method.body.replaceAll('this.', 'data.')});`); + } + testCode.push(`expectTypeOf(data.${method.name}()).toEqualTypeOf<${method.returnType}>();`); + }); + testCode.push('});'); + + filePath = filePath.replaceAll('.ts', '.test.ts'); + const joinedString = [...imports, ...typedImports, '/* eslint-enable @stylistic/max-len */', '', ...testCode] + .join('\n') + .replaceAll('\n\n\n', '\n'); + const formatted = await format(joinedString, { ...prettierConfig, filepath: filePath }); + writeFileSync(filePath, formatted); + console.log(`Generated Test for ${filePath}\n`); +} + +async function getIgnoredTypes(): Promise { + const ignoredTypes: string[] = []; + const typesPaths = await scanDirectory('./src/Types/'); + for (const file of typesPaths) { + getExportedNames(file).forEach((type) => { + if (!ignoredTypes.includes(type)) ignoredTypes.push(type); + }); + } + + return ignoredTypes; +} + +(async () => { + const ignoredTypes = await getIgnoredTypes(); + const structuresPaths = await scanDirectory(process.argv[2] ?? './src/Structures/'); + for (const file of structuresPaths) { + await parseFile(file, ignoredTypes); + } +})(); diff --git a/.github/scripts/generateIndexFile.ts b/.github/scripts/generateIndexFile.ts new file mode 100644 index 000000000..4a0b3566a --- /dev/null +++ b/.github/scripts/generateIndexFile.ts @@ -0,0 +1,64 @@ +import { format } from 'prettier'; +import { readFileSync, writeFileSync } from 'fs'; +import { scanDirectory } from './Utils'; + +const prettierConfig = JSON.parse(readFileSync('.prettierrc').toString('utf-8')); + +(async () => { + const lines: string[] = [ + '/* v8 ignore next 10000 */', + '/* eslint-disable @stylistic/max-len */', + '', + '', + "import Client from './Client.js';", + "import Errors from './Errors.js';", + '' + ]; + + const typesPaths = await scanDirectory('./src/Types/', { replaceSrc: true }); + typesPaths.forEach((path) => { + const fixedPath = path.replaceAll('.ts', '.js'); + lines.push(`export * from '${fixedPath}';`); + }); + + lines.push(''); + + const utilsPaths = await scanDirectory('./src/Utils/', { replaceSrc: true }); + utilsPaths.forEach((path) => { + const fixedPath = path.replaceAll('.ts', '.js'); + lines.push(`export * from '${fixedPath}';`); + }); + + lines.push(''); + + const structuresPaths = await scanDirectory('./src/Structures/', { replaceSrc: true }); + const fixedStructuresPaths: string[] = []; + const importNames: string[] = []; + + structuresPaths.forEach((path) => { + const importName = path.split('.ts')[0].split('/')[path.split('.ts')[0].split('/').length - 1]; + importNames.push(importName); + const fixedPath = path.replaceAll('.ts', '.js'); + fixedStructuresPaths.push(`import ${importName} from '${fixedPath}';`); + }); + + fixedStructuresPaths.sort().forEach((path) => lines.push(path)); + + lines.push(''); + lines.push('export {'); + lines.push('Client,'); + lines.push('Errors,'); + importNames.sort().forEach((importName) => lines.push(`${importName},`)); + lines.push('};'); + + lines.push(''); + + lines.push('export default {'); + lines.push('Client,'); + lines.push('Errors,'); + importNames.sort().forEach((importName) => lines.push(`${importName},`)); + lines.push('};'); + + const formatted = await format(lines.join('\n'), { ...prettierConfig, filepath: './src/index.ts' }); + writeFileSync('./src/index.ts', formatted); +})(); diff --git a/.github/workflows/UpdateDocs.yml b/.github/workflows/UpdateDocs.yml new file mode 100644 index 000000000..e3939368d --- /dev/null +++ b/.github/workflows/UpdateDocs.yml @@ -0,0 +1,81 @@ +name: 'Update Docs' +on: + push: + paths: + - src/** + branches: + - master + workflow_dispatch: + +env: + NODE_VERSION: '20' + +jobs: + pnpm: + name: Install dependencies (pnpm) + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm install + + UpdateDocs: + name: Update Documentation + needs: [pnpm] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm install + + - name: Generate Documentation + run: pnpm docgen + + - name: Move new documentation to temp directory + run: mv documentation/ tmp/ + + - name: Switch to documentation branch + run: | + git fetch --all + git checkout documentation + + - name: Clear Old Documentation files + run: + rm -rf assets/ classes/ functions/ interfaces/ modules/ types/ variables/ 404.html hierarchy.html index.html + modules.html sitemap.xml .nojekyll + + - name: Move new Documentation files into place + run: | + mv tmp/.nojekyll ./ + mv tmp/* ./ + rm -r tmp/ + + - name: Commit and push changes + run: | + git config --global user.name "Docs Updater[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add . + git commit -m "Update Documentation" || echo "No changes to commit" + git push origin documentation diff --git a/.github/workflows/ci-cd-18x.yml b/.github/workflows/ci-cd-18x.yml deleted file mode 100644 index a64c042c1..000000000 --- a/.github/workflows/ci-cd-18x.yml +++ /dev/null @@ -1,84 +0,0 @@ -# This CI Workflow was deployed and configured by WarpWing and Nate. -name: CI/CD (18.x) - -on: - push: - paths: - - src/** - pull_request: - workflow_dispatch: - -env: - NODE_VERSION: '18.x' - -jobs: - es-lint: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: es-lint - run: npm run lint - - tests: - runs-on: ubuntu-latest - environment: env - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: Run Tests - run: npm run tests - env: - HYPIXEL_KEY: ${{ secrets.HYPIXEL_KEY }} - - build: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: Build - run: npm run build --if-present - - prettier: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: prettier - run: npm run prettier:check diff --git a/.github/workflows/ci-cd-20x.yml b/.github/workflows/ci-cd-20x.yml deleted file mode 100644 index 6ab821aea..000000000 --- a/.github/workflows/ci-cd-20x.yml +++ /dev/null @@ -1,84 +0,0 @@ -# This CI Workflow was deployed and configured by WarpWing and Nate. -name: CI/CD (20.x) - -on: - push: - paths: - - src/** - pull_request: - workflow_dispatch: - -env: - NODE_VERSION: '20.x' - -jobs: - es-lint: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: es-lint - run: npm run lint - - tests: - runs-on: ubuntu-latest - environment: env - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: Run Tests - env: - HYPIXEL_KEY: ${{ secrets.HYPIXEL_KEY }} - run: npm run tests - - build: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: Build - run: npm run build --if-present - - prettier: - runs-on: ubuntu-latest - steps: - - name: Git checkout - uses: actions/checkout@v3 - - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v3 - with: - node-version: ${{ env.NODE_VERSION }} - - - name: Install node dependencies - run: npm i - - - name: prettier - run: npm run prettier:check diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml new file mode 100644 index 000000000..cdddaaacf --- /dev/null +++ b/.github/workflows/ci-cd.yml @@ -0,0 +1,189 @@ +name: 'CI/CD' +on: + push: + paths: + - src/** + branches: + - master + workflow_dispatch: + pull_request: + +env: + NODE_VERSION: '20' + +jobs: + pnpm: + name: install dependencies (pnpm) + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + prettier: + name: check linting (prettier) + needs: [pnpm] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Check prettier + run: pnpm prettier:check + + eslint: + name: check linting (eslint) + needs: [pnpm] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Check eslint + run: pnpm eslint:check + + index: + name: check building (index) + needs: [pnpm] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Run index generation + run: pnpm scripts:generate:index + + - name: Check index + run: | + if ! git diff --exit-code --quiet -- src/index.ts; then + echo "Index file isn't up to date. Please run 'pnpm scripts:gneerate:index'" + exit 1 + fi + + api-index: + name: check building (API index) + needs: [pnpm] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Run API index generation + run: pnpm scripts:generate:index:api + + - name: Check API index + run: | + if ! git diff --exit-code --quiet -- src/API/index.ts; then + echo "Index file isn't up to date. Please run 'pnpm scripts:gneerate:index:api'" + exit 1 + fi + + build: + name: build + needs: [pnpm, eslint, index, api-index] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Check build + run: pnpm build + + tests: + name: tests + needs: [pnpm, eslint, index, api-index, build] + runs-on: ubuntu-latest + steps: + - name: Git checkout + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install node dependencies + run: pnpm i + + - name: Check tests + env: + HYPIXEL_KEY: ${{ secrets.HYPIXEL_KEY }} + run: pnpm test:coverage + + - name: Check Coverage + run: pnpm test:coverage:check diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index 74d83f3d2..000000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,43 +0,0 @@ -name: Update Docs - -on: - push: - paths: - - src/** - branches: - - master - workflow_dispatch: - -jobs: - UpdateDocs: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install dependencies - run: npm install - - - name: Generate docs - run: | - mkdir tmp - npm run docgen - mv ./master.json tmp/master.json - - - name: Switch to docs branch - run: | - git fetch --all - git checkout docs -- - - - name: Replace master.json in docs branch - run: | - rm master.json - mv tmp/master.json master.json - - - name: Commit and push changes - run: | - git config --global user.name "Docs Updater[bot]" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git commit -am "Update Docs" - git push origin docs diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml deleted file mode 100644 index 463a760e0..000000000 --- a/.github/workflows/prettier.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Write Prettier - -on: - workflow_dispatch: - -jobs: - WritePrettier: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Install dependencies - run: npm install - - - name: Run Prettier - run: npm run prettier - - - name: Commit and push changes - run: | - git config --global user.name "Prettier Updater[bot]" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git commit -am "style(prettier): run prettier on all files (auto-commit)" - git push origin master diff --git a/.gitignore b/.gitignore index d183da86b..8b4dbe91a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,49 +1,6 @@ -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json -pids -*.pid -*.seed -*.pid.lock -lib-cov -coverage -*.lcov -.nyc_output -.grunt -bower_components -.lock-wscript -build/Release node_modules/ -jspm_packages/ -*.tsbuildinfo -.npm -.eslintcache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ -.node_repl_history -*.tgz -.yarn-integrity -.env.test -.cache -.next -.nuxt -dist -.cache/ -.vuepress/dist -.serverless/ -.fusebox/ -.dynamodb/ -yarn.lock -.tern-port -testing/ -.circleci/ -changelog.md -master.json +coverage/ +.github/coverageData.xml +documentation/ +dist/ .env -.vscode/settings.json diff --git a/.npmignore b/.npmignore index 4f71b9358..0f7e40163 100644 --- a/.npmignore +++ b/.npmignore @@ -1,27 +1,9 @@ node_modules/ -.*.swp -._* -.DS_Store -.git -.hg -.npmrc -.lock-wscript -.svn -.wafpickle-* -config.gypi -CVS -npm-debug.log -.eslintignore -.eslintrc. -testing/ -.github -.travis.yml +coverage/ +.github/ +documentation/ +.git/ .vscode/ -.circleci/ -docs/ -tests/ -typings/*.json -master.json +.gitignore .env -dtslint.json -.eslintcache \ No newline at end of file +src diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..f2487af9c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +node_modules/ +coverage/ +documentation/ +dist/ +.env +.env +.env.example +pnpm-lock.yaml diff --git a/.prettierrc b/.prettierrc index 155ef4c65..5e20592d6 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { + "objectWrap": "collapse", "bracketSameLine": true, "trailingComma": "none", "arrowParens": "always", diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..6e11a125a --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,11 @@ +{ + "recommendations": [ + "editorconfig.editorconfig", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "eamodio.gitlens", + "aaron-bond.better-comments", + "vitest.explorer", + "github.vscode-pull-request-github" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index f897489f4..000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Launch Program", - "skipFiles": ["/**"], - "program": "${workspaceFolder}\\testing\\globaltest.js" - } - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..1c367cfa4 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,12 @@ +{ + "editor.tabSize": 2, + "prettier.useTabs": false, + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "editor.trimAutoWhitespace": true, + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, + "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, + "typescript.format.semicolons": "insert", + "typescript.preferences.quoteStyle": "single" +} diff --git a/README.md b/README.md index 976e86e08..6d8b17238 100644 --- a/README.md +++ b/README.md @@ -1,67 +1,28 @@
- -

Hypixel API • Reborn

- - - - - - - - -

A feature-rich Hypixel API wrapper for Node.js

-
+ +

Hypixel API • Reborn

+ + + + +

A feature-rich Hypixel API wrapper for Node.js

### Links -[Discord Support](https://discord.gg/NSEBNMM) | [Documentation](https://hypixel-api-reborn.github.io/) | -[NPM](https://www.npmjs.com/package/hypixel-api-reborn) | -[GitHub](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn) | -[ToDo](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/projects/1) | -[CLI](https://github.com/Hypixel-API-Reborn/cli) +[Discord Support](https://discord.gg/NSEBNMM) | [Documentation](https://hypixel-api-reborn.github.io/hypixel-api-reborn) +| [NPM](https://www.npmjs.com/package/hypixel-api-reborn) | +[GitHub](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn) -#### Requirements +### Requirements -**For Node.js users >= v18.18.0**
**For TypeScript users >= v3.5** +**For Node.js users >= v20.16.0**
**For TypeScript users >= v5.5.4** ### Installation & Usage ```shell -npm i hypixel-api-reborn +npm i hypixel-api-reborn@next ``` -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -// getPlayer -hypixel - .getPlayer('StavZDev') - .then((player) => { - console.log(player.level); // 141 - }) - .catch((e) => { - console.error(e); - }); - -// getGuild -hypixel - .getGuild('name', 'The Foundation') - .then((guild) => { - console.log(guild.level); // 111 - }) - .catch((e) => { - console.error(e); - }); -``` - -For more examples go to our [documentation](https://hypixel-api-reborn.github.io/). - -## Changelog - -[v11.0.0](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/releases/tag/11.0.0) - -### Try it now - -**[Code Sandbox](https://codesandbox.io/s/clever-babbage-xqmfw?file=/src/index.js)** +**Do note that you are installing a beta version of v12.0.0.** Any issues or bugs you encounter, please report them in +the [Discord Support](https://discord.gg/NSEBNMM). diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..b94707787 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/docs/JavaScript/Readme.md b/docs/JavaScript/Readme.md new file mode 100644 index 000000000..df9a3eff2 --- /dev/null +++ b/docs/JavaScript/Readme.md @@ -0,0 +1,9 @@ +# JavaScript Hypixel-API-Reborn Guides + +These guides assumes that you will be using JavaScript. Please checkout +[the TypeScript version](../TypeScript/SkyHelperNetWorth.md) of this guide if you need TypeScript + +## Guides + +- [Setting up Hypixel-API-Reborn's Client](SettingUpClient/Readme.md) +- [Fetching SkyHelper Networth using Hypixel-API-Reborn](SkyHelperNetworth/Readme.md) diff --git a/docs/JavaScript/SettingUpClient/Code/.gitignore b/docs/JavaScript/SettingUpClient/Code/.gitignore new file mode 100644 index 000000000..b94707787 --- /dev/null +++ b/docs/JavaScript/SettingUpClient/Code/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/docs/JavaScript/SettingUpClient/Code/package.json b/docs/JavaScript/SettingUpClient/Code/package.json new file mode 100644 index 000000000..d9d1a73c5 --- /dev/null +++ b/docs/JavaScript/SettingUpClient/Code/package.json @@ -0,0 +1,7 @@ +{ + "name": "@hypixel-api-reborn-docs/javascript-setting-up-client", + "type": "module", + "dependencies": { + "hypixel-api-reborn": "catalog:" + } +} diff --git a/docs/JavaScript/SettingUpClient/Code/src/HypixelAPIReborn.js b/docs/JavaScript/SettingUpClient/Code/src/HypixelAPIReborn.js new file mode 100644 index 000000000..b62a133b6 --- /dev/null +++ b/docs/JavaScript/SettingUpClient/Code/src/HypixelAPIReborn.js @@ -0,0 +1,5 @@ +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client('YOUR API_KEY'); + +export default HypixelAPIReborn; diff --git a/docs/JavaScript/SettingUpClient/Code/src/PlayerExample.js b/docs/JavaScript/SettingUpClient/Code/src/PlayerExample.js new file mode 100644 index 000000000..f73a78516 --- /dev/null +++ b/docs/JavaScript/SettingUpClient/Code/src/PlayerExample.js @@ -0,0 +1,10 @@ +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +async function Run() { + const player = await HypixelAPIReborn.getPlayer('kathund'); + + console.log(player); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/JavaScript/SettingUpClient/Readme.md b/docs/JavaScript/SettingUpClient/Readme.md new file mode 100644 index 000000000..43f626ee8 --- /dev/null +++ b/docs/JavaScript/SettingUpClient/Readme.md @@ -0,0 +1,73 @@ +# Setting up Hypixel-API-Reborn's Client (JavaScript) + +This guide will explain how to setup a reuseable Client instance from Hypixel-API-Reborn. + +This assumes that you will be using JavaScript. Please checkout +[the TypeScript version](../TypeScript/SettingUpClient.md) of this guide if you need TypeScript + +## Requirements + +- Hypixel-API-Reborn v12.0.0-15 or **higher** + +## Assumptions + +This guide assumes the following + +- You are using Hypixel-API-Reborn v12.0.0-15 +- You are using ES6 Modules + +## Initializing a Client Instance + +By importing the Client constructor from Hypixel-API-Reborn you can start a new instance of it by calling new on the +class and passing in your API Key + +```JavaScript +// File HypixelAPIReborn.js +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client("YOUR API_KEY"); +``` + +## Sharing your Client Instance + +We recommend not creating multiple instances of Client because of how we manage ratelimiting and having it cause desync +issues. Instead we recommend making one instance of Client then exporting it and importing it an any files that need the +Client instance. + +```JavaScript +// File HypixelAPIReborn.js + +import { Client } from 'hypixel-api-reborn.js'; + +const HypixelAPIReborn = new Client("YOUR API_KEY"); + +export default HypixelAPIReborn; +``` + +Once it's exported you can then reimport it into a different file and make requests from it + +```JavaScript +// File PlayerExample.js +import HypixelAPIReborn from './HypixelAPIReborn.js'; +``` + +## Fetching a Player + +Once you have initialized your client instance you can then call a function on it. In this example we are going to call +[getPlayer](https://hypixel-api-reborn.github.io/hypixel-api-reborn/classes/Client.Client.html#getplayer) but there are +many more endpoints you can fetch. A +[full list can be found on the docs under the Methods section](https://hypixel-api-reborn.github.io/hypixel-api-reborn/classes/Client.Client.html) + +```JavaScript +// File PlayerExample.js +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +const player = await hypixelAPI.getPlayer("kathund"); + +console.log(player); +``` + +## Code + +The resulting code can be found at +[Code/src/](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/blob/master/docs/JavaScript/SettingUpClient/Code/src/) diff --git a/docs/JavaScript/SkyHelperNetworth/Code/.gitignore b/docs/JavaScript/SkyHelperNetworth/Code/.gitignore new file mode 100644 index 000000000..b94707787 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/docs/JavaScript/SkyHelperNetworth/Code/package.json b/docs/JavaScript/SkyHelperNetworth/Code/package.json new file mode 100644 index 000000000..697ab7624 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/package.json @@ -0,0 +1,7 @@ +{ + "name": "@hypixel-api-reborn-docs/javascript-sky-helper-networth", + "type": "module", + "dependencies": { + "hypixel-api-reborn": "catalog:" + } +} diff --git a/docs/JavaScript/SkyHelperNetworth/Code/src/CalculatorExample.js b/docs/JavaScript/SkyHelperNetworth/Code/src/CalculatorExample.js new file mode 100644 index 000000000..d8cbbc192 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/src/CalculatorExample.js @@ -0,0 +1,28 @@ +import HypixelAPIReborn from './HypixelAPIReborn.js'; +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + // Reparse the profile data so that SkyHelper can read it and use it + const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + + // Create the Networth calculator + const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); + console.log(networthCalculator); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/JavaScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.js b/docs/JavaScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.js new file mode 100644 index 000000000..b62a133b6 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.js @@ -0,0 +1,5 @@ +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client('YOUR API_KEY'); + +export default HypixelAPIReborn; diff --git a/docs/JavaScript/SkyHelperNetworth/Code/src/MuseumExample.js b/docs/JavaScript/SkyHelperNetworth/Code/src/MuseumExample.js new file mode 100644 index 000000000..6a9c65368 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/src/MuseumExample.js @@ -0,0 +1,21 @@ +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + console.log(museumProfile); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/JavaScript/SkyHelperNetworth/Code/src/NetworthExample.js b/docs/JavaScript/SkyHelperNetworth/Code/src/NetworthExample.js new file mode 100644 index 000000000..160823094 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/src/NetworthExample.js @@ -0,0 +1,31 @@ +import HypixelAPIReborn from './HypixelAPIReborn.js'; +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + // Reparse the profile data so that SkyHelper can read it and use it + const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + + // Create the Networth calculator + const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); + + // Fetch the Networth + const networthData = await networthCalculator.getNetworth({ onlyNetworth: true }); + console.log(networthData); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/JavaScript/SkyHelperNetworth/Code/src/ProfileExample.js b/docs/JavaScript/SkyHelperNetworth/Code/src/ProfileExample.js new file mode 100644 index 000000000..0a0bb2020 --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Code/src/ProfileExample.js @@ -0,0 +1,12 @@ +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + +const selectedProfile = profiles.selectedProfile; +// Check that the player has a selectedProfile. +if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + +console.log(selectedProfile); + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/JavaScript/SkyHelperNetworth/Readme.md b/docs/JavaScript/SkyHelperNetworth/Readme.md new file mode 100644 index 000000000..20e144a3f --- /dev/null +++ b/docs/JavaScript/SkyHelperNetworth/Readme.md @@ -0,0 +1,95 @@ +# Fetching SkyHelper Networth using Hypixel-API-Reborn (JavaScript) + +This will explain how to convert a Hypixel-API-Reborn API request into useable data that can be parsed into SkyHelper +Networth. This assumes that you will be using JavaScript. Please checkout +[the TypeScript version](../TypeScript/SkyHelperNetWorth.md) of this guide if you need TypeScript + +## Requirements + +- Hypixel-API-Reborn v12.0.0-15 or **higher** +- SkyHelper Networth v2.5.1 or **higher** + +## Assumptions + +This guide assumes the following + +- You are using Hypixel-API-Reborn v12.0.0-15 +- You are using SkyHelper Networth v2.5.1 +- You have setup a Client instance. If not please see [the Setting Up Client guide](../SettingUpClient/Guide.md) + +## Fetching A Player's Profiles + +Once you have initialized your client instance you can then fetch a user's SkyBlock Profiles and get there currently +selected profile. + +```JavaScript +// File ProfileExample.js +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + +// Check that the profiles data is not Raw API Data. +if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + +const selectedProfile = profiles.selectedProfile; +// Check that the player has a selectedProfile. +if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + +console.log(selectedProfile); +``` + +## Fetching A Player's Museum + +Once you have found the user's selected profile you will be required to get that player's museum data + +```JavaScript +// File MuseumExample.js +import HypixelAPIReborn from './HypixelAPIReborn.js'; + +const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + +// Check that the requested data is raw. +if (!museum.isRaw()) throw new Error('Museum data is not Raw Data.'); + +// Check that the player has API on. +const museumProfile = museum.data.members[selectedProfile.me.uuid]; +if (museumProfile === undefined) throw new Error('Player has museum API off.'); + +console.log(museumProfile); +``` + +## Creating a NetworthCalculator + +Once you have found the user's selected profile and there museum data we need to parse the SkyblockProfile into useable +data for the Networth Calculator + +```JavaScript +// File CalculatorExample.js +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +// Reparse the profile data so that SkyHelper can read it and use it +const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + +// Create the Networth calculator +const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); +``` + +## Calculating a Player's Networth + +Once we have the Networth Calculator we can calculate the player's networth + +```JavaScript +// File NetworthExample.js +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +// Fetch the Networth +const networthData = await networthCalculator.getNetworth({ onlyNetworth: true }); +console.log(networthData); +``` + +## Code + +The resulting code can be found at +[Code/src/](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/blob/master/docs/JavaScript/SkyHelperNetworth/Code/src/) diff --git a/docs/Readme.md b/docs/Readme.md new file mode 100644 index 000000000..94cf47182 --- /dev/null +++ b/docs/Readme.md @@ -0,0 +1,11 @@ +# Hypixel-API-Reborn Guides + +## Guides + +- [JavaScript](JavaScript/Readme.md) + - [Setting up Hypixel-API-Reborn's Client](JavaScript/SettingUpClient/Readme.md) + - [Fetching SkyHelper Networth using Hypixel-API-Reborn](JavaScript/SkyHelperNetworth/Readme.md) +- [TypeScript](TypeScript/Readme.md) + - [Setting up Hypixel-API-Reborn's Client](TypeScript/SettingUpClient/Readme.md) + - [Fetching SkyHelper Networth using Hypixel-API-Reborn](TypeScript/SkyHelperNetworth/Readme.md) + - [Understanding Is Raw](TypeScript/UnderstandingIsRaw/Readme.md) diff --git a/docs/TypeScript/Readme.md b/docs/TypeScript/Readme.md new file mode 100644 index 000000000..7d52cd5fd --- /dev/null +++ b/docs/TypeScript/Readme.md @@ -0,0 +1,10 @@ +# TypeScript Hypixel-API-Reborn Guides + +These guides assumes that you will be using TypeScript. Please checkout +[the JavaScript version](../JavaScript/SkyHelperNetWorth.md) of this guide if you need JavaScript + +## Guides + +- [Setting up Hypixel-API-Reborn's Client](SettingUpClient/Readme.md) +- [Fetching SkyHelper Networth using Hypixel-API-Reborn](SkyHelperNetworth/Readme.md) +- [Understanding Is Raw](UnderstandingIsRaw/Readme.md) diff --git a/docs/TypeScript/SettingUpClient/Code/.gitignore b/docs/TypeScript/SettingUpClient/Code/.gitignore new file mode 100644 index 000000000..b94707787 --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Code/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/docs/TypeScript/SettingUpClient/Code/package.json b/docs/TypeScript/SettingUpClient/Code/package.json new file mode 100644 index 000000000..ea7f9a553 --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Code/package.json @@ -0,0 +1,14 @@ +{ + "name": "@hypixel-api-reborn-docs/typescript-setting-up-client", + "type": "module", + "scripts": { + "build": "pnpm exec tsc --build" + }, + "dependencies": { + "hypixel-api-reborn": "catalog:" + }, + "devDependencies": { + "tsx": "catalog:", + "typescript": "catalog:" + } +} diff --git a/docs/TypeScript/SettingUpClient/Code/src/HypixelAPIReborn.ts b/docs/TypeScript/SettingUpClient/Code/src/HypixelAPIReborn.ts new file mode 100644 index 000000000..b62a133b6 --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Code/src/HypixelAPIReborn.ts @@ -0,0 +1,5 @@ +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client('YOUR API_KEY'); + +export default HypixelAPIReborn; diff --git a/docs/TypeScript/SettingUpClient/Code/src/PlayerExample.ts b/docs/TypeScript/SettingUpClient/Code/src/PlayerExample.ts new file mode 100644 index 000000000..6fe7e1356 --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Code/src/PlayerExample.ts @@ -0,0 +1,13 @@ +import HypixelAPIReborn from './HypixelAPIReborn'; + +async function Run() { + const player = await HypixelAPIReborn.getPlayer('kathund'); + + // Check that the player data is not Raw API Data.. + if (player.isRaw()) throw new Error('Player data is Raw Data.'); + + console.log(player); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/TypeScript/SettingUpClient/Code/tsconfig.json b/docs/TypeScript/SettingUpClient/Code/tsconfig.json new file mode 100644 index 000000000..517fe6f64 --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Code/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "skipLibCheck": true, + "outDir": "./dist", + "module": "ES2022", + "target": "ES2022", + "strict": true + } +} diff --git a/docs/TypeScript/SettingUpClient/Readme.md b/docs/TypeScript/SettingUpClient/Readme.md new file mode 100644 index 000000000..af76b4a3a --- /dev/null +++ b/docs/TypeScript/SettingUpClient/Readme.md @@ -0,0 +1,80 @@ +# Setting up Hypixel-API-Reborn's Client (JavaScript) + +This guide will explain how to setup a reuseable Client instance from Hypixel-API-Reborn. + +This assumes that you will be using TypeScript. Please checkout +[the JavaScript version](../JavaScript/SettingUpClient.md) of this guide if you need JavaScript + +## Requirements + +- Hypixel-API-Reborn v12.0.0-15 or **higher** +- TypeScript v5.9.2 or **higher** + +## Assumptions + +This guide assumes the following + +- You are using Hypixel-API-Reborn v12.0.0-15 +- You are using TypeScript v5.9.2 + +## Initializing a Client Instance + +By importing the Client constructor from Hypixel-API-Reborn you can start a new instance of it by calling new on the +class and passing in your API Key + +```TypeScript +// File HypixelAPIReborn.ts +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client("YOUR API_KEY"); +``` + +## Sharing your Client Instance + +We recommend not creating multiple instances of Client because of how we manage ratelimiting and having it cause desync +issues. Instead we recommend making one instance of Client then exporting it and importing it an any files that need the +Client instance. + +```TypeScript +// File HypixelAPIReborn.ts + +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client("YOUR API_KEY"); + +export default HypixelAPIReborn; +``` + +Once it's exported you can then reimport it into a different file and make requests from it + +```TypeScript +// File PlayerExample.ts +import HypixelAPIReborn from './HypixelAPIReborn'; +``` + +## Fetching a Player + +Once you have initialized your client instance you can then call a function on it. In this example we are going to call +[getPlayer](https://hypixel-api-reborn.github.io/hypixel-api-reborn/classes/Client.Client.html#getplayer) but there are +many more endpoints you can fetch. A +[full list can be found on the docs under the Methods section](https://hypixel-api-reborn.github.io/hypixel-api-reborn/classes/Client.Client.html) + +```TypeScript +// File PlayerExample.ts +import HypixelAPIReborn from './HypixelAPIReborn'; + +const player = await hypixelAPI.getPlayer("kathund"); + +// Check that the player data is not Raw API Data. +if (player.isRaw()) throw new Error("Player data is Raw Data"); + +console.log(player); +``` + +When fetching endpoints we use isRaw to check if the data is a raw request data or not. Consider checking out the +[guide on Understanding isRaw](../UnderstandingIsRaw/Guide.md) for more info + +## Code + +The resulting code can be found at +[Code/src/](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/blob/master/docs/TypeScript/SettingUpClient/Code/src/) diff --git a/docs/TypeScript/SkyHelperNetworth/Code/.gitignore b/docs/TypeScript/SkyHelperNetworth/Code/.gitignore new file mode 100644 index 000000000..b94707787 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/.gitignore @@ -0,0 +1,2 @@ +node_modules/ +dist/ diff --git a/docs/TypeScript/SkyHelperNetworth/Code/package.json b/docs/TypeScript/SkyHelperNetworth/Code/package.json new file mode 100644 index 000000000..f18521e76 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/package.json @@ -0,0 +1,14 @@ +{ + "name": "@hypixel-api-reborn-docs/typescript-sky-helper-networth", + "type": "module", + "scripts": { + "build": "pnpm exec tsc --build" + }, + "dependencies": { + "hypixel-api-reborn": "catalog:" + }, + "devDependencies": { + "tsx": "catalog:", + "typescript": "catalog:" + } +} diff --git a/docs/TypeScript/SkyHelperNetworth/Code/src/CalculatorExample.ts b/docs/TypeScript/SkyHelperNetworth/Code/src/CalculatorExample.ts new file mode 100644 index 000000000..cd4d772ed --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/src/CalculatorExample.ts @@ -0,0 +1,34 @@ +import HypixelAPIReborn from './HypixelAPIReborn'; +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + // Check that the profiles data is not Raw API Data. + if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the requested data is raw. + if (!museum.isRaw()) throw new Error('Museum data is not Raw Data.'); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + // Reparse the profile data so that SkyHelper can read it and use it + const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + + // Create the Networth calculator + const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); + console.log(networthCalculator); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/TypeScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.ts b/docs/TypeScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.ts new file mode 100644 index 000000000..b62a133b6 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/src/HypixelAPIReborn.ts @@ -0,0 +1,5 @@ +import { Client } from 'hypixel-api-reborn'; + +const HypixelAPIReborn = new Client('YOUR API_KEY'); + +export default HypixelAPIReborn; diff --git a/docs/TypeScript/SkyHelperNetworth/Code/src/MuseumExample.ts b/docs/TypeScript/SkyHelperNetworth/Code/src/MuseumExample.ts new file mode 100644 index 000000000..535742392 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/src/MuseumExample.ts @@ -0,0 +1,27 @@ +import HypixelAPIReborn from './HypixelAPIReborn'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + // Check that the profiles data is not Raw API Data. + if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the requested data is raw. + if (!museum.isRaw()) throw new Error('Museum data is not Raw Data.'); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + console.log(museumProfile); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/TypeScript/SkyHelperNetworth/Code/src/NetworthExample.ts b/docs/TypeScript/SkyHelperNetworth/Code/src/NetworthExample.ts new file mode 100644 index 000000000..15eaf6a60 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/src/NetworthExample.ts @@ -0,0 +1,37 @@ +import HypixelAPIReborn from './HypixelAPIReborn'; +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +async function Run() { + const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + + // Check that the profiles data is not Raw API Data. + if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + + const selectedProfile = profiles.selectedProfile; + // Check that the player has a selectedProfile. + if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + + // Fetch the player's museum data + const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + + // Check that the requested data is raw. + if (!museum.isRaw()) throw new Error('Museum data is not Raw Data.'); + + // Check that the player has API on. + const museumProfile = museum.data.members[selectedProfile.me.uuid]; + if (museumProfile === undefined) throw new Error('Player has museum API off.'); + + // Reparse the profile data so that SkyHelper can read it and use it + const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + + // Create the Networth calculator + const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); + + // Fetch the Networth + const networthData = await networthCalculator.getNetworth({ onlyNetworth: true }); + console.log(networthData); +} + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/TypeScript/SkyHelperNetworth/Code/src/ProfileExample.ts b/docs/TypeScript/SkyHelperNetworth/Code/src/ProfileExample.ts new file mode 100644 index 000000000..b2227c448 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/src/ProfileExample.ts @@ -0,0 +1,15 @@ +import HypixelAPIReborn from './HypixelAPIReborn'; + +const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + +// Check that the profiles data is not Raw API Data. +if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + +const selectedProfile = profiles.selectedProfile; +// Check that the player has a selectedProfile. +if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + +console.log(selectedProfile); + +// Required because you can't just run async stuff. +Run(); diff --git a/docs/TypeScript/SkyHelperNetworth/Code/tsconfig.json b/docs/TypeScript/SkyHelperNetworth/Code/tsconfig.json new file mode 100644 index 000000000..517fe6f64 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Code/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "skipLibCheck": true, + "outDir": "./dist", + "module": "ES2022", + "target": "ES2022", + "strict": true + } +} diff --git a/docs/TypeScript/SkyHelperNetworth/Readme.md b/docs/TypeScript/SkyHelperNetworth/Readme.md new file mode 100644 index 000000000..509d660f5 --- /dev/null +++ b/docs/TypeScript/SkyHelperNetworth/Readme.md @@ -0,0 +1,97 @@ +# Fetching SkyHelper Networth using Hypixel-API-Reborn (TypeScript) + +This will explain how to convert a Hypixel-API-Reborn API request into useable data that can be parsed into SkyHelper +Networth. This assumes that you will be using TypeScript. Please checkout +[the JavaScript version](../JavaScript/SkyHelperNetWorth.md) of this guide if you need JavaScript + +## Requirements + +- Hypixel-API-Reborn v12.0.0-15 or **higher** +- SkyHelper Networth v2.5.1 or **higher** +- TypeScript v5.9.2 or **higher** + +## Assumptions + +This guide assumes the following + +- You are using Hypixel-API-Reborn v12.0.0-15 +- You are using SkyHelper Networth v2.5.1 +- You are using TypeScript v5.9.2 +- You have setup a Client instance. If not please see [the Setting Up Client guide](../SettingUpClient/Guide.md) + +## Fetching A Player's Profiles + +Once you have initialized your client instance you can then fetch a user's SkyBlock Profiles and get there currently +selected profile. + +```TypeScript +// File ProfileExample.ts +import HypixelAPIReborn from './HypixelAPIReborn'; + +const profiles = await HypixelAPIReborn.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + +// Check that the profiles data is not Raw API Data. +if (profiles.isRaw()) throw new Error('Player data is Raw Data.'); + +const selectedProfile = profiles.selectedProfile; +// Check that the player has a selectedProfile. +if (selectedProfile === undefined) throw new Error("Player doesn't have a skyblock profile selected."); + +console.log(selectedProfile); +``` + +## Fetching A Player's Museum + +Once you have found the user's selected profile you will be required to get that player's museum data + +```TypeScript +// File MuseumExample.ts +import HypixelAPIReborn from './HypixelAPIReborn'; + +const museum = await HypixelAPIReborn.getSkyBlockMuseum(selectedProfile.profileId, { raw: true }); + +// Check that the requested data is raw. +if (!museum.isRaw()) throw new Error('Museum data is not Raw Data.'); + +// Check that the player has API on. +const museumProfile = museum.data.members[selectedProfile.me.uuid]; +if (museumProfile === undefined) throw new Error('Player has museum API off.'); + +console.log(museumProfile); +``` + +## Creating a NetworthCalculator + +Once you have found the user's selected profile and there museum data we need to parse the SkyblockProfile into useable +data for the Networth Calculator + +```TypeScript +// File CalculatorExample.ts +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +// Reparse the profile data so that SkyHelper can read it and use it +const profileData = PrepareSkyBlockProfileForSkyHelperNetworth(selectedProfile); + +// Create the Networth calculator +const networthCalculator = new ProfileNetworthCalculator(profileData, museumProfile, selectedProfile.banking.balance); +``` + +## Calculating a Player's Networth + +Once we have the Networth Calculator we can calculate the player's networth + +```TypeScript +// File NetworthExample.ts +import { PrepareSkyBlockProfileForSkyHelperNetworth } from 'hypixel-api-reborn'; +import { ProfileNetworthCalculator } from 'skyhelper-networth'; + +// Fetch the Networth +const networthData = await networthCalculator.getNetworth({ onlyNetworth: true }); +console.log(networthData); +``` + +## Code + +The resulting code can be found at +[Code/src/](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/blob/master/docs/TypeScript/SkyHelperNetworth/Code/src/) diff --git a/docs/TypeScript/UnderstandingIsRaw/Readme.md b/docs/TypeScript/UnderstandingIsRaw/Readme.md new file mode 100644 index 000000000..a28426922 --- /dev/null +++ b/docs/TypeScript/UnderstandingIsRaw/Readme.md @@ -0,0 +1,29 @@ +# Understanding Is Raw + +This guide will explain how isRaw works and why it's needed in TypeScript. + +This assumes that you will be using TypeScript. There will not be a JavaScript version of this guide. + +## Requirements + +- Hypixel-API-Reborn v12.0.0-15 or **higher** +- TypeScript v5.9.2 or **higher** + +## Assumptions + +This guide assumes the following + +- You are using Hypixel-API-Reborn v12.0.0-15 +- You are using TypeScript v5.9.2 + +## Why + +When fetching an endpoint it returns the following + +```TypeScript +client.getPlayer(): Promise +``` + +In this case when fetching getPlayer it returns the RequestData Or the Player data. Using `isRaw()` as a type guard we +can confirm that it's the Player data because we did not include the raw option in our request. This isRaw will be on +every endpoint because every endpoint supports fetching raw data thus returning RequestData diff --git a/docs/general/errorHandling.md b/docs/general/errorHandling.md deleted file mode 100644 index 53069e6d8..000000000 --- a/docs/general/errorHandling.md +++ /dev/null @@ -1,17 +0,0 @@ -# Error Handling - -Example of error handling in `getPlayer` method. - -```js -const { Errors } = require('hypixel-api-reborn'); -// invalid nickname -hypixel - .getPlayer('3424242') - .then((player) => {}) - .catch((e) => { - if (e.message === Errors.PLAYER_DOES_NOT_EXIST) { - console.log(`Player doesn't exist!`); - // here you can replace default error message with yours. - } - }); -``` diff --git a/docs/general/welcome.md b/docs/general/welcome.md deleted file mode 100644 index 202692fe6..000000000 --- a/docs/general/welcome.md +++ /dev/null @@ -1,63 +0,0 @@ -
- - - - - - - - - - - -
- -

Welcome to the hypixel-api-reborn documentation

-
- -# About - -Hypixel API • Reborn is a feature-rich Hypixel API wrapper for Node.js/Typescript.
- -- 100% Promise-based.
-- Speedy and efficient.
-- Intellisense support. [(?)](https://code.visualstudio.com/docs/editor/intellisense) - -# Installation - -``` -// npm -npm i hypixel-api-reborn - -// yarn -yarn add hypixel-api-reborn -``` - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getPlayer('StavZDev') - .then((player) => { - console.log(player.level); // 141 - }) - .catch((e) => { - console.error(e); - }); -``` - -## Links - -- [Hypixel API • Reborn Discord Server](https://discord.gg/NSEBNMM) -- [GitHub](https://github.com/Hypixel-API-Reborn) -- [NPM](https://www.npmjs.com/package/hypixel-api-reborn) - -# Contributing - -[Contributing.md](https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/blob/master/.github/CONTRIBUTING.md) - -Make sure before creating an issue that it hasn't already reported. Please, don't create an issue for feature request, -you can do it on our [discord server](https://discord.gg/NSEBNMM). diff --git a/docs/index.yml b/docs/index.yml deleted file mode 100644 index 603b766fd..000000000 --- a/docs/index.yml +++ /dev/null @@ -1,38 +0,0 @@ -- name: General - files: - - name: Welcome - path: welcome.md - - name: Error Handling - path: errorHandling.md -- name: Methods - files: - - name: getPlayer - path: getPlayer.md - - name: getGuild - path: getGuild.md - - name: getStatus - path: getStatus.md - - name: getRecentGames - path: getRecentGames.md - - name: getWatchdogStats - path: getWatchdogStats.md - - name: getLeaderboards - path: getLeaderboards.md - - name: getAPIStatus - path: getAPIStatus.md - - name: getBoosters - path: getBoosters.md - - name: getServerInfo - path: getServerInfo.md - - name: getSkyblockProfiles - path: getSkyblockProfiles.md - - name: getSkyblockMember - path: getSkyblockMember.md - - name: getSkyblockBazaar - path: getSkyblockBazaar.md - - name: getSkyblockAuctions - path: getSkyblockAuctions.md - - name: getSkyblockAuctionsByPlayer - path: getSkyblockAuctionsByPlayer.md - - name: getEndedSkyblockAuctions - path: getEndedSkyblockAuctions.md diff --git a/docs/methods/getAPIStatus.md b/docs/methods/getAPIStatus.md deleted file mode 100644 index 831a40618..000000000 --- a/docs/methods/getAPIStatus.md +++ /dev/null @@ -1,65 +0,0 @@ -# getAPIStatus - -Allows you to get the Hypixel API's Status and past Incidents, no key needed. - -## Arguments - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getAPIStatus() - .then((apistatus) => { - console.log(apistatus); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const apistatus = await hypixel.getAPIStatus().catch((e) => console.error(e)); -console.log(apistatus); -``` - -## Example response - -```js -APIStatus { - sourceUrl: null, - title: 'Hypixel Status - Incident History', - description: 'Statuspage', - incidents: [ - APIIncident { - link: 'https://status.hypixel.net/incidents/v1kgjvxxbcrk', - start: 2021-01-15T20:06:01.000Z, - startFormatted: 'Fri, 15 Jan 2021 15:06:01 -0500', - startTimestamp: 1610741161000, - author: null, - HTMLContent: '\n' + - "

Jan 15, 15:06 EST
Completed - The scheduled maintenance has been completed.

Jan 15, 07:55 EST
Update - Maintenance is currently still in progress, maintenance will last a few hours longer than originally intended.

Jan 14, 09:30 EST
In progress - Scheduled maintenance is currently in progress. We will provide updates as necessary.

Jan 14, 09:10 EST
Scheduled - SkyBlock will be undergoing maintenance for a game update. There is not currently an exact ETA for when the maintenance will end.

", - snippet: 'Jan 15, 15:06 EST\n' + - 'Completed - The scheduled maintenance has been completed.\n' + - 'Jan 15, 07:55 EST\n' + - 'Update - Maintenance is currently still in progress, maintenance will last a few hours longer than originally intended.\n' + - 'Jan 14, 09:30 EST\n' + - 'In progress - Scheduled maintenance is currently in progress. We will provide updates as necessary.\n' + - 'Jan 14, 09:10 EST\n' + - 'Scheduled - SkyBlock will be undergoing maintenance for a game update. There is not currently an exact ETA for when the maintenance will end.', - TextContent: '\n' + - 'Jan 15, 15:06 ESTCompleted - The scheduled maintenance has been completed.Jan 15, 07:55 ESTUpdate - Maintenance is currently still in progress, maintenance will last a few hours longer than originally intended.Jan 14, 09:30 ESTIn progress - Scheduled maintenance is currently in progress. We will provide updates as necessary.Jan 14, 09:10 ESTScheduled - SkyBlock will be undergoing maintenance for a game update. There is not currently an exact ETA for when the maintenance will end. ', - guid: 'v1kgjvxxbcrk', - categories: [] - }, - ... - ] -} -``` - -## Links - -- [getAPIStatus](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getAPIStatus) -- [APIStatus](https://hypixel-api-reborn.github.io/#/docs/main/master/class/APIStatus) -- [APIIncident](https://hypixel-api-reborn.github.io/#/docs/main/master/class/APIIncident) diff --git a/docs/methods/getBoosters.md b/docs/methods/getBoosters.md deleted file mode 100644 index e0fcd1b03..000000000 --- a/docs/methods/getBoosters.md +++ /dev/null @@ -1,67 +0,0 @@ -# getBoosters - -Allows you to get all active boosters. - -## Arguments - -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getBoosters() - .then((boosters) => { - console.log(boosters); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const boosters = await hypixel.getBoosters().catch((e) => console.error(e)); -console.log(boosters); -``` - -## Example response - -```js -[ - Booster { - purchaser: '978ddb705a8e43618e41749178c020b0', - amount: 2, - originalLength: 3600, - remaining: 3595, - activatedTimestamp: 1545244519133, - activated: 2018-12-19T18:35:19.133Z, - game: Game { game: 24, id: 24, code: 'SUPER_SMASH' } - }, - Booster { - purchaser: 'dfe1bb0a4220421486506ba487cdb530', - amount: 3, - originalLength: 3600, - remaining: 3600, - activatedTimestamp: 1586351429371, - activated: 2020-04-08T13:10:29.371Z, - game: Game { game: 23, id: 23, code: 'BATTLEGROUND' } - }, - Booster { - purchaser: 'f456fe17ba9741f68d2938907b443313', - amount: 2.7, - originalLength: 3600, - remaining: 1744, - activatedTimestamp: 1609097441466, - activated: 2020-12-27T19:30:41.466Z, - game: Game { game: 51, id: 51, code: 'SKYWARS' } - }, - ... -] -``` - -## Links - -- [getBoosters](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getBoosters) -- [Booster](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Booster) diff --git a/docs/methods/getEndedSkyblockAuctions.md b/docs/methods/getEndedSkyblockAuctions.md deleted file mode 100644 index 0aad66f3d..000000000 --- a/docs/methods/getEndedSkyblockAuctions.md +++ /dev/null @@ -1,70 +0,0 @@ -# getEndedSkyblockAuctions - -Allows you to get all ended auctions in around the last 60 seconds - -## Arguments - -- Boolean - include item bytes (`false` by default) -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getEndedSkyblockAuctions() - .then((data) => { - console.log(data); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const data = await hypixel.getEndedSkyblockAuctions().catch((e) => console.error(e)); -console.log(data); -``` - -## Example response - -```js -{ - info: AuctionInfo { - page: 0, - totalPages: 1, - totalAuctions: 409, - lastUpdatedTimestamp: 1635958343258, - lastUpdatedAt: 2021-11-03T16:52:23.258Z, - age: 0 - }, - auctions: [ - PartialAuction { - auctionId: '0c296cb0369249339b9e7e0dab224091', - auctioneerUuid: '5ec150a8026e4c299fbf9619f9bf10c9', - auctioneerProfile: '83c5c5f87aca47f5a5c079ca9bfe2828', - bin: true, - itemBytes: null, - buyer: '91a5a476b2d94632bf542d71c56b4cd3', - price: 60000 - }, - PartialAuction { - auctionId: '3ac36e5ed54e487d9a876b3be58bed2f', - auctioneerUuid: '3e4cbd18866140da88d5ffed25f34d1e', - auctioneerProfile: '3e4cbd18866140da88d5ffed25f34d1e', - bin: true, - itemBytes: null, - buyer: '840f212f11c640088ea2ce375b70b6a2', - price: 2690000 - }, - ... 309 more items - ] -} -``` - -## Links - -- [getEndedSkyblockAuctions](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getEndedSkyblockAuctions) -- [AuctionInfo](https://hypixel-api-reborn.github.io/#/docs/main/master/class/AuctionInfo) -- [Partial](https://hypixel-api-reborn.github.io/#/docs/main/master/class/PartialAuction) diff --git a/docs/methods/getGuild.md b/docs/methods/getGuild.md deleted file mode 100644 index 8f491b1c9..000000000 --- a/docs/methods/getGuild.md +++ /dev/null @@ -1,94 +0,0 @@ -# getGuild - -Allows you to get statistics of hypixel guild. - -## Arguments - -- Search parameter. ('player', 'name' or 'id') -- Player UUID/Nickname or Guild Name or Guild ID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getGuild('name', 'The Foundation') - .then((guild) => { - console.log(guild.level); // 112 - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const guild = await hypixel.getGuild('player', 'StavZDev').catch((e) => console.error(e)); -console.log(guild); // null (player isn't in guild) -``` - -## Example response - -```js -Guild { - id: '52e5719284ae51ed0c716c69', - name: 'The Foundation', - description: 'Hax <3 Ays Forum thread: https://hypixel.net/threads/the-foundation-f-1-legacy-guild-applications-open-questing-all-games.695949/', - experience: 317328400, - level: 112, - members: [ - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - [GuildMember], [GuildMember], [GuildMember], [GuildMember], [GuildMember], - ... - ], - ranks: [ [GuildRank], [GuildRank], [GuildRank], [GuildRank], [GuildRank] ], - totalWeeklyGexp: 13093255, - getRanksByNewest: [Function (anonymous)], - getMemberUUIDMap: [Function (anonymous)], - getRankByPriority: [Function (anonymous)], - createdAtTimestamp: 1390768530176, - createdAt: 2014-01-26T20:35:30.176Z, - joinable: true, - publiclyListed: false, - chatMuteUntilTimestamp: null, - chatMuteUntil: null, - banner: { Base: '0', Patterns: [Array] }, - tag: 'F', - tagColor: Color { color: 'YELLOW' }, - legacyRank: 1, - expHistory: [ - { day: '2021-01-13', exp: 123713 }, - { day: '2021-01-12', exp: 2252825 }, - { day: '2021-01-11', exp: 1942112 }, - { day: '2021-01-10', exp: 1976094 }, - { day: '2021-01-09', exp: 2425690 }, - { day: '2021-01-08', exp: 2345603 }, - { day: '2021-01-07', exp: 2027218 } -], - achievements: { winners: 2627, experienceKings: 489954, onlinePlayers: 125 }, - preferredGames: [ - [Game], [Game], [Game], - [Game], [Game], [Game], - [Game], [Game], [Game], - [Game], [Game], [Game], - [Game], [Game], [Game], - [Game], [Game], [Game], - [Game] - ] -} -``` - -## Links - -- [getGuild](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getGuild) -- [Guild](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Guild) -- [GuildMember](https://hypixel-api-reborn.github.io/#/docs/main/master/class/GuildMember) -- [GuildRank](https://hypixel-api-reborn.github.io/#/docs/main/master/class/GuildRank) -- [Color](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Color) -- [Game](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Game) diff --git a/docs/methods/getLeaderboards.md b/docs/methods/getLeaderboards.md deleted file mode 100644 index bab0c5c3e..000000000 --- a/docs/methods/getLeaderboards.md +++ /dev/null @@ -1,169 +0,0 @@ -# getLeaderboards - -Gets all leaderboards. - -## Arguments - -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getLeaderboards() - .then((leaderboards) => { - console.log(leaderboards); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const leaderboards = await hypixel.getLeaderboards().catch((e) => console.error(e)); -console.log(leaderboards); -``` - -## Example response - -```js -{ - ARENA: [ - Leaderboard { name: 'Overall', title: 'Rating', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: '1v1 Wins', playerCount: 10, leaders: [Array] } - ], - COPS_AND_CRIMS: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Defusal Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Defusal Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Deathmatch Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Deathmatch Wins', playerCount: 10, leaders: [Array] } - ], - WARLORDS: [ - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'DOM Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'TDM Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'CTF Wins', playerCount: 10, leaders: [Array] } - ], - BLITZ_SURVIVAL_GAMES: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Solo Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Teams Wins', playerCount: 10, leaders: [Array] } - ], - UHC: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Wins', playerCount: 10, leaders: [Array] } - ], - WALLS: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 10, leaders: [Array] } - ], - PROTOTYPE: [], - PAINTBALL: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 10, leaders: [Array] } - ], - SKYWARS: [ - Leaderboard { name: 'Overall', title: 'Rating', playerCount: 14, leaders: [] }, - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 14, leaders: [Array] } - ], - MURDER_MYSTERY: [ - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Kills as Murderer', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills as Murderer', playerCount: 14, leaders: [Array] } - ], - SMASH_HEROES: [ - Leaderboard { name: 'Overall', title: 'Smash Level', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 14, leaders: [Array] } - ], - DUELS: [ - Leaderboard { name: 'Weekly', title: 'Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Wins', playerCount: 10, leaders: [Array] } - ], - SPEED_UHC: [ - Leaderboard { name: 'Total', title: 'Salt', playerCount: 16, leaders: [Array] }, - Leaderboard { name: 'Normal', title: 'Kills', playerCount: 16, leaders: [Array] }, - Leaderboard { name: 'Normal', title: 'Wins', playerCount: 16, leaders: [Array] }, - Leaderboard { name: 'Insane', title: 'Kills', playerCount: 16, leaders: [Array] }, - Leaderboard { name: 'Insane', title: 'Wins', playerCount: 16, leaders: [Array] } - ], - TNTGAMES: [ - Leaderboard { name: 'Overall', title: 'TNT Run Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'PVP Run Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Wizards Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'TNT Tag Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Spleef Wins', playerCount: 10, leaders: [Array] } - ], - BEDWARS: [ - Leaderboard { name: 'Current', title: 'Level', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Final Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Final Kills', playerCount: 14, leaders: [Array] } - ], - TURBO_KART_RACERS: [ - Leaderboard { name: 'Overall', title: 'Gold Trophies', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Gold Trophies', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Gold Trophies', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Laps Completed', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Grand Prix', title: 'Points', playerCount: 10, leaders: [Array] } - ], - BUILD_BATTLE: [ - Leaderboard { name: 'Lifetime', title: 'Score', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Lifetime', title: 'Coins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Lifetime', title: 'Wins', playerCount: 14, leaders: [Array] } - ], - ARCADE: [ - Leaderboard { name: 'Current', title: 'Coins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Coins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Coins', playerCount: 10, leaders: [Array] } - ], - SKYCLASH: [ - Leaderboard { name: 'Total', title: 'Kills', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Solo', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Doubles', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'TeamWar', title: 'Wins', playerCount: 14, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 14, leaders: [] } - ], - QUAKECRAFT: [ - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 10, leaders: [] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 10, leaders: [] } - ], - CRAZY_WALLS: [ - Leaderboard { name: 'Overall', title: 'Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Overall', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Kills', playerCount: 10, leaders: [Array] } - ], - MEGA_WALLS: [ - Leaderboard { name: 'Overall', title: 'Final Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Final Kills', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Final Kills', playerCount: 10, leaders: [Array] } - ], - VAMPIREZ: [ - Leaderboard { name: 'Overall', title: 'Human Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Monthly', title: 'Human Wins', playerCount: 10, leaders: [Array] }, - Leaderboard { name: 'Weekly', title: 'Human Wins', playerCount: 10, leaders: [Array] } - ] -} -``` - -## Links - -- [getLeaderboards](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getLeaderboards) -- [Leaderboard](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Leaderboard) diff --git a/docs/methods/getPlayer.md b/docs/methods/getPlayer.md deleted file mode 100644 index 5d4030425..000000000 --- a/docs/methods/getPlayer.md +++ /dev/null @@ -1,131 +0,0 @@ -# getPlayer - -Allows you to get statistics of player. - -## Arguments - -- Player nickname or UUID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/PlayerMethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getPlayer('StavZDev') - .then((player) => { - console.log(player); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const player = await hypixel.getPlayer('StavZDev').catch((e) => console.error(e)); -console.log(player); // if player doesn't exist will return null - -// include player's guild in Player -hypixel - .getPlayer('StavZDev', { guild: true }) - .then((player) => { - console.log(player); - }) - .catch((e) => { - console.error(e); - }); -``` - -## Example response - -```js -Player { - nickname: 'StavZDev', - uuid: '52d9a36f66ce4cdf9a56ad9724ae9fb4', - history: [ - 'StavZ', - 'GravitonSurge', - 'StavZDev' - ], - rank: 'MVP+', - mcVersion: '1.8.9', - channel: 'PARTY', - firstLoginTimestamp: 1505345803214, - firstLogin: 2017-09-13T23:36:43.214Z, - lastLoginTimestamp: 1609782932833, - lastLogin: 2021-01-04T17:55:32.833Z, - lastLogoutTimestamp: 1609783056053, - lastLogout: 2021-01-04T17:57:36.053Z, - recentlyPlayedGame: Game { game: 'BEDWARS' }, - plusColor: Color { color: 'DARK_GREEN' }, - guild: null, - karma: 4747751, - achievements: { - skywarsKillsTeam: 3853, - skywarsCages: 26, - skywarsWinsTeam: 403, - skywarsWinsMega: 5, - skywarsKitsSolo: 23, - skywarsKitsTeam: 25, - skywarsWinsSolo: 2767, - skywarsKillsSolo: 19580, - skywarsKillsMega: 83, - skywarsKitsMega: 10, - generalChallenger: 2838, - generalQuestMaster: 2183, - generalWins: 6602, - ... - }, - achievementPoints: 4155, - totalExperience: 25842562, - level: 141.33, - socialMedia: [ - { name: 'Twitter', link: 'https://twitter.com/StavZDev', id: 'TWITTER' }, - { name: 'YouTube', link: 'https://www.youtube.com/channel/UCQcOYjpXiDEWpb34eBtObtQ', id: 'YOUTUBE' }, - { name: 'Discord', link: 'StavZDev#6469', id: 'DISCORD' }, - { name: 'Hypixel', link: 'https://hypixel.net/members/imstavz.1246904/', id: 'HYPIXEL' } - ], - giftsSent: 25, - giftsReceived: 6, - isOnline: false, - lastDailyReward: 2021-01-03T18:37:11.800Z, - lastDailyRewardTimestamp: 1609699031800, - getRecentGames: [Function (anonymous)], - stats: { - skywars: SkyWars, - bedwars: BedWars, - uhc: UHC, - speeduhc: SpeedUHC, - murdermystery: MurderMystery, - duels: Duels, - buildbattle: BuildBattle, - megawalls: MegaWalls, - copsandcrims: CopsAndCrims, - tntgames: TNTGames, - smashheroes: SmashHeroes, - vampirez: VampireZ, - blitzsg: BlitzSurvivalGames, - arena: ArenaBrawl - } -} -``` - -## Links - -- [getPlayer](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getPlayer) -- [Player](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Player) -- [SkyWars](https://hypixel-api-reborn.github.io/#/docs/main/master/class/SkyWars) -- [BedWars](https://hypixel-api-reborn.github.io/#/docs/main/master/class/BedWars) -- [UHC](https://hypixel-api-reborn.github.io/#/docs/main/master/class/UHC) -- [Speed UHC](https://hypixel-api-reborn.github.io/#/docs/main/master/class/SpeedUHC) -- [Murder Mystery](https://hypixel-api-reborn.github.io/#/docs/main/master/class/MurderMystery) -- [Duels](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Duels) -- [BuildBattle](https://hypixel-api-reborn.github.io/#/docs/main/master/class/BuildBattle) -- [MegaWalls](https://hypixel-api-reborn.github.io/#/docs/main/master/class/MegaWalls) -- [Cops And Crims](https://hypixel-api-reborn.github.io/#/docs/main/master/class/CopsAndCrims) -- [The TNT Games](https://hypixel-api-reborn.github.io/#/docs/main/master/class/TNTGames) -- [Smash Heroes](https://hypixel-api-reborn.github.io/#/docs/main/master/class/ShashHeroes) -- [VampireZ](https://hypixel-api-reborn.github.io/#/docs/main/master/class/VampireZ) -- [Blitz Survival Games](https://hypixel-api-reborn.github.io/#/docs/main/master/class/BlitzSurvivalGames) -- [Arena Brawl](https://hypixel-api-reborn.github.io/#/docs/main/master/class/ArenaBrawl) diff --git a/docs/methods/getRecentGames.md b/docs/methods/getRecentGames.md deleted file mode 100644 index 25352d783..000000000 --- a/docs/methods/getRecentGames.md +++ /dev/null @@ -1,52 +0,0 @@ -# getRecentGames - -Allows you to get recent games of a player. - -## Arguments - -- Player nickname or UUID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getRecentGames('StavZDev') - .then((recentGames) => { - console.log(recentGames); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const recentGames = await hypixel.getRecentGames('StavZDev').catch((e) => console.error(e)); -console.log(recentGames); // if player doesn't exist will return null. -``` - -## Example response - -```js -[ - RecentGame { - game: 'SKYWARS', - id: 51, - code: 'SKYWARS', - dateTimestamp: 1612067873760, - date: 2021-01-31T04:37:53.760Z, - mode: 'solo_insane', - map: 'Aquarius', - ongoing: true, - endedAt: null, - endedTimestamp: null - } -] -``` - -## Links - -- [getRecentGames](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getRecentGames) -- [RecentGame](https://hypixel-api-reborn.github.io/#/docs/main/master/class/RecentGame) diff --git a/docs/methods/getServerInfo.md b/docs/methods/getServerInfo.md deleted file mode 100644 index 6954fbb6c..000000000 --- a/docs/methods/getServerInfo.md +++ /dev/null @@ -1,53 +0,0 @@ -# getServerInfo - -Sends a STATUS packet to hypixel and parses the return info - -## Arguments - -- Repeats (Sends x amount of ping requests and gets the average. Should be between 1 and 10) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getServerInfo() - .then((serverInfo) => { - console.log(serverInfo); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const serverInfo = await hypixel.getServerInfo().catch((e) => console.error(e)); -console.log(serverInfo); -``` - -## Example response - -```js -ServerInfo { - protocolUsed: 736, - versionInfo: 'Requires MC 1.8 / 1.16', - players: { - max: 200000, - online: 50225, - players: [], - toString: [Function: toString] - }, - rawMOTD: '§aHypixel Network §c[1.8-1.16]\n' + '§6§lSKYBLOCK 0.11 §7- §5§lDWARVEN MINES', - cleanMOTD: 'Hypixel Network [1.8-1.16]\n' + 'SKYBLOCK 0.11 - DWARVEN MINES', - textMOTD: 'Hypixel Network [1.8-1.16]\nSKYBLOCK 0.11 - DWARVEN MINES', - faviconB64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAttklEQVR42nV7B3hc5bXt2Oq9Te+9d400TV2yLFndkiXZlm1Z7pY7roCxKcEBktiQhCQkXMilmRoIJYRwk3Ah/eYBCYnBQGICBAImBmPcrfXWf0am3ff8ffs7lkYzc/b61957rf+cIzObAr/qGh47tmDNKrSNLMKGK67B5r3XYtboEqT6hpHuH0Gax9Tno3ceYm3d0jH15de+FI1zR9A4OB3S/0fRNTaGkVXLMLFxFVZeshZrtk9i3aXrsP7TWI8NjI0iLtuATZf//+OS3RuxdfcmbNuzCTv2bsSOKzd9Gtv5u73X78a+A1/Bdd+8Dnuu34NrD1yHic3r0DO29JzDGf29rGNg+J0fP/nw+eu+uZ8nNoH6Pp5k3zz+0TY09A2htr0H0ZZOhBvbEWqYhWB9G4J1rQikmhFIt0jh5/+lSDZ9Gr5k45eiIROJBv5tI4LpJoTqRDQiXP/5aEC4jpGuRyTdgAhfz0RDJsTvUg2IphtRzfdHGWF+fjiZ+X91fTOjSYooI9bQgtqmVtS2zEIo1YIm5rTn+mvx4yfvn+pbtPgTWffY4qnb7zqAnnnDsPmSMPuTMPoS8NQ0wRJMwxxISb8zTYd4TYT0szh+KczTn6Fj6MXf+1P820xYGFbp/3yvl5/jrkWZ0oisrCLMkOUz8jCTx8K8KmgMLtis1bAaw7AYQ1CpbJArrSivNEOptqOgxAaZTDYdJZApHNDz8wz2GPSuBHQefr9HHBPQukXEpf8r+Vp7/1zs//YerN2+DrL2BYtJuW3wx+pRoXJCobagSmVGcbkW5VUGVMiNqFAYUcmoYigUJinKFXzt0+BrKgvkWgdK9S6UGz1wOyJwOaslUI0iWa8AKCmFxh5GUVEFcplwNhMor1JCY7RBbbBCb3Yh3NSOWctWYtbEStSzZOoH56Nl0VLMXr4avZPr0bFyDQbXbcKSTVsxvmU7RiY3YXDFJLyJFlSpzfyuOIyeWgJSDYOnBiZ3DYyu6swicQECyRb0j41iYsNKyFqHx7Blz+UI1NajqEwPVZUFqgozVJUWKHlUS5H5nb3ShoDCgxqVH/pyA+SlWhTmFqMovwzKSis0VQ7Y5Q7ElC6sNEYwZgijTmVHUWEZ8ovLIc+tQN7MQq66FllFZUzaDos3jPp5C9DO5NpXrMZsJtez6RJ0TW5E84IJtC5ZgbYlqzCy90qs2b8f++66CytuuAEHn34ab7z3Ho68+y/87Le/w8OP/xSjy9fAy1LUcxGUJSqUFPA7S5RQlKpQXqzkApqgc8VgD6XROKcL6c4+yFrmLWQD2gZfbaMEgEYCQCTPY7kRNiakZfLaCivBccAgdxIAH2rVAZgJhrxUh7zsfJQVVKGBv580RbHDXI2Uwg5DqRpl0zSdwSjjSpu9IbSNL0P3ijVS0t1Mtm3ZGtQNLUbd4GKk545BX90MmSnJ93kgyxJhh0zjwEyzG2pvBDKWgCOSQufAQqzdsgutPfMwMrEWd9z3IzS0zIHeHoWiUgNniQHGEg0qihSoLFbxdwYyIg4TGVjfOUdq7rKW4YXYcBlLIN5E2hvgkNtgrDBJq65nsg6lB2b+HKyyw6X0QkEQxEr7FG64q2wwy108wXxoyIQF+gg6jXF4StSf1qfcTFpb3XCEa0jhVehcux7d67fg2ltuRWJ2L3tFDazhNKzsN6JfqGwR1EY96JwTxJwuxhw/j0y2swPt7Z2YPbsDff396O3rwOzOhPTZshILyix+tPaPMo9maLUulOSVwS0WsUyHKjJVIaLSmClHlke4oRWz5y+ArGloPpZvInVqGlDKP3AqnPBw1R2ku7rMADWTKc4vh6GwCoNaPwJcZTeTHtWFMEsThLpQiazsPBTkFUJLyuXIcpn4TKj0LJlQDN0bNqH/ku3o3boD6cUroPJHkeIECCfqobEFoHPWSM2r3OhCJRvdUFMKv7x/Az45cT1On7kep04dYPyc8W+cOXMGp0+fxPGP3sXHxw/j/fd/il27d6JC54PW5oMsuwQFLLWC3FJUFaklhirJaj2BMFXYWKbTALBHBNPNHPXTACzjPPYQgJIKA0xy0osr71G4EOLRSgTLSZ/KvFJ0q1wYIQijXOlVBnZo0l6WnYv83AKJ4mLFy5QaeOJ1rOMt6N18CdLzFiM0h+O0sRnt3X3YvPESPPfgfWhPkuJM2h5pgMbqg0tnx3hzM566eQ3eeuEKYGo/gJsYBxl/ZpzFubPn8O6Rt/DtbWuwe7AHSwdnwxeKwsCkDFzVwuJSTpRcqLl4LqUfFqVPSl7HElayVBXMT2rGBCBAAFqHLwKwebXEAFECBtLaSgZYSXMPKe8likY2EH1BGcyspWiZEh7+jYe/z80p4urnIpcMKFOqOXZ8mDO5AQM7LkXD8BKoQ+zGDg/mDo3iJz95Gic+OYmzp0/gvd8+g8G6NEpcYdT2jMDn8OHKzgF8Y2gYz987gXOnb2DC+zE19V3GrTh/7lUc//fb2LNqM0aqZ2FIpsdCCfBSVDpi0ormFldANiMLGibvZuJuVWAaACsUZIGizIgSNkQBgIWTSADQMm/+dAl8CoAeJianY0e3cfVtpHqAIIQYiUoT6kmhirxiyHK44rlFyMsv4tyWodJkQcfqtei9ZBt6NlwCc009ipV6LJlYgTvuvg8nThzHhQunmdRx4PyvcegHX0WjKwJdvB7xvvnwE4CvUnwd6B/GLw8MMeHr+LebGDfgzKlf475vfhfL2ueiVWbBIia/y+lCp8MOW1BojhTPWyUxsJx1H+S5xtQh2Jm8KAEdGSCmVXmBHBWfByDVROW78IsAFBIpbZUVdtLfLBqgaHSMoMqLCD+4U25CpESOgpx85ObmSZTXWDyczRvQtW4zGkh3hd0Po8WKnZdejuMfn8D58yeZyCHGbYwf4MLZp/Cnm65AnTMIU10z4r3zEbR7cWNfL77f243/2h3CuZOr+bdbceH8d/D7pw5gJNCAOBPv1UZwucuLHrORmsEpzXTR0GRkYHl+JTo1PqTZl1w8Z3+V6GFceVJf9LJKvu5TuqXkBQjB6joMLl/xZQYYSBs3G6FbWn33NAAiGjj2FupDaKnUoTivgCAUQWlxo3/tRuz5zvcRbe4kIDq0zJqNRx69CydPfsQkTjHuZBzA1IWv8vgdTJ35Bf70jUtRR6DM7MQJMsBjdmKP14Hr3XY8takC5w7X8W/vxqmTt2NysBmNMhfmGKOYqwhil5XTSGOCyptRnfmC+jOzpX61ylSDOM/TwJXXc3KpJOrrqFko3vKrUK32w+pLSdMmSAZ0j4x+BoBogmWc+wHSxyAnAJwGXgEEo4ar/xVrDZZrvdDkF7PplcBG4TSy8zJceuBmpDsGmLwBwyNz8fwLz+Ds2ReZwO2YYsKYuh64wKZ2rA842oWpdybx4r61ZECUALQgQQa4CeTlFiVu4so+PazAuUMpvude/OOVb2NhIo75MhsW673UFw5sNlphUVHQCFXJ2hdN2FMox1pTNTp0EVhJfS3B0E5TXzDAxP8bS7So1wapTFMwUIqH6lswvGLpZ03wIgBRbRTVOspHoiiY4OCxXxfFFdTkATZCmWwGnDQf41Rmm75yA01GN9QmM77zvX345OSvJJoDVzO2MflrgJNjwEddwNth4J8RTL1FkK5YiLSNGr+xFenBMThZRrsdKtyVtuDZURXOv5wmAAfx5is3Y2VjHDvYfC+zGQmAGVGVHsUEwEwGVFBJ6tmT1jP5NcZq6XzNBMDOCaAi7atKNRILbKKx8+c2AuQgAHqCFyYAiyZXEQDq7KUbOAZjDShiE/RTCHXpa9CgTyBBILr4pmuscWzSUoVR7Nhq67Dqmn2487HHqcCGpD6wfGk7Pjh6G8fUzZzT+3D65CKc+UCseCeTrmbyTuCIA3jDjQuvNuCZjf2oltMvzOrA4O7d8Hj8uNJeiR93W/HiuIYAkAFT9+L9t2/BxtZa7MqpxDUuPXaYDHCpdCjUWGCmoquQa+ArkmOrOY5hQ5yjj91fjD+Wr5GmycDx5+REs1PEqXLK0S4AIP113iSqm9qw4fLtkKW7+rF4coUEQAkBqCrTSApqkSGCNaYYrrQlsVHvgSuH3Z8rMY8G5K5HH0fvyGLk6Dlq9HYsjySweW4rVs6pxYquOkzMjmHXYAjvPOlj8rVM3AW8bgP+ZmVyEfxiXQ8ixXZ42C+G9uxBzBfEwbgSL6x24J2delyYBuDdI7dgawvPQVGJe2Im3OAywMnpUmZmh/cnkFdagXI25Fls3AsMCdRqwhzh7GEEQKy6j57Ew3JQcYyXUa3Wq72wTzMgwv6zfPMayGKtHViwejncEgN0nO35yJ5JMZFTCDdVoBA/5vxSztgcVFQZ4a1rQXpWD5S2aqmbaliHYbq/XekuzJP50UX93iQLcGQFsH+hDyd+7wXeDGDqb3aCYMb5Q278fLIL4XwrvO1kAAGIB4J4vFOFN69w4uwPDMDhJEvgfvzrHw9g76wk7lBV4IGYBfvsethVRhjoA4Kts1FQIWdDruB0MmKnJUmKR2HlBHPLRf9ywUUtU5xTgiw2SS3/rk4bknpABoAWifmyaBOFxbJxOKs5uwlAdlY2Zs6YmdHyFBbFuWUceaUo4wfIi9WoylNIr1XSLivlpBkBMNBm+uxO+HQ6jJscGNT70c6OPagM4ImrPDj/Ckvgb2TA62TAazX4+ZoOhGeYJAAGLt+NuM+Pnw2qceJWN/CkHng1QQbch2PvPoLbO1N4pKMcv1hpxY0xqkxq/5aVq5EcHEZJWRVm8Lw8RVXYZUnwe2u54m4pcSHlS8laR14JHFzIWvaHsCYgTQ4DI0oGrNgyCZkwBQPji+GM1lMK65DDmZqXXcBkVdL4iGliiGqiCGtjqNbWoJlfElJYIS9UEP1ylJapJSZkq8wopCCJl6sxyC/rUgbRRhZc0enF6T+yBF4zsRRCOH98FZ5aOwtBmRauplbE6P46fFa8fqUJ5+7j3z2jIwBxNtFHcObEL/HUlkac/GMlPnnGgSc26RBxOtG4bCWaFo6jtEqFvJwKVJGhQyo3htm7oqR/CVe9jJI4SeHTq3QiyolmIihixFs4AcTmSLKtAzd850bIgnVN6F28CA4CUE6KKzk3K6iaQmq6Ml0t4oxaJh/kzy5VEA2GFEbYINtoirSlehTQJBnZkMRuj05sQlSqMaZmD9G5MC/LjbW1Prz9VIBNkMm9HcS5j5biRyNsVjI5PM2tCHePYo7PjLdvMgPPeQhAAcHi1Jh6Dzh3lCNxDn/OxoVDLvxslx5hsx2phUvQMr4SpfQdOZxKMpatiSu9UO1BiCufx3qfQ92/QutDnEkLYWepoq9RZQBQOmvR0NmDO+hJZMF0I7oXLYKdAFSS0m4mKS/Wwkgq6fkm0VGD6jB81AdeWuMwNXYrQRk1Jjl3a1BBhaUkykKSitmsL1VgQm3FCr0DY0VObI578MajLo4/0vtDAUA/Hppn/wwA6oC5XjOOft0C/IEg/bkUeG85ATjDPsD4Ww8ZIZMA+O11RtRQK9gbZqN58XKUa/SSFM/JLSRr82DL55jOyoGloALr9WF0afySiBPjUThYO89TAKBw1KCxqw/3PfEIAUg1omfx4gwDKHU1HBnlRSoY+SYt32QRslIVoh7w8RiAXxgkjptmXQzrzNTVrMEKvsfiE+OF/pxSeRkBWGOyY7HMgZ1tLpz6M+v/fQLwSQTnTgzioWEHXLIqCYBIz3wsClnw4ffYJF8kAC8o+LcrWQLTALw+DcDLLjz/TSOSDjbBOAVU/xDtsx7ZsiyUssvnUpxlM3nRt0wc12t0fqQp4f3yjL0XfcFQZaZ4qpUAaCIADzz5KAGgqOlZNJYBQGGWtrYKWduqSjvBcEpjRcxWu0CSRy9BcJEJcerySc5fAUC53C5pbI27BtpiOVZqLdjDjr2zmMalzYkzh6gBjkcIQDXOnRrDQyPs1LIKeAUAc0Yx3mDHiWcofw8HGRyBR9dI9vfzAEz91YUXvmVC0mmEKdmKxvmLJT+QJZuJwgLRByphY/n6WAJl2YUsiXJUMxc7+5i10gIrj8pS9it39WcA/IQA+Clsmnv7YQulUaW2MXGbJHUvAiBkpUjcx9Lw8OhXBwmCT2qMffo4VJwSFRV6qbtWOTiHSypwqUmDKx1aXMqmurvdhdN/JQCn2QdO1RCApXhofgAemRrO5hZEuhZieQcb5Z+p/v5Rj6nTuwjWDpbAOQJwNlMCh2Q4f68PPx7k6FSyBNICgHFUaU3S5ouJDGyhzBU7VgGeb4A/Wyl9FTy3IMWQhYpQlKqCU85ACS6VwJxe3Pvog4IBDehdkmmCYkdGJRjAsSespJkfKIFA+uh4FJsMHgJhVnjRSAAWG2LQiRHJDzZzFFbaQ7AWZwD4iluLrwUNODDXgTOHKYjODdIKJwjABB7oU8DI2tVZLAgmezDepsPpdxcAH4xh6vwPyZQ9BIAuUljow73AE7mY2hHEX4YcSBsNMKRa0Ty2FJU6E3JlOVyMMBqFzuf5Cgmsov7XkA0Osa1H8VaRXw47gRDqUO+IQO2qRXp2F757x60ZAPoIgHMagFLO1Fx2UUOFVTITlSXU03SJGjLCSCBCLAEbQWih6NhqroEtr5TjT88SSKCKAJjJgL1mDe5PGPFUvwn/sdyFMx8zCWxhUgtw7vQmPLGuH7vaZ+O6oU7c0NWB76/twdmTe/n6tUz6bgKwlf9/gqD9C3h4ANhegamNQbw834E6AqBPZgCo0plRLCtEmpMpLPQ+F0/0LLEBIvYBlZId1sJKZyg2dgSbdfawdH2gpqUdl167BzKxHd4+OAR7uA5VGgfKOdaEgKjMZ3NjHVXRaSkKlagsUiNGBFfQeDSx/gc4BZbRgOhYLqUEwMoSKLSFECqvwJ0hPR6pN+MXI0rcvT6NM2e+TwBEPMc4jHNnTvF3J3H2zMeMDxnv8/dPMZj0hYeoFzroHg+wbP5JXzUErCUAm4I4zOZZrzdAm2whABOQE4BsjkH9tPe3sXwtAgiCoKGxE2Wsnt7EFSxWix1unqPYQovSC6zZvp4MSDRkhBCVoFLr4gr7UctVjotgvSdIr6QQQppq6CmORtRObGL3v9aewqQhTMlczBIgA6gFCqwBBEsrcTBmwNN9VjzamI/blrXjzCeHSP+P2Nc+YZDa589+FqLRSQ3vBOM443e0zJfg3ItkwSf/AK6aRwDKgUuCeH/SjTYbXV68WWKAQmdhCcyAjQbOwISdVRnj4+Dct4oJxhDJqy+GAMAa/BSA1dvWZUpgcGIJAWiAggB4iaBf+GfWkJV17+H8NxNR4bSEmNCypmIVRnRTVvr4pblZeZBXGmAP1aGETTBYQgBqDXhuTDBAjYPjCZx9dh9w/woGx9sDPD6yHlOPb8DUk6sw9SyPR0j919gDXh/AhcMd+PdjLhx7fBRTnxwBvkYANlQA3w3hyKP0GQkdsqwxNC9aijKdEXJZLnrYizL7lBnz45qe/SKENxAgmHjuGgKg4SJJADS2SvsgshABGF65FC6aIblOzH6HVO8X6SNCbDJ0GJIYMqYQ5xcECYCQmAkqx3zOYbXOgYbhcdjSbQiUVuGeiB6/X27FXy8rw0/XteHsS6T1naPAt7TAf4SA/6QmeJo2+b8Y/10PvESdcFgGvCzD8cdNOHpvJY492o+pfz9PBvQDN1BG/yaEvz/tQWOtDjJztSSFy9gElbJszNVyOvG8PUxYgOCd3sWykwECgIuCzizAsPglACIEQFydloVSDZi/apnkBhU6L9TUzerP00ZMACYtmktCE8KQOYVe2spu+oHqcg3yOIY0VH2NBMBeNwt+AvBIkwFH93rw8YEiPL2mF2dPUdaefgu4ZzFwsx0XvhPAmRv9OPM1Hi8P4cwDNEu/cePcsx68f38YH9xvwbGHOyigHsXUXvaDH3KEvkgGPO1GYw0BsFRzDC5BqZZ1zgUY1gYQpvX1UvaGqFHSaj+inAgCEB3P3yaksGCwkO8CALEhQg+0cPVSmiECMLZ6GTw1jZAbfNAovpi8ViqDMALsAWGaoVr6gBZjGv0qD5rJgGKegIaCpGXBBNSpWZhlU+DotVzRu9w4+w0tfkfjc/bU/7DO36QU/m9MPTSAV7cbcQn9/Q6PATssBlzHhnlsoxvPrbThrTsD+LcA4MF2nPzTg5i6lb7glzXAx2G8+awbTVEBQBT1w4tQoKEoIgMmjVHUMvEgo47Ji6iVNnI9XH2HdPVKAGASY93sh3F6R2h4fOEXAVAYfVSCJqg/pb9dqh8BQJT6v0ZH789oowzea01hvs6HAs5zozuIkSv2IDi8ALMdanz0dQLwIxfO7XHj7xuCOP+vywmAAOFFnD9yFZ5Z4pS8gIyTRpZTSu2uxBUGE25O2/H2fwZw7H4rjj00CxfeOQj8hCP0j0mKqDDeJktaYqIECMC8MeSqKYpkedhpqUH1xR1sssDHFfczgtNGSEwFExVtSUEVVCYvjGJPsK4FAwtGMgAsWrs8A4DJL109UbK5KYV0ZIgLpYIFfk0ECX0SNYx+Qxw3cAr0knpib8DiiWB0714Ehuej067BqX2k9J30AOs9+OAqJy68uYTJ/4wd/ic48cI4Huo0IJCtQ7nZApW4QqyoxHIam2vr3PgnGfDhA3a890AzLrx3C/B/+oDn0xIAx17yoj2th0wfRd3gfMgUanhnFuCrtlp0sCxDTFRVpMz0ACYvtvatwqdQuJUVKJCdU5gBgAyQdoWHBr8IgNIc4KqbpK3kzNUUBkWQmvM/wFEY1yUQY/TrY7ieAAwYophBCpocQczdth1+cfuLV4PTVztxdpcbR8dd+NdeNy4cIY1P76e4uROnXrkOD3YJKVwBlSeAWOdcOHV6rNXosDflxZu3swTus+Pow82YOkUAXuzD1DQAJ173oqORAHAx0gMjmEkARAlcaQziBk6GUbW4KFrCiWBHUGyQ8iiXrnW4kEt/UEJFmAEgAV84gTn9fRkAFn8KQJCUN0MjZCPR03D1FWSBhmYiyC8V8thKOTyXAOyzpTHXUE0hkg2j3YeBLVvhnTuCbnqAjyddODzPgRc7bXhoiErw9WYanDHO/Xtw8uUb8eAc+glZJcw1CSR6R2HXG7FCpcWelB//+I8A3rnNjY9/2k5HfDUB6CIAnBSnwzj1lg9zWgiAMoJk3zDKlDpJB0TKlEiXqWGjiKvmhLLmlkOZXQRzXhnKOaZNNGxhSmQ/TZtmmgGhdDP6RucRgORnAKgsISjJABWTFlvLQvNb2DjEdYJqba3UBH0Eol9fi+3WNGaRillsgka7H70bt8DUOBuNagWe77Hh2VlW3O814o4uO86+wnH3Thv9zddx7I978EC7F75cJU1NgwSAjfN8Qq3F7oQXr3/bi/du9+H4CyOYOktj9EInAWigO47g9FE/5rQbICsNIdregyJOnDyWYGFhOWS5BXAUq3Ep+8EqQwiDuiCW8Pza2QOW6MKYx1HpYn9TGj3SXSph9oD++SMZAC6WgMoagl5ukXqAuMLqpOaPMGlR/142QrEtFucUGGAPWGFJo1VfzRUgAM4A+rduh6OhHbWV1AHVBvwobsJBtxF3d1tx9i9m4K0opo5vwtHnduKBNh/1ggYBGhJxZcihM2C1gQDEvXjtRg8+fCiACx9OkDGTBGAWAWgiAAGc/tiD7i4LZNpqRFs7yVgHG2kpclim+VV6xLlgey1xNKkDWGImQ011aDWk4RPXOUVPYzkIAIzTAMxdMCoAqJemgJsA6K1h1LKZaAmAhsZCEkH8UIcwQGJDhH0gTQCWmuKYIABdLIESujG1yYH2ZWvhpBByVarwDZ8O99cYcdBlxD084bN/sXMKshe8Mxtv3L8W99V7EFbrERsYRLJ/AQEwcpRpcTUZ8Pcb3Tj9mJ9GaA2b5lo2QJbC/0lRLSdw6kQMra1ZHIMdaJo/gZYlKzHO5rts56VQmixwZMkxaeJE4Pl20K+4eO5iJ0u42otTTWV0fzoG54kxGCQA81dNSABo7BG6KCVNUBlqxAaiuFeIb1RI4YSTLBAfupwACHTd9A05BECls3EsUQjRpblUBuz36/Bg3IgHWAIP9IsSqCUDOA6PJHDo2/24t9aGKE84Pm8kA4DejHUWHfbF3HjtGjem/tufSf4CGfB8ElN/ms8GejdOn7kLGzetxazuAPS+KFp7hnHojTfw4uHDiKfT0kheSIcqrg7XkAUOzv6giuVCTxNmiHJWGjxSE4w0tmEBF14WSNRj7sQ4pXAjdM4YjJS4yoJK6V6AHl0Nkpz/FvYAMVpi2ihGKIK2W+sxSIqJ+4myZhAAjQ2JnlFYaps5LYz4QdiA/2q24HC/A2+u9+KC2OZ+uwbnXwvjxWuTOBg1odpiQ3J0Abv5Qhj1VvSyCe71O/HKDhem/jANwPnVwF95PPmCtEU2NTWFc+fex7F/9qKtSYalqzfjDy+/jE3X7mMPKEbujCzpXoYaMsDHZMUlcgd7mY2LJm73EU1cRQAMEgCzsHDtisyOUPfYIjhohvQu0eT8SPCNhiI5QhyHC00JLDKlsJPCZyll8Nftac7dBOIskRnstHkzs1BSooAtmMIMWxApgwG/bLfij2yEp9d4cHS7nwaHFH6zmkc/Xt5fQwYYUW11IDV/DGkyQGewo5Edfbfbib9MUjf8JkwAxL7gXoJAh4gpZP6dwLmPNuAPl2WhmxR++LlnsfO734WMrjCHkry4oBgzs/MkG+/mohmoAAX1VdOqVpSCapoBYQIwTAvwvwDwqIScDMJRooSlqALVZVos07ixSktxUSiHh7PUR3YUUlSUVKlQUFCGyko9HL44ZDY/2kwGvLnIiWNbnTi/wYNj1/hw4TUquSMhAuDDywdaCYBFAiC9aLF0T4HeRKFVYsMaoxd/WcsS+JWXC74ysz/A5KX0zx3HmeNX41vrZAjIirFgw2Y88utfYWT9BoqxbBRw/ldX6ODl+RaJc8stlUAQK/95S6w0ZHqAYMDAsvEMAF0Lxz5jAJtgkgC4+EEBztdAqQLeokq4SuTIZ/Ky7HzIsnKhs7lRO2cerOF6yV0pXSl25CC62PlPXe6i6SGVt3twil196lVq+SNenH/Zjxeu6WYJ0EhZbZi9fiOG9+yFPVILV64ZK/VevDTpw9QzVcCrC5n7G0z+DBf+H7TFy/DCpAbxPKq/lnbc8tij2HjgAPROt3RtwFEsR7fahxaVW7LpYoEqCxWSIXKT+pppUaQ0uD4DYOkSyDyxNFK9Q1IiencNO74Xbez0daz3GhqjJtZ5ivI4Quen5rzNn5lHShnQ3DUXIys3svkthjXEkVhPk9QeQStH2qmbKIXvIQBfZ3zbw2SiwN8cBMCHF64mAJEMAJ0bN2P0qqtgjyZgzzVhld6Pl9Y6cOFXLJl//ZhC6N9Mfh/OXT8bH00YMaIg4wJRbNt/E66+7XZ4ahMZKc7GvY2zf6GxFhE2P32JTrpAUslmnpdbCE2xCjoKITlL+jMA2tG/lAzwVKeR6P4MAB2TFpI3aUihnrp/0JjECnMSyyh7GyqNKC8o4ZfmIFHfjn3fuxUD23ch4HHhsesceOWXPuxcacXJGx3AYw5MkQW4zZvZ7v6bjQB4v8CAzo0bMXrllQQgDms+AeBq/WkDwfrtCuC6bmBPPz6+zIUragvQajMj32DFrEXLccnX9iNS3ygln00dMFftwTXWWoqwgHRvk7gI0kzNkhIXeagCc3MyMljcLaq4CEBTe6YE3NUpJHsyAIi7KNWKjAXW80PE/BcuS2w4iB2gHlLMylIQNyTZHQGsvnQP2hatgN1kwnqnFteP2/DBP6naXmcXf4zJf49A3K0nABHg72TAoYsAZMZg8+o1GQZUJ2CdQTls9eF/lnhxansU59aa8NHyCmwwm6Q7Q2W0sR5OmblrN6N1aAHysoqkK9aDChtucSSxxVTNju+VGp9FNDwyoI5TrJkhLpeXUh4X5pVCoc8AEG2ajaHlSzMAXGSAzhGFRuGUrg2IXSGxHaaTrrbaMKwL8IOcUFBvF+UV0gPkIJJuxaqrr+UITcJGc7NEZsDXVrtw4oN+4F26uEME4gkC8rKWANhxnr3gha/04GC1AMDGJjiOYdpoUQJ6vnepzYOfDXpwtVuP7V4LetxWGh+zVGLxrkHE+0Y4NudDrjZIfaiGlP6Wnc7UFkcjp5dReH4unk7saImbI3nuUeYQ14QREfc3yx2flkB182yMCh0gATDNAD0BsIsamt5MFB4gTASDbIqj+gAdlgt2glCcXyKxQGuwYWRyM3onJimHOQF0WozLyITlfpz4aBk791YquF/QB2yhEOJUONaB5wUAIZaAzYFo3xBt7RgbWRC2Ygt6NU7sq6bv0HHVy2l6qN1t4TQi7f0Izx6AK96MKoVeuinKWFCBrZYErqQVbheXvcWODxlglK5h2KdzEEx2S7f7CEus4/lfnAKxltkYm1zxRQYIAJxMVhIQpL8AQGyEBOkH6nQxjqmIdKk5lyMnKzcf+bSYBpsXTQsnJE1vNrsxZDJipUyJ60eTeOmn4ibHv7KbHwOOr8WF0+M49L0x3BuzI0IG2OvbYAvV0aKyc1fY0MKTd6mMUKgpxanZneE6xLqG4G3oIAtSKGL5iXuUxCQKcUptpO4fMVCsaYLSvqVRStYtyXgdAdBO6wDdNBjiZyGFRamHOP3G16/8Yg/Q2sISSrbp20xFCUTJAOEChQkao/bfZo6gRcGRkl8mXZEtL1TCQW8d7RiAiclYNSbMszBkXE3K45d+/ijOnzlCNfdrnD/1axy+fRPujesR0lpgrWuFlQJKaw9CoTRCyShQmWlyvDyfOgRaehBs7oLBXY186o0Ccc2vsJIjTwEtv1/4fqH5G2nWnKS4bZoFOpawYICu6jMARClndECmBGpopqQ7RNxRwYBB6QvVlgA00rXAAN1fhEwISBuiorGI/YCUVgAQxYQ+iDmct5V5xcjPKaJP0Eu3zgRbu6F2hrgKOjRT3CwoNWBPWzOef/JBHD3yEt499Ae8esfNNEOinHSw1bVJd4mrrQEozD4p9K4IbNEGVHfMhSPaCLMjhqIC+vu8KrRrw9hERdquclHsFCArKx/6Uh30HHFpLlZKK26T80p2XshfizT/HdLqi5CegZgGoLa9axqACBtCa5f0eIza4ucfmaUGoptuguIDFDRFBv6c5GgRvnqVzg8/Lagsu0C6Hl+UU8rVM7EZphBomkNbTR2u4EmprJhXYcVibxzb+gfx3ME78Ksb9+Fg2ouwUg9rugXWQAoaGx0bv98ea0INDU6MDc8SSKKU2kPGEVZVoESfMYVL7PXYaqvHHCPZwfPx0lK7S7UoyymBokAOE3+nZ1iZuGCDtiqjAs1yj8QKCQAxBfwpxDt6sGT9NAPic+ZKz/mIBiFuKZeLy0pM2iHddkY7TKr5WVdhHu1M3MovLeCJiZuklbnUBTnittlcyJUGJCiqkoMLoDA6UFWhRVzrRIeMdllGMIJ1uCwSxF0RA2oMFlhECRAAUX617PBJNkR3sk26hl9A9VnATm8p0aJBX4sNTHyjNYk4F6WOANTT5zs4nQw8p2qVDzaCoSzghCIYxRx5ogT007RXcxGkp16mATDxO+t65mLxOvYAV0TskbdLd10qtJnVFndZmsXDEHzjbKWDqsoENZNW80vM4pYY1qGck8BZrMYKfRTREjV/LkXhjAKyyImGhUtZDl2oNDr5xTp0sj47VWE0yTwYr3Dhh0E9EvQCdQMjtOFNCDd3wp9qg9lbIzW6nCwyiyZLRT2/xJLCOia/iGIsKl2Z9kl3sdQZ6pBigxZaX81F0XLlxe294kGOYpo0RcV0I5QAsEgbvEIJKvTODAC9g2yCqzJKME5Za/TEUCY3UDGVkVZqan8F3NTXHXIzApIxqoKVYWOI10L80h5DLXbb0ricKzOmr4GKNrpgRil0dg+alixDjL1F743yJIyU0x60yUMYoD+/wmxB1OXjCmxCDcebnR1eQyMkY8JCw+v4OVm5Rajiag7Tdg/we/zS7e9+6V4FYXGd/DlEuS6OksYX9CcYYYLtLtVnQGDSWk4XM4/leReFkAAgjfr+YUxsXA2ZN1aHdO88TgA/yhUmFLLhlBIEOVc6VK5FdSV9wHRE2R8iVVYk5TYsNiSw3JLEalMMGywxLOMKJVl7eRyRxdkV0JAJqf55aBybgL22CXJ+tlJuRBcb63aOuWS0BtfsvxGNFDayrDJSt0i6tydNsSLuVNWwpuXsMeP6aqzm9wRVQWk6OadDuhWeK+yUbok3f2p7xTNNoiQ8peKmbk6qnGIU5RZDyVL6jAEEYGAYK8SNksFkE0bXbJT29ktpespYe/lMooBvruBKiJsNnOKiI3uBuC2mxRCnR0ggwYlQw/mb1IQQ4xeuNMYwYUzARfSzOKezxL2EVWxSNXVoGFvKKdGOGToXajj+brAq0FyTwA0334LWeWOSnTVRq68yhDFGxdmn8WGIIHhZdr78Kiw3xJAm3cV9CULQiM1a0dxUXF1tmRHGSqd0MUdcz1Tyd8L4hPn/EpZSeRH1f4kGVpaBeAJOoc3cZl9HEZa5NkgAFq3fAru/GuVcZRtrtrKYzaSQdCyk1yfdXUTZS2rFdXSIPLEAqeejvBQ7RI00SXX8/SJTLS6zpyiE2EvK1SgoKUcB+0QBV9HkCiA1tBAOdnm9zUfnV4ZILIFb7rgHXeNsRDPZOwhAu9qPmNKONo0LY8Zq2nIvy8eMZKUOFpacn9+nV3G0KV1SiKtYomnr5XZpN1uEeDBKxaNPSeFTpuaIpqiibrFydIpjldoqPQzawBJYs3U9ZIE4x8rwQpRQhhawlirZB7LzVcjOU7IOFZiZo6CbUiE3l1Y0V82jGjn8OT9PPEylpRDSorLUCC2/0Klxw+qkoXLWQuVg2GMop8eXyWij+bkOWu9Aii5O50Q71edt9zxAAFZlni6TFUglZHHHYfEm4BRPdkjP9ySk+xCFehP3IRk94vmgxPQx/qWonY649FSqgaFz1UghPVXK1/LICGekATuu2YebfnAzZImWjqk9X9+PTtaEWYgQNqRgolGKACOUFNE0ffz8z5kIXoxUEzu5ODYjnGqZjmaERPD1QLwB0bpm1DU0oG1WO75188249fYfIpaixK2qgJ4K0mMOStLYwrFoZoij9XMhtIKZyvHzYfKLxGIM8ZRolElnwuSthom/t/J1WzATRleYI7sKXQODuO/RH2H55g3nZd6ahmPjG9ZfOPjw/ViwbCla+/ulJ7HFU9lbLt+AHVduxs6rtkixa/r4+f+L178c2/eK2ITtV2z8NLZdsQFbGZt2rcPkjklsuWILNl2+CfNXL8W85eNsxEOSIhWy/P8VCU6qEJWjOEo/d1+Mwf8V4vW24cVoHx3H3OVrMbx6PeatXIfalk7UNLXhyuuuwubdWy8k5/Qfl5kN/t/Vzur7sHfxBBrIgjrWhnicTETL0CiblIj5mRgcQcvAEJr65qKxdwANPf2o7+5FfVcv6uZ0o65TPI7ahVTHdMyew+hEqr0TSSk6kJjVgdrW2Yg0tTLaaEvbGbMQqm9FUMjptHgqvUl6qCkwzSrxtLl48twbr5OePvfV1v/vqPliBOKNUkhMTWXY6mUJikg0t18Ip5vfN5uCv/m/ezrDmHEPQgkAAAAASUVORK5CYII=', - favicon: , - ping: 163 -} -``` - -## Links - -- [getServerInfo](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getServerInfo) -- [ServerInfo](https://hypixel-api-reborn.github.io/#/docs/main/master/class/ServerInfo) diff --git a/docs/methods/getSkyblockAuctions.md b/docs/methods/getSkyblockAuctions.md deleted file mode 100644 index e71733c7d..000000000 --- a/docs/methods/getSkyblockAuctions.md +++ /dev/null @@ -1,138 +0,0 @@ -# getSkyblockAuctions - -Allows you to get skyblock auctions - -## Arguments - -- "\*", a page number, or an array with the start and the end page number (automatically sorted) -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/auctionsOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getSkyblockAuctions(1) - .then((data) => { - console.log(data); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const data = await hypixel.getSkyblockAuctions(1).catch((e) => console.error(e)); -console.log(data); -``` - -## Example response - -```js -{ - auctions: [ - Auction { - auctionId: '739762c5556848008bd719df6b027bd8', - auctioneerUuid: 'b62f419ed8dd40bbaf0d2e8c075a0e1a', - auctioneerProfile: 'b62f419ed8dd40bbaf0d2e8c075a0e1a', - bin: true, - itemBytes: null, - coop: [Array], - auctionStartTimestamp: 1635954533152, - auctionStart: 2021-11-03T15:48:53.152Z, - auctionEnd: 2021-11-03T21:48:53.152Z, - auctionEndTimestamp: 1635976133152, - item: 'Gemstone Mixture', - itemLore: 'A collection of finely treated\n' + - 'Gemstones held together by\n' + - 'the sturdiest of sticky\n' + - 'substances.\n' + - '\n' + - 'RARE', - itemLoreRaw: '§7§7A collection of finely treated\n' + - '§7§dGemstones §7held together by\n' + - '§7the sturdiest of §asticky\n' + - '§a§7substances.\n' + - '\n' + - '§9§lRARE', - rarity: 'RARE', - startingBid: 1200000, - highestBid: 1200000, - bids: [], - claimed: false, - claimedBidders: [] - }, - Auction { - auctionId: '5b27b677b59b4059b9502aa958b9b3a5', - auctioneerUuid: 'dea9145c3b384f57a23299fa5b7d8ff9', - auctioneerProfile: '06c2bf868f154bf0b6446fc7f099b5c9', - bin: true, - itemBytes: null, - coop: [Array], - auctionStartTimestamp: 1635915150654, - auctionStart: 2021-11-03T04:52:30.654Z, - auctionEnd: 2021-11-17T04:52:30.654Z, - auctionEndTimestamp: 1637124750654, - item: 'Rock Gemstone', - itemLore: 'Reforge Stone\n' + - '\n' + - 'Can be used in a Reforge Anvil\n' + - 'or with the Dungeon Blacksmith\n' + - 'to apply the Auspicious\n' + - 'reforge to a pickaxe.\n' + - '\n' + - 'oThe lowest gemstone in the\n' + - 'ofood chain.\n' + - '\n' + - 'Auspicious (Legendary):\n' + - 'Mining Speed: +45\n' + - '\n' + - 'Requires Mining Skill Level\n' + - 'XXI!\n' + - '\n' + - 'RARE REFORGE STONE', - itemLoreRaw: '§8Reforge Stone\n' + - '\n' + - '§7Can be used in a Reforge Anvil\n' + - '§7or with the Dungeon Blacksmith\n' + - '§7to apply the §9Auspicious\n' + - '§9§7reforge to a pickaxe.\n' + - '\n' + - '§7§8§oThe lowest gemstone in the\n' + - '§8§ofood chain.\n' + - '\n' + - '§9Auspicious §7(§6Legendary§7):\n' + - '§7Mining Speed: §a+45\n' + - '\n' + - '§7Requires §aMining Skill Level\n' + - '§aXXI§7!\n' + - '\n' + - '§9§lRARE REFORGE STONE', - rarity: 'RARE', - startingBid: 1800000, - highestBid: 1800000, - bids: [], - claimed: false, - claimedBidders: [] - } - ... 900 more items - ], - info: AuctionInfo { - page: 1, - totalPages: 59, - totalAuctions: 58497, - lastUpdatedTimestamp: 1635957623258, - lastUpdatedAt: 2021-11-03T16:40:23.258Z, - age: 11, - failedPages: [] - } -} -``` - -## Links - -- [getSkyblockAuctions](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getSkyblockAuctions) -- [AuctionInfo](https://hypixel-api-reborn.github.io/#/docs/main/master/class/AuctionInfo) -- [Auction](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Auction) -- [Bid](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Bid) diff --git a/docs/methods/getSkyblockAuctionsByPlayer.md b/docs/methods/getSkyblockAuctionsByPlayer.md deleted file mode 100644 index 729583220..000000000 --- a/docs/methods/getSkyblockAuctionsByPlayer.md +++ /dev/null @@ -1,101 +0,0 @@ -# getSkyblockAuctions - -Allows you to get player's skyblock auctions - -## Arguments - -- Player nickname or UUID -- Boolean - include item bytes (`false` by default) -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getSkyblockAuctionsByPlayer('StavZDev') - .then((data) => { - console.log(data); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const data = await hypixel.getSkyblockAuctionsByPlayer('StavZDev').catch((e) => console.error(e)); -console.log(data); -``` - -## Example response - -```js -[ - Auction { - auctionId: 'f213f4499d3341959d1fe5a7f78dc14d', - auctioneerUuid: '28667672039044989b0019b14a2c34d6', - auctioneerProfile: 'd3df3cccffd3473fbbba311d5329bd25', - bin: false, - itemBytes: null, - coop: [ - '4ce231a79af8473faf1dab7ecf4de2ad', - '28667672039044989b0019b14a2c34d6', - '0e3713522c0f4b63a20e2474724ae761', - 'ed32a0660fc948378dcf8ed717d1188c' - ], - auctionStartTimestamp: 1565028554338, - auctionStart: 2019-08-05T18:09:14.338Z, - auctionEnd: 2019-08-06T06:09:14.338Z, - auctionEndTimestamp: 1565071754338, - item: 'Protector Dragon Fragment', - itemLore: 'Right-click to view recipes!\n\nEPIC', - itemLoreRaw: '§eRight-click to view recipes!\n\n§5§lEPIC', - rarity: 'EPIC', - startingBid: 800, - highestBid: 80000, - bids: [ [Bid], [Bid], [Bid], [Bid], [Bid] ], - claimed: true, - claimedBidders: [ - '9e93a11bdced49279afb87e1bd205098', - 'd500749d2666436b814b8e34717a3b51', - '8ce05c84824b404faa0397614be6cac5', - '56b9c409d8cf4fdda08a131dd6b37579' - ] - }, - Auction { - auctionId: '9b714581da774c729ea95ee0dc38a089', - auctioneerUuid: '28667672039044989b0019b14a2c34d6', - auctioneerProfile: 'd3df3cccffd3473fbbba311d5329bd25', - bin: false, - itemBytes: null, - coop: [ - 'd8a5686cae794419aafc72a93afb7b26', - '4ce231a79af8473faf1dab7ecf4de2ad', - '40884fdda30c4c26ba00abef570469e0', - '28667672039044989b0019b14a2c34d6', - '32eda389f6d1446f8c26b30fe1384550' - ], - auctionStartTimestamp: 1570978114450, - auctionStart: 2019-10-13T14:48:34.450Z, - auctionEnd: 2019-10-13T14:53:34.450Z, - auctionEndTimestamp: 1570978414450, - item: 'Rotten Flesh', - itemLore: 'COMMON', - itemLoreRaw: '§f§lCOMMON', - rarity: 'COMMON', - startingBid: 2, - highestBid: 532647, - bids: [ [Bid] ], - claimed: true, - claimedBidders: [] - } - ... 153 more items -] -``` - -## Links - -- [getSkyblockAuctionsByPlayer](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getSkyblockAuctionsByPlayer) -- [Auction](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Auction) -- [Bid](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Bid) diff --git a/docs/methods/getSkyblockBazaar.md b/docs/methods/getSkyblockBazaar.md deleted file mode 100644 index bba7bebe1..000000000 --- a/docs/methods/getSkyblockBazaar.md +++ /dev/null @@ -1,65 +0,0 @@ -# getSkyblockBazaar - -Allows you to get list of products - -## Arguments - -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getSkyblockBazaar() - .then((products) => { - console.log(products); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const products = await hypixel.getSkyblockMember().catch((e) => console.error(e)); -console.log(products); -``` - -## Example response - -```js -[ - Product { - productId: 'INK_SACK:3', - sellSummary: [ [Order], [Order], [Order], [Order], [Order], [Order] ], - buySummary: [ - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order], [Order], [Order], - [Order], [Order] - ], - status: { - sellPrice: 2, - buyPrice: 3, - sellVolume: 2340181, - buyVolume: 2555183, - sellMovingWeek: 27628511, - buyMovingWeek: 7376853, - sellOrders: 34, - buyOrders: 337 - } - } - ... 204 more items -] -``` - -## Links - -- [getSkyblockBazaar](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getSkyblockBazaar) -- [Product](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Product) -- [Order](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Order) diff --git a/docs/methods/getSkyblockMember.md b/docs/methods/getSkyblockMember.md deleted file mode 100644 index 3dbdfb97f..000000000 --- a/docs/methods/getSkyblockMember.md +++ /dev/null @@ -1,138 +0,0 @@ -# getSkyblockMember - -Allows you to get a player's skyblock member data from all their profiles - -## Arguments - -- Player nickname or UUID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getSkyblockMember('StavZDev') - .then((map) => { - console.log(map); // if player has no skyblock profiles will return an empty Map - }) - .catch((e) => { - console.error(e); - // if player doesn't exist will throw an error - }); - -// async/await -const map = await hypixel.getSkyblockMember('StavZDev').catch((e) => console.error(e)); -console.log(map); -``` - -## Example response - -```js -Map(1) { - 'Lime' => SkyblockMember { - uuid: '52d9a36f66ce4cdf9a56ad9724ae9fb4', - player: null, - profileName: 'Lime', - firstJoinTimestamp: 1560352500017, - firstJoinAt: 2019-06-12T15:15:00.017Z, - firstJoinHubTimestamp: 848208, - firstJoinHubAt: 2019-06-12T15:29:08.225Z, - lastSave: 1615632015391, - lastSaveAt: 2021-03-13T10:40:15.391Z, - lastDeathAt: 2020-02-14T16:11:05.000Z, - lastDeath: 21420965, - getArmor: [AsyncFunction (anonymous)], - getWardrobe: [AsyncFunction (anonymous)], - fairySouls: 14, - fairyExchanges: 0, - skills: { - farming: [Object], - mining: [Object], - combat: [Object], - foraging: [Object], - fishing: [Object], - enchanting: [Object], - alchemy: [Object], - taming: [Object], - carpentry: [Object], - runecrafting: [Object] - }, - slayer: { zombie: [Object], spider: [Object], wolf: [Object] }, - dungeons: { types: [Object], classes: [Object] }, - collections: { - LOG: 19, - SEEDS: 7430, - COBBLESTONE: 6206, - COAL: 92, - CARROT_ITEM: 1225, - ROTTEN_FLESH: 38, - 'LOG:2': 84, - 'LOG:1': 2, - 'LOG_2:1': 69, - WHEAT: 7770, - IRON_INGOT: 118, - GOLD_INGOT: 52, - SULPHUR: 2, - 'INK_SACK:4': 37, - REDSTONE: 66, - SPIDER_EYE: 1, - STRING: 1, - BONE: 14, - ENDER_PEARL: 1, - MELON: 96, - PUMPKIN: 6, - POTATO_ITEM: 89, - PORK: 15, - FEATHER: 9, - RAW_CHICKEN: 9, - MUTTON: 31, - SUGAR_CANE: 25, - RABBIT: 14, - MUSHROOM_COLLECTION: 63, - LEATHER: 12 - }, - getEnderChest: [AsyncFunction (anonymous)], - getInventory: [AsyncFunction (anonymous)], - purse: 5089.609042968747, - stats: { - highestCritDamage: 2259.52084, - kills: 140, - killsZombie: 33, - deaths: 13, - deathsVoid: 5, - killsInvisibleCreeper: 2, - killsLapisZombie: 2, - killsRedstonePigman: 1, - deathsRedstonePigman: 1, - deathsLapisZombie: 1, - deathsZombie: 3, - deathsSkeleton: 1, - killsSpider: 1, - killsSkeleton: 13, - killsEnderman: 2, - highestCriticalDamage: 60.196500000000015, - deathsUnburriedZombie: 2, - killsPig: 15, - killsChicken: 9, - killsSheep: 31, - killsRabbit: 14, - killsCow: 12, - killsZombieVillager: 5, - giftsReceived: 2, - giftsGiven: 6, - auctionsCreated: 1, - auctionsFees: 45 - }, - pets: [], - jacob: { medals: [Object], perks: [Object], contests: [Object] } - } -} -``` - -## Links - -- [getSkyblockMember](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getSkyblockMember) -- [SkyblockMember](https://hypixel-api-reborn.github.io/#/docs/main/master/class/SkyblockMember) diff --git a/docs/methods/getSkyblockProfiles.md b/docs/methods/getSkyblockProfiles.md deleted file mode 100644 index 382651deb..000000000 --- a/docs/methods/getSkyblockProfiles.md +++ /dev/null @@ -1,74 +0,0 @@ -# getSkyblockProfiles - -Allows you to get all skyblock profiles of player. - -## Arguments - -- Player nickname or UUID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/SkyblockMethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getSkyblockProfiles('StavZDev') - .then((profiles) => { - console.log(profiles); // if player has no skyblock profiles will return an empty array - }) - .catch((e) => { - console.error(e); - // if player doesn't exist will throw an error - }); - -// async/await -const profiles = await hypixel.getSkyblockProfiles('StavZDev').catch((e) => console.error(e)); -console.log(profiles); -``` - -## Example response - -```js -[ - SkyblockProfile { - profileId: '65feab38f8434631b77d616bb40e1987', - profileName: 'Lime', - members: [ [SkyblockMember] ], - me: SkyblockMember { - uuid: '52d9a36f66ce4cdf9a56ad9724ae9fb4', - player: null, - profileName: 'Lime', - firstJoinTimestamp: 1560352500017, - firstJoinAt: 2019-06-12T15:15:00.017Z, - firstJoinHubTimestamp: 848208, - firstJoinHubAt: 2019-06-12T15:29:08.225Z, - lastSave: 1615632015391, - lastSaveAt: 2021-03-13T10:40:15.391Z, - lastDeathAt: 2020-02-14T16:11:05.000Z, - lastDeath: 21420965, - getArmor: [AsyncFunction (anonymous)], - getWardrobe: [AsyncFunction (anonymous)], - fairySouls: 14, - fairyExchanges: 0, - skills: [Object], - slayer: [Object], - dungeons: [Object], - collections: [Object], - getEnderChest: [AsyncFunction (anonymous)], - getInventory: [AsyncFunction (anonymous)], - purse: 5089.609042968747, - stats: [Object], - pets: [], - jacob: [Object] - } - } -] -``` - -## Links - -- [getSkyblockProfiles](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getSkyblockProfiles) -- [SkyblockProfile](https://hypixel-api-reborn.github.io/#/docs/main/master/class/SkyblockProfile) -- [SkyblockMember](https://hypixel-api-reborn.github.io/#/docs/main/master/class/SkyblockMember) diff --git a/docs/methods/getStatus.md b/docs/methods/getStatus.md deleted file mode 100644 index f77cbce1a..000000000 --- a/docs/methods/getStatus.md +++ /dev/null @@ -1,45 +0,0 @@ -# getStatus - -Allows you to get the status of a player. - -## Arguments - -- Player nickname or UUID -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getStatus('StavZDev') - .then((status) => { - console.log(status); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const status = await hypixel.getStatus('StavZDev').catch((e) => console.error(e)); -console.log(status); // if player doesn't exist will return null -``` - -## Example response - -```js -Status { - online: true, - game: Game { game: 'SKYWARS', id: 51, code: 'SKYWARS' }, - mode: 'LOBBY', - map: null -} -``` - -## Links - -- [getStatus](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getStatus) -- [Status](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Status) -- [Game](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Game) diff --git a/docs/methods/getWatchdogStats.md b/docs/methods/getWatchdogStats.md deleted file mode 100644 index f31befd82..000000000 --- a/docs/methods/getWatchdogStats.md +++ /dev/null @@ -1,44 +0,0 @@ -# getWatchdogStats - -Allows you to get statistics of watchdog, the server anticheat. - -## Arguments - -- [Method options](https://hypixel-api-reborn.github.io/#/docs/main/master/typedef/MethodOptions) (optional) - -## Example usage - -```js -const Hypixel = require('hypixel-api-reborn'); -const hypixel = new Hypixel.Client('API-KEY'); - -hypixel - .getWatchdogStats() - .then((watchdog) => { - console.log(watchdog); - }) - .catch((e) => { - console.error(e); - }); - -// async/await -const watchdog = await hypixel.getWatchdogStats().catch((e) => console.error(e)); -console.log(watchdog); -``` - -## Example response - -```js -WatchdogStats { - byWatchdogTotal: 6122345, - byWatchdogLastMinute: 7, - byWatchdogRollingDay: 6374, - byStaffTotal: 2143182, - byStaffRollingDay: 2248 -} -``` - -## Links - -- [getWatchdogStats](https://hypixel-api-reborn.github.io/#/docs/main/master/class/Client?scrollTo=getWatchdogStats) -- [WatchdogStats](https://hypixel-api-reborn.github.io/#/docs/main/master/class/WatchdogStats) diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 000000000..9b9b7a21a --- /dev/null +++ b/docs/package.json @@ -0,0 +1,29 @@ +{ + "name": "@hypixel-api-reborn-docs/root", + "scripts": { + "generate-packages": "pnpm exec tsx ./src/GeneratePackages.ts" + }, + "packageManager": "pnpm@9.9.0", + "type": "module", + "workspaces": { + "packages": [ + "./TypeScript/SettingUpClient/Code/*", + "./TypeScript/SkyHelperNetworth/Code/*", + "./JavaScript/SettingUpClient/Code/*", + "./JavaScript/SkyHelperNetworth/Code/*" + ] + }, + "engines": { + "node": ">=20.16.0", + "pnpm": ">=9.9.0", + "npm": "forbidden, use pnpm instead", + "yarn": "forbidden, use pnpm instead", + "bun": "forbidden, use pnpm instead" + }, + "devDependencies": { + "tsx": "catalog:", + "typescript": "catalog:", + "prettier": "catalog:", + "yaml": "catalog:" + } +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 000000000..9719b1b12 --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,602 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +catalogs: + default: + hypixel-api-reborn: + specifier: 12.0.0-15 + version: 12.0.0-15 + prettier: + specifier: ^3.8.0 + version: 3.8.0 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + yaml: + specifier: ^2.8.2 + version: 2.8.2 + +importers: + + .: + devDependencies: + prettier: + specifier: 'catalog:' + version: 3.8.0 + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + yaml: + specifier: 'catalog:' + version: 2.8.2 + + JavaScript/SettingUpClient/Code: + dependencies: + hypixel-api-reborn: + specifier: 'catalog:' + version: 12.0.0-15 + + JavaScript/SkyHelperNetworth/Code: + dependencies: + hypixel-api-reborn: + specifier: 'catalog:' + version: 12.0.0-15 + + TypeScript/SettingUpClient/Code: + dependencies: + hypixel-api-reborn: + specifier: 'catalog:' + version: 12.0.0-15 + devDependencies: + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + + TypeScript/SkyHelperNetworth/Code: + dependencies: + hypixel-api-reborn: + specifier: 'catalog:' + version: 12.0.0-15 + devDependencies: + tsx: + specifier: 'catalog:' + version: 4.21.0 + typescript: + specifier: 'catalog:' + version: 5.9.3 + +packages: + + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.12.0: + resolution: {integrity: sha512-LScr2aNr2FbjAjZh2C6X6BxRx1/x+aTDExct/xyq2XKbYOiG5c0aK7pMsSuyc0brz3ibr/lbQiHD9jzt4lccJw==} + + hypixel-api-reborn@12.0.0-15: + resolution: {integrity: sha512-xreG5r+2bTn+2WGsNkIvdQa7kjx36AkTYYjdCHYONEqFCRSSYxxkLyV6Rm4/S5ODMlXtrU2rG0Vbw//9VbiNrQ==} + engines: {node: '>=20.16.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + lodash.reduce@4.6.0: + resolution: {integrity: sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==} + + minecraft-data@3.99.1: + resolution: {integrity: sha512-mI9SNwlrqY2uTTLOT332Hf/QlaLa+AH3V36qu3Y2i9Z2/PjsZlja2ToTDHjazWqDMBtfch+rDTwPB2mHloArHA==} + + node-cache@5.1.2: + resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} + engines: {node: '>= 8.0.0'} + + prettier@3.8.0: + resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==} + engines: {node: '>=14'} + hasBin: true + + prismarine-nbt@2.7.0: + resolution: {integrity: sha512-Du9OLQAcCj3y29YtewOJbbV4ARaSUEJiTguw0PPQbPBy83f+eCyDRkyBpnXTi/KPyEpgYCzsjGzElevLpFoYGQ==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + protodef-validator@1.4.0: + resolution: {integrity: sha512-2y2coBolqCEuk5Kc3QwO7ThR+/7TZiOit4FrpAgl+vFMvq8w76nDhh09z08e2NQOdrgPLsN2yzXsvRvtADgUZQ==} + hasBin: true + + protodef@1.19.0: + resolution: {integrity: sha512-94f3GR7pk4Qi5YVLaLvWBfTGUIzzO8hyo7vFVICQuu5f5nwKtgGDaeC1uXIu49s5to/49QQhEYeL0aigu1jEGA==} + engines: {node: '>=14'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rss-parser@3.13.0: + resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + yaml@2.8.2: + resolution: {integrity: sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==} + engines: {node: '>= 14.6'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + base64-js@1.5.1: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + clone@2.1.2: {} + + entities@2.2.0: {} + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.12.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + hypixel-api-reborn@12.0.0-15: + dependencies: + minecraft-data: 3.99.1 + node-cache: 5.1.2 + prismarine-nbt: 2.7.0 + rss-parser: 3.13.0 + + ieee754@1.2.1: {} + + json-schema-traverse@0.4.1: {} + + lodash.reduce@4.6.0: {} + + minecraft-data@3.99.1: {} + + node-cache@5.1.2: + dependencies: + clone: 2.1.2 + + prettier@3.8.0: {} + + prismarine-nbt@2.7.0: + dependencies: + protodef: 1.19.0 + + process@0.11.10: {} + + protodef-validator@1.4.0: + dependencies: + ajv: 6.12.6 + + protodef@1.19.0: + dependencies: + lodash.reduce: 4.6.0 + protodef-validator: 1.4.0 + readable-stream: 4.7.0 + + punycode@2.3.1: {} + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + resolve-pkg-maps@1.0.0: {} + + rss-parser@3.13.0: + dependencies: + entities: 2.2.0 + xml2js: 0.5.0 + + safe-buffer@5.2.1: {} + + sax@1.4.1: {} + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + tsx@4.21.0: + dependencies: + esbuild: 0.27.2 + get-tsconfig: 4.12.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + xml2js@0.5.0: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + yaml@2.8.2: {} diff --git a/docs/pnpm-workspace.yaml b/docs/pnpm-workspace.yaml new file mode 100644 index 000000000..84a2682a5 --- /dev/null +++ b/docs/pnpm-workspace.yaml @@ -0,0 +1,12 @@ +packages: + - ./TypeScript/SettingUpClient/Code + - ./TypeScript/SkyHelperNetworth/Code + - ./JavaScript/SettingUpClient/Code + - ./JavaScript/SkyHelperNetworth/Code +catalog: + tsx: ^4.21.0 + typescript: ^5.9.3 + prettier: ^3.8.0 + hypixel-api-reborn: 12.0.0-15 + yaml: ^2.8.2 + skyhelper-networth: ^2.5.1 diff --git a/docs/src/GeneratePackages.ts b/docs/src/GeneratePackages.ts new file mode 100644 index 000000000..f01ad636d --- /dev/null +++ b/docs/src/GeneratePackages.ts @@ -0,0 +1,165 @@ +import YAML from 'yaml'; +import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from 'fs'; +import { format } from 'prettier'; + +async function TypeScript() { + const dir = './TypeScript'; + const ignoredFolders = ['node_modules', 'src']; + const packages = []; + const files = readdirSync(dir); + for (const file of files) { + const fullPath = `${dir}/${file}`.replaceAll('//', '/'); + if (statSync(fullPath).isDirectory()) { + if (ignoredFolders.includes(file) === false) { + const deeperFiles = readdirSync(`${dir}/${file}`); + if (deeperFiles.includes('Code') && statSync(`${dir}/${file}/Code`).isDirectory()) packages.push(file); + } + } + } + + const packageJSONFile = JSON.parse(readFileSync('package.json').toString('utf-8')); + const currentPackages = packageJSONFile.workspaces.packages.filter((pkg: string) => pkg.startsWith('./JavaScript/')); + packageJSONFile.workspaces.packages = [ + ...currentPackages, + ...packages.map((pkg) => `${dir}/${pkg}/Code/*`).filter((pkg) => !currentPackages.includes(pkg)) + ]; + + const workspaceConfig = YAML.parse(readFileSync('pnpm-workspace.yaml', 'utf-8')); + const currentPnpm = workspaceConfig.packages.filter((pkg: string) => pkg.startsWith('./JavaScript/')); + workspaceConfig.packages = [ + ...currentPnpm, + ...packages.map((pkg) => `${dir}/${pkg}/Code`).filter((pkg) => !currentPnpm.includes(pkg)) + ]; + writeFileSync('pnpm-workspace.yaml', YAML.stringify(workspaceConfig)); + + const prettierConfig = JSON.parse(readFileSync('../.prettierrc').toString('utf-8')); + const formatted = await format(JSON.stringify(packageJSONFile), { ...prettierConfig, filepath: 'package.json' }); + writeFileSync('package.json', formatted); + + const templatePackage = { + name: '@hypixel-api-reborn-docs', + type: 'module', + scripts: { build: 'pnpm exec tsc --build' }, + dependencies: { 'hypixel-api-reborn': 'catalog:' }, + devDependencies: { tsx: 'catalog:', typescript: 'catalog:' } + }; + + const typeScriptConfig = readFileSync('tsconfig.json').toString('utf-8'); + const gitIgnore = readFileSync('.gitignore').toString('utf-8'); + + for (const docPackage of packages) { + const packageJSON = { ...templatePackage }; + packageJSON.name = `${packageJSON.name}/typescript-${docPackage + .replace(/([a-z])([A-Z])/g, '$1-$2') + .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2') + .toLowerCase()}`; + const formattedPackageJSON = await format(JSON.stringify(packageJSON), { + ...prettierConfig, + filepath: 'package.json' + }); + + writeFileSync(`${dir}/${docPackage}/Code/package.json`, formattedPackageJSON); + writeFileSync(`${dir}/${docPackage}/Code/tsconfig.json`, typeScriptConfig); + writeFileSync(`${dir}/${docPackage}/Code/.gitignore`, gitIgnore); + + if (!existsSync(`${dir}/${docPackage}/Code/src`)) mkdirSync(`${docPackage}/Code/src`, { recursive: true }); + writeFileSync( + `${dir}/${docPackage}/Code/src/HypixelAPIReborn.ts`, + [ + "import { Client } from 'hypixel-api-reborn';", + '', + "const HypixelAPIReborn = new Client('YOUR API_KEY');", + '', + 'export default HypixelAPIReborn;', + '' + ].join('\n') + ); + } +} + +async function JavaScript() { + const dir = './JavaScript'; + const ignoredFolders = ['node_modules', 'src']; + const packages = []; + const files = readdirSync(dir); + for (const file of files) { + const fullPath = `${dir}/${file}`.replaceAll('//', '/'); + if (statSync(fullPath).isDirectory()) { + if (ignoredFolders.includes(file) === false) { + const deeperFiles = readdirSync(`${dir}/${file}`); + if (deeperFiles.includes('Code') && statSync(`${dir}/${file}/Code`).isDirectory()) packages.push(file); + } + } + } + + const packageJSONFile = JSON.parse(readFileSync('package.json').toString('utf-8')); + const currentPackages = packageJSONFile.workspaces.packages.filter((pkg: string) => pkg.startsWith('./TypeScript/')); + packageJSONFile.workspaces.packages = [ + ...currentPackages, + ...packages.map((pkg) => `${dir}/${pkg}/Code/*`).filter((pkg) => !currentPackages.includes(pkg)) + ]; + + const workspaceConfig = YAML.parse(readFileSync('pnpm-workspace.yaml', 'utf-8')); + const currentPnpm = workspaceConfig.packages.filter((pkg: string) => pkg.startsWith('./TypeScript/')); + workspaceConfig.packages = [ + ...currentPnpm, + ...packages.map((pkg) => `${dir}/${pkg}/Code`).filter((pkg) => !currentPnpm.includes(pkg)) + ]; + writeFileSync('pnpm-workspace.yaml', YAML.stringify(workspaceConfig)); + + const prettierConfig = JSON.parse(readFileSync('../.prettierrc').toString('utf-8')); + const formatted = await format(JSON.stringify(packageJSONFile), { ...prettierConfig, filepath: 'package.json' }); + writeFileSync('package.json', formatted); + + const templatePackage = { + name: '@hypixel-api-reborn-docs', + type: 'module', + dependencies: { 'hypixel-api-reborn': 'catalog:' } + }; + + const gitIgnore = readFileSync('.gitignore').toString('utf-8'); + + for (const docPackage of packages) { + const packageJSON = { ...templatePackage }; + packageJSON.name = `${packageJSON.name}/javascript-${docPackage + .replace(/([a-z])([A-Z])/g, '$1-$2') + .replace(/([A-Z])([A-Z][a-z])/g, '$1-$2') + .toLowerCase()}`; + const formattedPackageJSON = await format(JSON.stringify(packageJSON), { + ...prettierConfig, + filepath: 'package.json' + }); + + writeFileSync(`${dir}/${docPackage}/Code/package.json`, formattedPackageJSON); + writeFileSync(`${dir}/${docPackage}/Code/.gitignore`, gitIgnore); + + if (!existsSync(`${dir}/${docPackage}/Code/src`)) mkdirSync(`${docPackage}/Code/src`, { recursive: true }); + writeFileSync( + `${dir}/${docPackage}/Code/src/HypixelAPIReborn.js`, + [ + "import { Client } from 'hypixel-api-reborn';", + '', + "const HypixelAPIReborn = new Client('YOUR API_KEY');", + '', + 'export default HypixelAPIReborn;', + '' + ].join('\n') + ); + } +} + +(async () => { + const packageJSONFile = JSON.parse(readFileSync('package.json').toString('utf-8')); + packageJSONFile.workspaces.packages = []; + + const workspaceConfig = YAML.parse(readFileSync('pnpm-workspace.yaml', 'utf-8')); + workspaceConfig.packages = []; + writeFileSync('pnpm-workspace.yaml', YAML.stringify(workspaceConfig)); + + const prettierConfig = JSON.parse(readFileSync('../.prettierrc').toString('utf-8')); + const formatted = await format(JSON.stringify(packageJSONFile), { ...prettierConfig, filepath: 'package.json' }); + writeFileSync('package.json', formatted); + + await TypeScript(); + await JavaScript(); +})(); diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 000000000..517fe6f64 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "esModuleInterop": true, + "skipLibCheck": true, + "outDir": "./dist", + "module": "ES2022", + "target": "ES2022", + "strict": true + } +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 000000000..1307810a2 --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,120 @@ +/* eslint-disable */ +import globals from 'globals'; +import prettier from 'eslint-config-prettier'; +import sortImports from '@j4cobi/eslint-plugin-sort-imports'; +import ts from 'typescript-eslint'; +import stylistic from '@stylistic/eslint-plugin'; +import { globalIgnores } from 'eslint/config'; + +export default [ + ...ts.configs.recommended, + prettier, + globalIgnores(['./dist/', './coverage/', './documentation/']), + { + files: ['**/*.ts', '**/*.js'], + languageOptions: { ecmaVersion: 2022, sourceType: 'module', globals: { ...globals.es2022, ...globals.node } }, + plugins: { '@stylistic': stylistic, 'sort-imports': sortImports }, + rules: { + 'sort-imports/sort-imports': [ + 'error', + { ignoreCase: false, ignoreMemberSort: false, memberSyntaxSortOrder: ['all', 'single', 'multiple', 'none'] } + ], + '@stylistic/max-len': [ + 'error', + { code: 120, tabWidth: 2, ignoreComments: true, ignoreUrls: true, ignoreRegExpLiterals: true } + ], + '@stylistic/space-before-function-paren': ['error', { anonymous: 'never', named: 'never', catch: 'always' }], + '@stylistic/function-call-argument-newline': ['error', 'consistent'], + '@typescript-eslint/no-unused-vars': ['error', { args: 'none' }], + '@stylistic/quotes': ['error', 'single', { avoidEscape: true }], + '@stylistic/array-bracket-newline': ['error', 'consistent'], + 'no-constant-condition': ['error', { checkLoops: false }], + 'no-extend-native': ['warn', { exceptions: ['Object'] }], + '@stylistic/nonblock-statement-body-position': 'error', + '@stylistic/object-curly-spacing': ['error', 'always'], + '@stylistic/no-whitespace-before-property': 'error', + '@stylistic/one-var-declaration-per-line': 'error', + 'prefer-const': ['warn', { destructuring: 'all' }], + '@stylistic/dot-location': ['error', 'property'], + '@stylistic/computed-property-spacing': 'error', + '@stylistic/no-mixed-spaces-and-tabs': 'error', + '@stylistic/type-named-tuple-spacing': 'error', + curly: ['warn', 'multi-line', 'consistent'], + '@stylistic/no-multiple-empty-lines': 'error', + '@stylistic/max-statements-per-line': 'error', + '@stylistic/type-annotation-spacing': 'error', + '@stylistic/member-delimiter-style': 'error', + '@stylistic/template-curly-spacing': 'error', + '@typescript-eslint/no-explicit-any': 'off', + '@stylistic/line-comment-position': 'error', + '@stylistic/object-curly-newline': 'error', + '@stylistic/array-bracket-spacing': 'warn', + '@stylistic/switch-colon-spacing': 'error', + '@stylistic/type-generic-spacing': 'error', + '@stylistic/rest-spread-spacing': 'error', + '@stylistic/no-floating-decimal': 'error', + '@stylistic/space-before-blocks': 'error', + '@stylistic/no-trailing-spaces': 'error', + '@stylistic/no-confusing-arrow': 'error', + 'logical-assignment-operators': 'warn', + 'no-template-curly-in-string': 'error', + '@stylistic/space-in-parens': 'error', + '@stylistic/space-infix-ops': 'error', + '@stylistic/no-multi-spaces': 'error', + '@stylistic/keyword-spacing': 'error', + '@stylistic/linebreak-style': 'error', + 'quote-props': ['error', 'as-needed'], + '@stylistic/spaced-comment': 'error', + '@stylistic/no-extra-semi': 'error', + '@stylistic/arrow-spacing': 'error', + '@stylistic/block-spacing': 'error', + '@stylistic/comma-spacing': 'error', + '@stylistic/curly-newline': 'error', + '@stylistic/semi-spacing': 'error', + '@stylistic/arrow-parens': 'error', + '@stylistic/comma-dangle': 'error', + '@stylistic/brace-style': 'error', + '@stylistic/key-spacing': 'error', + '@stylistic/comma-style': 'error', + 'no-useless-constructor': 'error', + '@stylistic/semi-style': 'error', + '@stylistic/wrap-regex': 'error', + '@stylistic/new-parens': 'error', + 'no-useless-assignment': 'error', + 'no-inner-declarations': 'error', + 'no-implicit-coercion': 'error', + '@stylistic/eol-last': 'error', + 'no-use-before-define': 'warn', + 'no-underscore-dangle': 'warn', + 'no-unneeded-ternary': 'error', + '@stylistic/no-tabs': 'error', + 'default-param-last': 'error', + 'one-var': ['warn', 'never'], + 'no-inline-comments': 'warn', + 'no-empty-function': 'error', + 'no-useless-return': 'error', + 'no-useless-rename': 'warn', + 'no-useless-concat': 'warn', + 'no-throw-literal': 'error', + 'default-case-last': 'warn', + '@stylistic/semi': 'error', + 'no-self-compare': 'error', + 'no-new-wrappers': 'error', + yoda: ['error', 'never'], + '@stylistic/semi': 'error', + 'no-lone-blocks': 'error', + 'no-undef-init': 'error', + 'no-else-return': 'warn', + 'require-await': 'warn', + 'default-case': 'error', + 'dot-notation': 'error', + 'no-sequences': 'warn', + 'no-multi-str': 'warn', + 'no-lonely-if': 'warn', + 'no-new-func': 'error', + camelcase: 'warn', + 'no-var': 'warn', + eqeqeq: 'warn' + } + } +]; diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 01c98f0d0..000000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,71 +0,0 @@ -import jsdoc from 'eslint-plugin-jsdoc'; -import globals from 'globals'; -import js from '@eslint/js'; - -export default [ - js.configs.recommended, - { - ignores: ['docs/**', 'tests/**', 'node_modules/*'], - plugins: { jsdoc: jsdoc }, - languageOptions: { - ecmaVersion: 2021, - sourceType: 'commonjs', - globals: { - ...globals.commonjs, - ...globals.es2021, - ...globals.node - } - }, - rules: { - 'max-len': ['error', { code: 120, ignoreUrls: true, ignoreComments: true }], - 'no-constant-condition': ['error', { checkLoops: false }], - 'prefer-const': ['warn', { destructuring: 'all' }], - 'no-unused-vars': ['error', { args: 'none' }], - curly: ['warn', 'multi-line', 'consistent'], - 'logical-assignment-operators': 'warn', - 'no-template-curly-in-string': 'error', - 'quote-props': ['error', 'as-needed'], - 'jsdoc/no-undefined-types': 'warn', - 'comma-dangle': ['error', 'never'], - 'no-useless-constructor': 'error', - 'no-useless-assignment': 'error', - 'no-inner-declarations': 'error', - 'no-implicit-coercion': 'error', - 'jsdoc/require-jsdoc': 'error', - 'no-use-before-define': 'warn', - 'no-underscore-dangle': 'warn', - 'no-unneeded-ternary': 'error', - 'jsdoc/check-values': 'error', - 'default-param-last': 'error', - 'one-var': ['warn', 'never'], - 'no-inline-comments': 'warn', - 'jsdoc/valid-types': 'error', - 'no-empty-function': 'error', - 'no-useless-return': 'error', - 'no-useless-rename': 'warn', - 'no-useless-concat': 'warn', - 'no-throw-literal': 'error', - 'no-extend-native': 'error', - 'default-case-last': 'warn', - 'no-self-compare': 'error', - 'no-new-wrappers': 'error', - 'no-lone-blocks': 'error', - 'no-undef-init': 'error', - 'no-else-return': 'warn', - 'no-extra-semi': 'error', - 'require-await': 'warn', - yoda: ['error', 'always'], - 'default-case': 'error', - 'dot-notation': 'error', - 'no-sequences': 'warn', - 'no-multi-str': 'warn', - 'no-lonely-if': 'warn', - 'no-new-func': 'error', - 'no-console': 'error', - camelcase: 'warn', - 'no-var': 'warn', - eqeqeq: 'warn', - semi: 'error' - } - } -]; diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 4708630ef..000000000 --- a/package-lock.json +++ /dev/null @@ -1,4815 +0,0 @@ -{ - "name": "hypixel-api-reborn", - "version": "11.3.7", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "hypixel-api-reborn", - "version": "11.3.7", - "license": "MIT", - "dependencies": { - "node-cache": "^5.1.2", - "node-fetch": "^3.3.2", - "prismarine-nbt": "^2.6.0", - "rss-parser": "^3.13.0", - "skyhelper-networth": "^1.26.0" - }, - "devDependencies": { - "@discordjs/docgen": "github:discordjs/docgen", - "@types/node": "^22.10.1", - "chai": "^4.3.4", - "eslint": "^9.16.0", - "eslint-plugin-jsdoc": "^50.6.0", - "globals": "^15.13.0", - "mocha": "^10.4.0", - "node-env-run": "^4.0.2", - "path": "^0.12.7", - "prettier": "^3.4.2", - "typescript": "^5.7.2" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.3.tgz", - "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.26.3" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.3.tgz", - "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@discordjs/docgen": { - "version": "0.11.1", - "resolved": "git+ssh://git@github.com/discordjs/docgen.git#a06a15db5f57a9dde2af50b78480ec59237030a7", - "dev": true, - "dependencies": { - "eslint": "^6.3.0", - "js-yaml": "^3.13.1", - "jsdoc-to-markdown": "^5.0.1", - "tsubaki": "^1.3.2", - "yargs": "^14.0.0" - }, - "bin": { - "docgen": "src/index.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@discordjs/docgen/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@discordjs/docgen/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/@discordjs/docgen/node_modules/cross-spawn/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/@discordjs/docgen/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.3", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@discordjs/docgen/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/@discordjs/docgen/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@discordjs/docgen/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", - "dev": true, - "dependencies": { - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@discordjs/docgen/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@discordjs/docgen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/@discordjs/docgen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@discordjs/docgen/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@discordjs/docgen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/@discordjs/docgen/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@discordjs/docgen/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/@es-joy/jsdoccomment": { - "version": "0.49.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", - "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", - "dev": true, - "dependencies": { - "comment-parser": "1.4.1", - "esquery": "^1.6.0", - "jsdoc-type-pratt-parser": "~4.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz", - "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.1.tgz", - "integrity": "sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==", - "dev": true, - "dependencies": { - "@eslint/object-schema": "^2.1.5", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.9.1.tgz", - "integrity": "sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.2.0.tgz", - "integrity": "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.16.0.tgz", - "integrity": "sha512-tw2HxzQkrbeuvyj1tG2Yqq+0H9wGoI2IMk4EOsQeX+vmd75FtJAzf+gTA69WF+baUKRYQ3x2kbLE08js5OsTVg==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.5.tgz", - "integrity": "sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz", - "integrity": "sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==", - "dev": true, - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", - "dev": true, - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", - "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", - "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@types/common-tags": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.4.tgz", - "integrity": "sha512-S+1hLDJPjWNDhcGxsxEbepzaxWqURP/o+3cP4aa2w7yBXgdcmKGQtZzP8JbyfOd0m+33nh+8+kvxYE2UJtBDkg==", - "dev": true - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "node_modules/@types/markdown-it": { - "version": "12.2.3", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", - "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", - "dev": true, - "dependencies": { - "@types/linkify-it": "*", - "@types/mdurl": "*" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true - }, - "node_modules/@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true - }, - "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", - "dev": true, - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/@types/yargs": { - "version": "15.0.19", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.19.tgz", - "integrity": "sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true - }, - "node_modules/abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escape-sequences": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz", - "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==", - "dev": true, - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/ansi-escape-sequences/node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/are-docs-informative": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", - "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-back": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz", - "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "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/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/cache-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz", - "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==", - "dev": true, - "dependencies": { - "array-back": "^4.0.0", - "fs-then-native": "^2.0.0", - "mkdirp2": "^1.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "dependencies": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/collect-all": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz", - "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==", - "dev": true, - "dependencies": { - "stream-connect": "^1.0.2", - "stream-via": "^1.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-line-args": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.2.1.tgz", - "integrity": "sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==", - "dev": true, - "dependencies": { - "array-back": "^3.1.0", - "find-replace": "^3.0.0", - "lodash.camelcase": "^4.3.0", - "typical": "^4.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-args/node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/command-line-args/node_modules/typical": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz", - "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/command-line-tool": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz", - "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==", - "dev": true, - "dependencies": { - "ansi-escape-sequences": "^4.0.0", - "array-back": "^2.0.0", - "command-line-args": "^5.0.0", - "command-line-usage": "^4.1.0", - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-tool/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/command-line-usage": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz", - "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==", - "dev": true, - "dependencies": { - "ansi-escape-sequences": "^4.0.0", - "array-back": "^2.0.0", - "table-layout": "^0.4.2", - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/command-line-usage/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/comment-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", - "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", - "dev": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/common-sequence": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz", - "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/common-tags": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz", - "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/config-master": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz", - "integrity": "sha512-n7LBL1zBzYdTpF1mx5DNcZnZn05CWIdsdvtPL4MosvqbBUK3Rq6VWEtGUuF3Y0s9/CIhMejezqlSkP6TnCJ/9g==", - "dev": true, - "dependencies": { - "walk-back": "^2.0.1" - } - }, - "node_modules/config-master/node_modules/walk-back": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz", - "integrity": "sha512-Nb6GvBR8UWX1D+Le+xUq0+Q1kFmRBIWVrfLnQAOmcpEzA9oAxwJ9gIr36t9TWYfzvWRvuMtjHiVsJYEkXWaTAQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dmd": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz", - "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==", - "dev": true, - "dependencies": { - "array-back": "^4.0.1", - "cache-point": "^1.0.0", - "common-sequence": "^2.0.0", - "file-set": "^3.0.0", - "handlebars": "^4.5.3", - "marked": "^0.7.0", - "object-get": "^2.1.0", - "reduce-flatten": "^3.0.0", - "reduce-unique": "^2.0.1", - "reduce-without": "^1.0.1", - "test-value": "^3.0.0", - "walk-back": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", - "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", - "dev": true - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.16.0.tgz", - "integrity": "sha512-whp8mSQI4C8VXd+fLgSM0lh3UlmcFtVwUQjyKCFfsp+2ItAIYhlq/hqGahGqHE6cv9unM41VlqKk2VtKYR2TaA==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.9.0", - "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.16.0", - "@eslint/plugin-kit": "^0.2.3", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.5", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.2.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsdoc": { - "version": "50.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.0.tgz", - "integrity": "sha512-tCNp4fR79Le3dYTPB0dKEv7yFyvGkUCa+Z3yuTrrNGGOxBlXo9Pn0PEgroOZikUQOGjxoGMVKNjrOHcYEdfszg==", - "dev": true, - "dependencies": { - "@es-joy/jsdoccomment": "~0.49.0", - "are-docs-informative": "^0.0.2", - "comment-parser": "1.4.1", - "debug": "^4.3.6", - "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", - "esquery": "^1.6.0", - "parse-imports": "^2.1.1", - "semver": "^7.6.3", - "spdx-expression-parse": "^4.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-scope": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", - "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", - "dev": true, - "dependencies": { - "acorn": "^8.14.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/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==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/file-set": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz", - "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==", - "dev": true, - "dependencies": { - "array-back": "^4.0.0", - "glob": "^7.1.5" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-replace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz", - "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==", - "dev": true, - "dependencies": { - "array-back": "^3.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/find-replace/node_modules/array-back": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz", - "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.2.tgz", - "integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==", - "dev": true - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fs-then-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz", - "integrity": "sha512-X712jAOaWXkemQCAmWeg5rOT2i+KOpWz1Z/txk/cW0qlOu2oQ9H61vc5w3X/iyuUEfq/OyaFJ78/cZAQD1/bgA==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "15.13.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.13.0.tgz", - "integrity": "sha512-49TewVEz0UxZjr1WYYsWpPrhyC/B/pA8Bq0fUmet2n+eR7yn0IvNzNaoBwnK6mdkzcN+se7Ez9zUgULTz2QH4g==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/inquirer": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz", - "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.19", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.6.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/inquirer/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "dependencies": { - "xmlcreate": "^2.0.4" - } - }, - "node_modules/jsdoc": { - "version": "3.6.11", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.11.tgz", - "integrity": "sha512-8UCU0TYeIYD9KeLzEcAu2q8N/mx9O3phAGl32nmHlE0LpaJL71mMkP4d+QE5zWfNt50qheHtOZ0qoxVrsX5TUg==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.9.4", - "@types/markdown-it": "^12.2.3", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^12.3.2", - "markdown-it-anchor": "^8.4.1", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "taffydb": "2.6.2", - "underscore": "~1.13.2" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/jsdoc-api": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz", - "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==", - "dev": true, - "dependencies": { - "array-back": "^4.0.0", - "cache-point": "^1.0.0", - "collect-all": "^1.0.3", - "file-set": "^2.0.1", - "fs-then-native": "^2.0.0", - "jsdoc": "^3.6.3", - "object-to-spawn-args": "^1.1.1", - "temp-path": "^1.0.0", - "walk-back": "^3.0.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/jsdoc-api/node_modules/file-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz", - "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==", - "dev": true, - "dependencies": { - "array-back": "^2.0.0", - "glob": "^7.1.3" - } - }, - "node_modules/jsdoc-api/node_modules/file-set/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jsdoc-api/node_modules/walk-back": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz", - "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/jsdoc-parse": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz", - "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==", - "dev": true, - "dependencies": { - "array-back": "^4.0.0", - "lodash.omit": "^4.5.0", - "lodash.pick": "^4.4.0", - "reduce-extract": "^1.0.0", - "sort-array": "^2.0.0", - "test-value": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdoc-to-markdown": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz", - "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==", - "dev": true, - "dependencies": { - "array-back": "^4.0.1", - "command-line-tool": "^0.8.0", - "config-master": "^3.1.0", - "dmd": "^4.0.5", - "jsdoc-api": "^5.0.4", - "jsdoc-parse": "^4.0.1", - "walk-back": "^4.0.0" - }, - "bin": { - "jsdoc2md": "bin/cli.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/jsdoc-type-pratt-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz", - "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==", - "dev": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsdoc/node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "dev": true, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.omit": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", - "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==", - "dev": true - }, - "node_modules/lodash.padend": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", - "integrity": "sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==", - "dev": true - }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", - "dev": true - }, - "node_modules/lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "dev": true, - "peerDependencies": { - "@types/markdown-it": "*", - "markdown-it": "*" - } - }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true, - "bin": { - "marked": "bin/marked" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mkdirp2": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.5.tgz", - "integrity": "sha512-xOE9xbICroUDmG1ye2h4bZ8WBie9EGmACaco8K8cx6RlkJJrxGIqjGqztAI+NMhexXBcdGbSEzI6N3EJPevxZw==", - "dev": true - }, - "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.3", - "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", - "debug": "^4.3.5", - "diff": "^5.2.0", - "escape-string-regexp": "^4.0.0", - "find-up": "^5.0.0", - "glob": "^8.1.0", - "he": "^1.2.0", - "js-yaml": "^4.1.0", - "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", - "ms": "^2.1.3", - "serialize-javascript": "^6.0.2", - "strip-json-comments": "^3.1.1", - "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", - "yargs-unparser": "^2.0.0" - }, - "bin": { - "_mocha": "bin/_mocha", - "mocha": "bin/mocha.js" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/mocha/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/mocha/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/mocha/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mocha/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mocha/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/mocha/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/mocha/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node_modules/node-cache": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", - "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", - "dependencies": { - "clone": "2.x" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-env-run": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/node-env-run/-/node-env-run-4.0.2.tgz", - "integrity": "sha512-qAGmXrM32xUGdaCBmkQG8RIgm+8Oj22rURkAoX9HuKDQiM0Vm66QebkWEnU5nozYgPbO/PFPrPmerI6ZEPp8UQ==", - "dev": true, - "dependencies": { - "@types/common-tags": "^1.4.0", - "@types/debug": "^4.1.5", - "@types/node": "^10.17.28", - "@types/yargs": "^15.0.5", - "common-tags": "^1.7.2", - "cross-spawn": "^7.0.3", - "debug": "^4.1.1", - "dotenv": "^8.2.0", - "pkginfo": "^0.4.1", - "upath": "^1.2.0", - "yargs": "^15.4.1" - }, - "bin": { - "node-env-run": "dist/bin/node-env-run.js", - "nodenv": "dist/bin/node-env-run.js" - } - }, - "node_modules/node-env-run/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", - "dev": true - }, - "node_modules/node-env-run/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/node-env-run/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/node-env-run/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/node-env-run/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/node-env-run/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/node-env-run/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-get": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz", - "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==", - "dev": true - }, - "node_modules/object-to-spawn-args": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz", - "integrity": "sha512-d6xH8b+QdNj+cdndsL3rVCzwW9PqSSXQBDVj0d8fyaCqMimUEz+sW+Jtxp77bxaSs7C5w7XOH844FG7p2A0cFw==", - "dev": true - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-imports": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/parse-imports/-/parse-imports-2.2.1.tgz", - "integrity": "sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==", - "dev": true, - "dependencies": { - "es-module-lexer": "^1.5.3", - "slashes": "^3.0.12" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/path": { - "version": "0.12.7", - "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", - "integrity": "sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==", - "dev": true, - "dependencies": { - "process": "^0.11.1", - "util": "^0.10.3" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkginfo": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", - "integrity": "sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", - "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", - "dev": true, - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prismarine-nbt": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.6.0.tgz", - "integrity": "sha512-z65ijm6hVlYOmhg8IEzdYfUz1u3AOiQtzyTSAwD8NLBCr96ZUPtUH5o/6sGAoDaN+rkDe0DNBCiO7bvXXO1fkQ==", - "dependencies": { - "protodef": "^1.9.0" - } - }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/protodef": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/protodef/-/protodef-1.17.0.tgz", - "integrity": "sha512-mnpNPV3xwu63u3NwZuXM1RCp979vjHxUGHzVrb6dxbvof5Fx+b8Rs0G0c3xtEuFDreGAMWS7VrlNkDUDBMsFWQ==", - "dependencies": { - "lodash.get": "^4.4.2", - "lodash.reduce": "^4.6.0", - "protodef-validator": "^1.3.0", - "readable-stream": "^4.4.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/protodef-validator": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/protodef-validator/-/protodef-validator-1.3.1.tgz", - "integrity": "sha512-lZ5FWKZYR9xOjpMw1+EfZRfCjzNRQWPq+Dk+jki47Sikl2EeWEPnTfnJERwnU/EwFq6us+0zqHHzSsmLeYX+Lg==", - "dependencies": { - "ajv": "^6.5.4" - }, - "bin": { - "protodef-validator": "cli.js" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/readable-stream": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", - "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/reduce-extract": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz", - "integrity": "sha512-QF8vjWx3wnRSL5uFMyCjDeDc5EBMiryoT9tz94VvgjKfzecHAVnqmXAwQDcr7X4JmLc2cjkjFGCVzhMqDjgR9g==", - "dev": true, - "dependencies": { - "test-value": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reduce-extract/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/reduce-extract/node_modules/test-value": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz", - "integrity": "sha512-wrsbRo7qP+2Je8x8DsK8ovCGyxe3sYfQwOraIY/09A2gFXU9DYKiTF14W4ki/01AEh56kMzAmlj9CaHGDDUBJA==", - "dev": true, - "dependencies": { - "array-back": "^1.0.2", - "typical": "^2.4.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reduce-flatten": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz", - "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/reduce-unique": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz", - "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/reduce-without": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz", - "integrity": "sha512-zQv5y/cf85sxvdrKPlfcRzlDn/OqKFThNimYmsS3flmkioKvkUGn2Qg9cJVoQiEvdxFGLE0MQER/9fZ9sUqdxg==", - "dev": true, - "dependencies": { - "test-value": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/reduce-without/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/reduce-without/node_modules/test-value": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz", - "integrity": "sha512-+1epbAxtKeXttkGFMTX9H42oqzOTufR1ceCF+GYA5aOmvaPq9wd4PUS8329fn2RRLGNeUkgRLnVpycjx8DsO2w==", - "dev": true, - "dependencies": { - "array-back": "^1.0.3", - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true, - "engines": { - "node": ">=6.5.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/rss-parser": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.13.0.tgz", - "integrity": "sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==", - "dependencies": { - "entities": "^2.0.3", - "xml2js": "^0.5.0" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "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/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sax": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==" - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/skyhelper-networth": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/skyhelper-networth/-/skyhelper-networth-1.26.0.tgz", - "integrity": "sha512-QkBfMKt+tref6D3T+zmKzWwjJ135QEigXN/VpEmlD0FK0mJPSxuBxvnDYe3F9r3UyWpXVP7w6tge4s9tA8Hc1Q==", - "dependencies": { - "axios": "^1.6.2", - "prismarine-nbt": "^2.2.1" - }, - "funding": { - "type": "patreon", - "url": "https://patreon.com/skyhelper" - } - }, - "node_modules/slashes": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/slashes/-/slashes-3.0.12.tgz", - "integrity": "sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==", - "dev": true - }, - "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/sort-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz", - "integrity": "sha512-nZI3lq+nPRImxYqQY5iwpOPVLdDEMr2k6rCOAz5hRcpyYFsrR+2m5Kw0tZaTt452nx/9wZrKaMEMrX03I7ChqQ==", - "dev": true, - "dependencies": { - "array-back": "^1.0.4", - "object-get": "^2.1.0", - "typical": "^2.6.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sort-array/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", - "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stream-connect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz", - "integrity": "sha512-68Kl+79cE0RGKemKkhxTSg8+6AGrqBt+cbZAXevg2iJ6Y3zX4JhA/sZeGzLpxW9cXhmqAcE7KnJCisUmIUfnFQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "array-back": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stream-connect/node_modules/array-back": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz", - "integrity": "sha512-1WxbZvrmyhkNoeYcizokbmh5oiOCIfyvGtcqbK3Ls1v1fKcquzxnQSceOx6tzq7jmai2kFLWIpGND2cLhH6TPw==", - "dev": true, - "dependencies": { - "typical": "^2.6.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/stream-via": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz", - "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==", - "dev": true, - "engines": { - "node": ">=0.10.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/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table-layout": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz", - "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==", - "dev": true, - "dependencies": { - "array-back": "^2.0.0", - "deep-extend": "~0.6.0", - "lodash.padend": "^4.6.1", - "typical": "^2.6.1", - "wordwrapjs": "^3.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/table-layout/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/taffydb": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz", - "integrity": "sha512-y3JaeRSplks6NYQuCOj3ZFMO3j60rTwbuKCvZxsAraGYH2epusatvZ0baZYA01WsGqJBq/Dl6vOrMUJqyMj8kA==", - "dev": true - }, - "node_modules/temp-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz", - "integrity": "sha512-TvmyH7kC6ZVTYkqCODjJIbgvu0FKiwQpZ4D1aknE7xpcDf/qEOB8KZEK5ef2pfbVoiBhNWs3yx4y+ESMtNYmlg==", - "dev": true - }, - "node_modules/test-value": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz", - "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==", - "dev": true, - "dependencies": { - "array-back": "^2.0.0", - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/test-value/node_modules/array-back": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz", - "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==", - "dev": true, - "dependencies": { - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true - }, - "node_modules/tsubaki": { - "version": "1.3.14", - "resolved": "https://registry.npmjs.org/tsubaki/-/tsubaki-1.3.14.tgz", - "integrity": "sha512-FnrXnBkTVtfSGWWL74X1lON1DMKwQ0Q6lBVhliHSQLAF2fT9PEH/r+yvT9A1sQUbJ90I/klurOgp3fUkr+uphw==", - "dev": true, - "engines": { - "node": ">=6.0.0", - "npm": ">=6.0.0" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typical": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz", - "integrity": "sha512-ofhi8kjIje6npGozTip9Fr8iecmYfEbS06i0JnIg+rh51KakryWF4+jX8lLKZVhy6N+ID45WYSFCxPOdTWCzNg==", - "dev": true - }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/underscore": { - "version": "1.13.7", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", - "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", - "dev": true - }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "dev": true - }, - "node_modules/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true, - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "dev": true, - "dependencies": { - "inherits": "2.0.3" - } - }, - "node_modules/util/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", - "dev": true - }, - "node_modules/v8-compile-cache": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", - "integrity": "sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==", - "dev": true - }, - "node_modules/walk-back": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz", - "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==", - "dev": true, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true - }, - "node_modules/wordwrapjs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz", - "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==", - "dev": true, - "dependencies": { - "reduce-flatten": "^1.0.1", - "typical": "^2.6.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/wordwrapjs/node_modules/reduce-flatten": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz", - "integrity": "sha512-j5WfFJfc9CoXv/WbwVLHq74i/hdTUpy+iNC534LxczMRP67vJeK3V9JOdnL0N1cIRbn9mYhE2yVjvvKXDxvNXQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true - }, - "node_modules/wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/wrap-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/wrap-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/xml2js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", - "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", - "dependencies": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "dev": true, - "dependencies": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "dependencies": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-unparser/node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz", - "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/package.json b/package.json index 8e3be0f1b..1bff57b71 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "name": "hypixel-api-reborn", - "version": "11.3.7", + "version": "12.0.0-23", "description": "Feature-rich Hypixel API wrapper for Node.js", - "main": "./src/index.js", - "types": "./typings/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "module": "dist/index.js", "keywords": [ "minecraft", "client", @@ -16,41 +17,65 @@ "url": "https://github.com/Hypixel-API-Reborn/hypixel-api-reborn/issues" }, "scripts": { - "lint": "npx eslint src/", - "lint:fix": "npx eslint src/ --fix", - "tests": "npx mocha tests --exit --recursive", - "docgen": " npx docgen -s src/ --custom docs/index.yml -o ./master.json", - "prettier": "npx prettier --write src/ typings/", - "prettier:check": "npx prettier --check src/ typings/" + "eslint:check": "pnpm exec eslint . ", + "eslint": "pnpm eslint:check --fix", + "prettier:check": "pnpm exec prettier --check .", + "prettier": "pnpm exec prettier --write .", + "build": "pnpm exec tsc", + "test": "pnpm exec vitest run", + "test:generate": "pnpm exec tsx .github/scripts/generateBasicTests.ts", + "test:coverage": "pnpm exec vitest run --coverage", + "test:coverage:check": "pnpm exec tsx .github/scripts/checkCoverage.ts", + "test:ui": "pnpm exec vitest --ui --coverage", + "scripts:generate:index": "pnpm exec tsx .github/scripts/generateIndexFile.ts", + "scripts:generate:index:api": "pnpm exec tsx .github/scripts/generateAPIIndexFile.ts", + "docgen": "pnpm exec typedoc", + "prepare": "pnpm build" }, "engines": { - "node": ">=18.18.0" + "node": ">=20.19.5" }, - "author": "StavZ", + "type": "module", + "packageManager": "pnpm@9.7.1", + "author": "Kathund", "dependencies": { + "minecraft-data": "^3.102.3", "node-cache": "^5.1.2", - "node-fetch": "^3.3.2", - "prismarine-nbt": "^2.6.0", - "rss-parser": "^3.13.0", - "skyhelper-networth": "^1.26.0" + "prismarine-nbt": "^2.8.0", + "rss-parser": "^3.13.0" }, "license": "MIT", - "readme": "https://hypixel.stavzdev.me/", + "readme": "https://github.com/Hypixel-API-Reborn/hypixel-api-reborn?tab=readme-ov-file#hypixel-api-reborn", "repository": { - "url": "https://github.com/Hypixel-API-Reborn/hypixel-api-reborn" + "url": "git+https://github.com/Hypixel-API-Reborn/hypixel-api-reborn.git" }, - "publisher": "StavZ", + "files": [ + "dist/**/*" + ], + "publisher": "Kathund", "devDependencies": { - "@discordjs/docgen": "github:discordjs/docgen", - "@types/node": "^22.10.1", - "chai": "^4.3.4", - "eslint": "^9.16.0", - "eslint-plugin-jsdoc": "^50.6.0", - "globals": "^15.13.0", - "mocha": "^10.4.0", - "node-env-run": "^4.0.2", - "path": "^0.12.7", - "prettier": "^3.4.2", - "typescript": "^5.7.2" + "@8hobbies/typedoc-plugin-404": "^3.2.1", + "@eslint/js": "^9.39.2", + "@j4cobi/eslint-plugin-sort-imports": "^1.0.2", + "@stylistic/eslint-plugin": "^5.7.0", + "@types/eslint": "^9.6.1", + "@types/node": "^20.19.5", + "@types/xml2js": "^0.4.14", + "@vitest/coverage-v8": "^3.2.4", + "@vitest/ui": "^3.2.4", + "dotenv": "^17.2.3", + "eslint": "^9.39.2", + "eslint-config-prettier": "^10.1.8", + "eslint-plugin-import": "^2.32.0", + "globals": "^16.5.0", + "prettier": "^3.8.0", + "tsx": "^4.21.0", + "typedoc": "^0.27.9", + "typedoc-material-theme": "^1.4.1", + "typedoc-plugin-rename-defaults": "^0.7.3", + "typescript": "^5.9.3", + "typescript-eslint": "^8.53.0", + "vitest": "^3.2.4", + "xml2js": "^0.6.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 000000000..ef22b1a3c --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,4344 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + minecraft-data: + specifier: ^3.102.3 + version: 3.102.3 + node-cache: + specifier: ^5.1.2 + version: 5.1.2 + prismarine-nbt: + specifier: ^2.8.0 + version: 2.8.0 + rss-parser: + specifier: ^3.13.0 + version: 3.13.0 + devDependencies: + '@8hobbies/typedoc-plugin-404': + specifier: ^3.2.1 + version: 3.2.1(typedoc@0.27.9(typescript@5.9.3)) + '@eslint/js': + specifier: ^9.39.2 + version: 9.39.2 + '@j4cobi/eslint-plugin-sort-imports': + specifier: ^1.0.2 + version: 1.0.2(eslint@9.39.2)(typescript@5.9.3) + '@stylistic/eslint-plugin': + specifier: ^5.7.0 + version: 5.7.0(eslint@9.39.2) + '@types/eslint': + specifier: ^9.6.1 + version: 9.6.1 + '@types/node': + specifier: ^20.19.5 + version: 20.19.25 + '@types/xml2js': + specifier: ^0.4.14 + version: 0.4.14 + '@vitest/coverage-v8': + specifier: ^3.2.4 + version: 3.2.4(vitest@3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4)) + '@vitest/ui': + specifier: ^3.2.4 + version: 3.2.4(vitest@3.2.4) + dotenv: + specifier: ^17.2.3 + version: 17.2.3 + eslint: + specifier: ^9.39.2 + version: 9.39.2 + eslint-config-prettier: + specifier: ^10.1.8 + version: 10.1.8(eslint@9.39.2) + eslint-plugin-import: + specifier: ^2.32.0 + version: 2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2) + globals: + specifier: ^16.5.0 + version: 16.5.0 + prettier: + specifier: ^3.8.0 + version: 3.8.0 + tsx: + specifier: ^4.21.0 + version: 4.21.0 + typedoc: + specifier: ^0.27.9 + version: 0.27.9(typescript@5.9.3) + typedoc-material-theme: + specifier: ^1.4.1 + version: 1.4.1(typedoc@0.27.9(typescript@5.9.3)) + typedoc-plugin-rename-defaults: + specifier: ^0.7.3 + version: 0.7.3(typedoc@0.27.9(typescript@5.9.3)) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.53.0 + version: 8.53.0(eslint@9.39.2)(typescript@5.9.3) + vitest: + specifier: ^3.2.4 + version: 3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4) + xml2js: + specifier: ^0.6.2 + version: 0.6.2 + +packages: + + '@8hobbies/typedoc-plugin-404@3.2.1': + resolution: {integrity: sha512-0e4IDEcFfTap0b2PpTcxdyr3oCNE/1OgB1kLiG/Arz4tf5fjYlVDEKpun6wsHRZLBULf874kVSK1rAh4LR0vYg==} + engines: {node: ^20 || ^22 || >= 23} + peerDependencies: + typedoc: ^0.26.11 || ^0.27.2 + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.1': + resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.1': + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.2': + resolution: {integrity: sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@gerrit0/mini-shiki@1.27.2': + resolution: {integrity: sha512-GeWyHz8ao2gBiUW4OJnQDxXQnFgZQwwQk05t/CVVgNBN7/rK8XZ7xY6YhLVv9tH3VppWWmr9DCl3MwemB/i+Og==} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@j4cobi/eslint-plugin-sort-imports@1.0.2': + resolution: {integrity: sha512-0bTHYIohk2RnWW8+FQoE06s/80aF1iPxP62JiS2+9chUFrs9D7+p0niFtNctcZGRPo5aOKG9q/ypPlT8OWcwyg==} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@material/material-color-utilities@0.3.0': + resolution: {integrity: sha512-ztmtTd6xwnuh2/xu+Vb01btgV8SQWYCaK56CkRK8gEkWe5TuDyBcYJ0wgkMRn+2VcE9KUmhvkz+N9GHrqw/C0g==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/rollup-android-arm-eabi@4.37.0': + resolution: {integrity: sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.37.0': + resolution: {integrity: sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.37.0': + resolution: {integrity: sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.37.0': + resolution: {integrity: sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.37.0': + resolution: {integrity: sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.37.0': + resolution: {integrity: sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.37.0': + resolution: {integrity: sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.37.0': + resolution: {integrity: sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.37.0': + resolution: {integrity: sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.37.0': + resolution: {integrity: sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.37.0': + resolution: {integrity: sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': + resolution: {integrity: sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.37.0': + resolution: {integrity: sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.37.0': + resolution: {integrity: sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.37.0': + resolution: {integrity: sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.37.0': + resolution: {integrity: sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.37.0': + resolution: {integrity: sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.37.0': + resolution: {integrity: sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.37.0': + resolution: {integrity: sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.37.0': + resolution: {integrity: sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@shikijs/engine-oniguruma@1.29.2': + resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + + '@shikijs/types@1.29.2': + resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@stylistic/eslint-plugin@5.7.0': + resolution: {integrity: sha512-PsSugIf9ip1H/mWKj4bi/BlEoerxXAda9ByRFsYuwsmr6af9NxJL0AaiNXs8Le7R21QR5KMiD/KdxZZ71LjAxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=9.0.0' + + '@types/chai@5.2.2': + resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@20.19.25': + resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/xml2js@0.4.14': + resolution: {integrity: sha512-4YnrRemBShWRO2QjvUin8ESA41rH+9nQGLUGZV/1IDhi3SL9OhdpNC/MrulTWuptXKwhx/aDxE7toV0f/ypIXQ==} + + '@typescript-eslint/eslint-plugin@8.53.0': + resolution: {integrity: sha512-eEXsVvLPu8Z4PkFibtuFJLJOTAV/nPdgtSjkGoPpddpFk3/ym2oy97jynY6ic2m6+nc5M8SE1e9v/mHKsulcJg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.53.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.53.0': + resolution: {integrity: sha512-npiaib8XzbjtzS2N4HlqPvlpxpmZ14FjSJrteZpPxGUaYPlvhzlzUZ4mZyABo0EFrOWnvyd0Xxroq//hKhtAWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.53.0': + resolution: {integrity: sha512-Bl6Gdr7NqkqIP5yP9z1JU///Nmes4Eose6L1HwpuVHwScgDPPuEWbUVhvlZmb8hy0vX9syLk5EGNL700WcBlbg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.28.0': + resolution: {integrity: sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/scope-manager@8.53.0': + resolution: {integrity: sha512-kWNj3l01eOGSdVBnfAF2K1BTh06WS0Yet6JUgb9Cmkqaz3Jlu0fdVUjj9UI8gPidBWSMqDIglmEXifSgDT/D0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.53.0': + resolution: {integrity: sha512-K6Sc0R5GIG6dNoPdOooQ+KtvT5KCKAvTcY8h2rIuul19vxH5OTQk7ArKkd4yTzkw66WnNY0kPPzzcmWA+XRmiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.53.0': + resolution: {integrity: sha512-BBAUhlx7g4SmcLhn8cnbxoxtmS7hcq39xKCgiutL3oNx1TaIp+cny51s8ewnKMpVUKQUGb41RAUWZ9kxYdovuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.28.0': + resolution: {integrity: sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/types@8.53.0': + resolution: {integrity: sha512-Bmh9KX31Vlxa13+PqPvt4RzKRN1XORYSLlAE+sO1i28NkisGbTtSLFVB3l7PWdHtR3E0mVMuC7JilWJ99m2HxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.28.0': + resolution: {integrity: sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/typescript-estree@8.53.0': + resolution: {integrity: sha512-pw0c0Gdo7Z4xOG987u3nJ8akL9093yEEKv8QTJ+Bhkghj1xyj8cgPaavlr9rq8h7+s6plUJ4QJYw2gCZodqmGw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.28.0': + resolution: {integrity: sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.53.0': + resolution: {integrity: sha512-XDY4mXTez3Z1iRDI5mbRhH4DFSt46oaIFsLg+Zn97+sYrXACziXSQcSelMybnVZ5pa1P6xYkPr5cMJyunM1ZDA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.28.0': + resolution: {integrity: sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/visitor-keys@8.53.0': + resolution: {integrity: sha512-LZ2NqIHFhvFwxG0qZeLL9DvdNAHPGCY5dIRwBhyYeU+LfLhcStE1ImjsuTG/WaVh3XysGaeLW8Rqq7cGkPCFvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitest/coverage-v8@3.2.4': + resolution: {integrity: sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==} + peerDependencies: + '@vitest/browser': 3.2.4 + vitest: 3.2.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + + '@vitest/ui@3.2.4': + resolution: {integrity: sha512-hGISOaP18plkzbWEcP/QvtRW1xDXF2+96HbEX6byqQhAUbiS5oH6/9JwW+QsQCIYON2bI6QZBF+2PvOmrRZ9wA==} + peerDependencies: + vitest: 3.2.4 + + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-v8-to-istanbul@0.3.5: + resolution: {integrity: sha512-9SdXjNheSiE8bALAQCQQuT6fgQaoxJh7IRYrRGZ8/9nv8WhJeC1aXAwN8TbaOssGOukUvyvnkgD9+Yuykvl1aA==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@8.0.0: + resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} + engines: {node: '>=16'} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dotenv@17.2.3: + resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.0: + resolution: {integrity: sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.2: + resolution: {integrity: sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@11.0.0: + resolution: {integrity: sha512-+gMeWRrIh/NsG+3NaLeWHuyeyk70p2tbvZIWBYcqQ4/7Xvars6GYTZNhF1sIeLcc6Wb11He5ffz3hsHyXFrw5A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + expect-type@1.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.5.0: + resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.reduce@4.6.0: + resolution: {integrity: sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==} + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minecraft-data@3.102.3: + resolution: {integrity: sha512-JxUPTUlamQ04GSK7YI3657BRurHLBRAhsmPb4gajd4z/p6t3LJh4l0HWIyNHRpJbQiUCIjn+mhos5oB+yqH0mQ==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-cache@5.1.2: + resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} + engines: {node: '>= 8.0.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.8.0: + resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==} + engines: {node: '>=14'} + hasBin: true + + prismarine-nbt@2.8.0: + resolution: {integrity: sha512-5D6FUZq0PNtf3v/41ImDlwThVesOv5adyqCRMZLzmkUGEmRJNNh5C6AsnvrClBftXs+IF0yqPnZoj8kcNPiMGg==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + protodef-validator@1.4.0: + resolution: {integrity: sha512-2y2coBolqCEuk5Kc3QwO7ThR+/7TZiOit4FrpAgl+vFMvq8w76nDhh09z08e2NQOdrgPLsN2yzXsvRvtADgUZQ==} + hasBin: true + + protodef@1.18.0: + resolution: {integrity: sha512-jO64lkzkh0dYc0AVWCU/GzCKwqhFFIz1kfEz0NBf0RUuRNcmvgKbopabJdfZ6W8NvALdySUXgEhvKDZPhdBwrg==} + engines: {node: '>=14'} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.37.0: + resolution: {integrity: sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rss-parser@3.13.0: + resolution: {integrity: sha512-7jWUBV5yGN3rqMMj7CZufl/291QAhvrrGpDNE4k/02ZchL0npisiYYqULF71jCEKoIiHvK/Q2e6IkDwPziT7+w==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@3.0.0: + resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.3: + resolution: {integrity: sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==} + engines: {node: '>=14.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-api-utils@2.4.0: + resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typedoc-material-theme@1.4.1: + resolution: {integrity: sha512-/inKZw8SqZPt+pmawpMhDmXCJQyIm+fHFuGChioyJQICZcX2FyzpwZnyPWcZHmJ09upttWFhti4ZI3hESJNkSA==} + engines: {node: '>=18.0.0', npm: '>=8.6.0'} + peerDependencies: + typedoc: ^0.25.13 || ^0.26.x || ^0.27.x || ^0.28.x + + typedoc-plugin-rename-defaults@0.7.3: + resolution: {integrity: sha512-fDtrWZ9NcDfdGdlL865GW7uIGQXlthPscURPOhDkKUe4DBQSRRFUf33fhWw41FLlsz8ZTeSxzvvuNmh54MynFA==} + peerDependencies: + typedoc: '>=0.22.x <0.29.x' + + typedoc@0.27.9: + resolution: {integrity: sha512-/z585740YHURLl9DN2jCWe6OW7zKYm6VoQ93H0sxZ1cwHQEQrUn5BJrEnkWhfzUdyO+BLGjnKUZ9iz9hKloFDw==} + engines: {node: '>= 18'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x + + typescript-eslint@8.53.0: + resolution: {integrity: sha512-xHURCQNxZ1dsWn0sdOaOfCSQG0HKeqSj9OexIxrz6ypU6wHYOdX2I3D2b8s8wFSsSOYJb+6q283cLiLlkEsBYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite@5.4.15: + resolution: {integrity: sha512-6ANcZRivqL/4WtwPGTKNaosuNJr5tWiftOC7liM7G9+rMb8+oeJeyzymDu4rTN93seySBmbjSfsS3Vzr19KNtA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@8hobbies/typedoc-plugin-404@3.2.1(typedoc@0.27.9(typescript@5.9.3))': + dependencies: + typedoc: 0.27.9(typescript@5.9.3) + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@babel/types@7.27.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@1.0.2': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.27.2': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.27.2': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.27.2': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.27.2': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.27.2': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.27.2': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.27.2': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.27.2': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.27.2': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.27.2': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.27.2': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.27.2': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.27.2': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.27.2': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.27.2': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.27.2': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.27.2': + optional: true + + '@esbuild/netbsd-arm64@0.27.2': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.27.2': + optional: true + + '@esbuild/openbsd-arm64@0.27.2': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.27.2': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.27.2': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.27.2': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.27.2': + optional: true + + '@eslint-community/eslint-utils@4.9.0(eslint@9.39.2)': + dependencies: + eslint: 9.39.2 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.2)': + dependencies: + eslint: 9.39.2 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.1': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.1': + dependencies: + ajv: 6.12.6 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.2': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@gerrit0/mini-shiki@1.27.2': + dependencies: + '@shikijs/engine-oniguruma': 1.29.2 + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@j4cobi/eslint-plugin-sort-imports@1.0.2(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/utils': 8.28.0(eslint@9.39.2)(typescript@5.9.3) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@material/material-color-utilities@0.3.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@1.0.0-next.28': {} + + '@rollup/rollup-android-arm-eabi@4.37.0': + optional: true + + '@rollup/rollup-android-arm64@4.37.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.37.0': + optional: true + + '@rollup/rollup-darwin-x64@4.37.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.37.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.37.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.37.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.37.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.37.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.37.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.37.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.37.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.37.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.37.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.37.0': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@shikijs/engine-oniguruma@1.29.2': + dependencies: + '@shikijs/types': 1.29.2 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/types@1.29.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@stylistic/eslint-plugin@5.7.0(eslint@9.39.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@typescript-eslint/types': 8.53.0 + eslint: 9.39.2 + eslint-visitor-keys: 5.0.0 + espree: 11.0.0 + estraverse: 5.3.0 + picomatch: 4.0.3 + + '@types/chai@5.2.2': + dependencies: + '@types/deep-eql': 4.0.2 + + '@types/deep-eql@4.0.2': {} + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.6': {} + + '@types/estree@1.0.7': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@20.19.25': + dependencies: + undici-types: 6.21.0 + + '@types/unist@3.0.3': {} + + '@types/xml2js@0.4.14': + dependencies: + '@types/node': 20.19.25 + + '@typescript-eslint/eslint-plugin@8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/type-utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 + eslint: 9.39.2 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.53.0 + debug: 4.4.3 + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.53.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.28.0': + dependencies: + '@typescript-eslint/types': 8.28.0 + '@typescript-eslint/visitor-keys': 8.28.0 + + '@typescript-eslint/scope-manager@8.53.0': + dependencies: + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 + + '@typescript-eslint/tsconfig-utils@8.53.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.2 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.28.0': {} + + '@typescript-eslint/types@8.53.0': {} + + '@typescript-eslint/typescript-estree@8.28.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.28.0 + '@typescript-eslint/visitor-keys': 8.28.0 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.53.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.53.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.53.0(typescript@5.9.3) + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/visitor-keys': 8.53.0 + debug: 4.4.3 + minimatch: 9.0.5 + semver: 7.7.3 + tinyglobby: 0.2.15 + ts-api-utils: 2.4.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.28.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) + '@typescript-eslint/scope-manager': 8.28.0 + '@typescript-eslint/types': 8.28.0 + '@typescript-eslint/typescript-estree': 8.28.0(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.53.0(eslint@9.39.2)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.2) + '@typescript-eslint/scope-manager': 8.53.0 + '@typescript-eslint/types': 8.53.0 + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.28.0': + dependencies: + '@typescript-eslint/types': 8.28.0 + eslint-visitor-keys: 4.2.1 + + '@typescript-eslint/visitor-keys@8.53.0': + dependencies: + '@typescript-eslint/types': 8.53.0 + eslint-visitor-keys: 4.2.1 + + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + ast-v8-to-istanbul: 0.3.5 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.9.0 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.2 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.4(vite@5.4.15(@types/node@20.19.25))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 5.4.15(@types/node@20.19.25) + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.0.0 + + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.17 + pathe: 2.0.3 + + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.3 + + '@vitest/ui@3.2.4(vitest@3.2.4)': + dependencies: + '@vitest/utils': 3.2.4 + fflate: 0.8.2 + flatted: 3.3.3 + pathe: 2.0.3 + sirv: 3.0.1 + tinyglobby: 0.2.15 + tinyrainbow: 2.0.0 + vitest: 3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4) + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + acorn-jsx@5.3.2(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + assertion-error@2.0.1: {} + + ast-v8-to-istanbul@0.3.5: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 9.0.1 + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase@8.0.0: {} + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + check-error@2.1.1: {} + + clone@2.1.2: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dotenv@17.2.3: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@2.2.0: {} + + entities@4.5.0: {} + + es-abstract@1.24.0: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.1.8(eslint@9.39.2): + dependencies: + eslint: 9.39.2 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + eslint: 9.39.2 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.2 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.2) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.0: {} + + eslint@9.39.2: + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.2) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.21.1 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.39.2 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.7 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 + + espree@11.0.0: + dependencies: + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 5.0.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + esutils@2.0.3: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + expect-type@1.2.2: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fflate@0.8.2: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globals@14.0.0: {} + + globals@16.5.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@9.0.1: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.get@4.4.2: {} + + lodash.merge@4.6.2: {} + + lodash.reduce@4.6.0: {} + + loupe@3.1.3: {} + + loupe@3.2.1: {} + + lru-cache@10.4.3: {} + + lunr@2.3.9: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.1 + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minecraft-data@3.102.3: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mrmime@2.0.1: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-cache@5.1.2: + dependencies: + clone: 2.1.2 + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@2.0.3: {} + + pathval@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + picomatch@4.0.3: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.0: {} + + prismarine-nbt@2.8.0: + dependencies: + protodef: 1.18.0 + + process@0.11.10: {} + + protodef-validator@1.4.0: + dependencies: + ajv: 6.12.6 + + protodef@1.18.0: + dependencies: + lodash.get: 4.4.2 + lodash.reduce: 4.6.0 + protodef-validator: 1.4.0 + readable-stream: 4.7.0 + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rollup@4.37.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.37.0 + '@rollup/rollup-android-arm64': 4.37.0 + '@rollup/rollup-darwin-arm64': 4.37.0 + '@rollup/rollup-darwin-x64': 4.37.0 + '@rollup/rollup-freebsd-arm64': 4.37.0 + '@rollup/rollup-freebsd-x64': 4.37.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.37.0 + '@rollup/rollup-linux-arm-musleabihf': 4.37.0 + '@rollup/rollup-linux-arm64-gnu': 4.37.0 + '@rollup/rollup-linux-arm64-musl': 4.37.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.37.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.37.0 + '@rollup/rollup-linux-riscv64-gnu': 4.37.0 + '@rollup/rollup-linux-riscv64-musl': 4.37.0 + '@rollup/rollup-linux-s390x-gnu': 4.37.0 + '@rollup/rollup-linux-x64-gnu': 4.37.0 + '@rollup/rollup-linux-x64-musl': 4.37.0 + '@rollup/rollup-win32-arm64-msvc': 4.37.0 + '@rollup/rollup-win32-ia32-msvc': 4.37.0 + '@rollup/rollup-win32-x64-msvc': 4.37.0 + fsevents: 2.3.3 + + rss-parser@3.13.0: + dependencies: + entities: 2.2.0 + xml2js: 0.5.0 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + sax@1.4.1: {} + + semver@6.3.1: {} + + semver@7.7.1: {} + + semver@7.7.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + sirv@3.0.1: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.1 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.9.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + strip-literal@3.0.0: + dependencies: + js-tokens: 9.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.3: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + ts-api-utils@2.1.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-api-utils@2.4.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tsx@4.21.0: + dependencies: + esbuild: 0.27.2 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typedoc-material-theme@1.4.1(typedoc@0.27.9(typescript@5.9.3)): + dependencies: + '@material/material-color-utilities': 0.3.0 + typedoc: 0.27.9(typescript@5.9.3) + + typedoc-plugin-rename-defaults@0.7.3(typedoc@0.27.9(typescript@5.9.3)): + dependencies: + camelcase: 8.0.0 + typedoc: 0.27.9(typescript@5.9.3) + + typedoc@0.27.9(typescript@5.9.3): + dependencies: + '@gerrit0/mini-shiki': 1.27.2 + lunr: 2.3.9 + markdown-it: 14.1.0 + minimatch: 9.0.5 + typescript: 5.9.3 + yaml: 2.8.1 + + typescript-eslint@8.53.0(eslint@9.39.2)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.53.0(@typescript-eslint/parser@8.53.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/parser': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.53.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.53.0(eslint@9.39.2)(typescript@5.9.3) + eslint: 9.39.2 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + vite-node@3.2.4(@types/node@20.19.25): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 5.4.15(@types/node@20.19.25) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.15(@types/node@20.19.25): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.37.0 + optionalDependencies: + '@types/node': 20.19.25 + fsevents: 2.3.3 + + vitest@3.2.4(@types/node@20.19.25)(@vitest/ui@3.2.4): + dependencies: + '@types/chai': 5.2.2 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@5.4.15(@types/node@20.19.25)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.2.0 + debug: 4.4.3 + expect-type: 1.2.2 + magic-string: 0.30.17 + pathe: 2.0.3 + picomatch: 4.0.2 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 5.4.15(@types/node@20.19.25) + vite-node: 3.2.4(@types/node@20.19.25) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.19.25 + '@vitest/ui': 3.2.4(vitest@3.2.4) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + xml2js@0.5.0: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xml2js@0.6.2: + dependencies: + sax: 1.4.1 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + yaml@2.8.1: {} + + yocto-queue@0.1.0: {} diff --git a/src/API/getAPIStatus.js b/src/API/getAPIStatus.js deleted file mode 100644 index dacf897ba..000000000 --- a/src/API/getAPIStatus.js +++ /dev/null @@ -1,8 +0,0 @@ -const Rss = require('rss-parser'); -const Parser = new Rss(); -module.exports = async function (options) { - const Status = require('../structures/APIStatus.js'); - const parsed = await Parser.parseURL('https://status.hypixel.net/history.rss'); - if (options && options.raw) return parsed; - return new Status(parsed); -}; diff --git a/src/API/getAchievements.js b/src/API/getAchievements.js deleted file mode 100644 index 392aac51e..000000000 --- a/src/API/getAchievements.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const Achievements = require('../structures/Static/Achievements'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/achievements'); - if (res.raw) return res; - return new Achievements(res); -}; diff --git a/src/API/getAchievements.test.ts b/src/API/getAchievements.test.ts new file mode 100644 index 000000000..c53591a3a --- /dev/null +++ b/src/API/getAchievements.test.ts @@ -0,0 +1,108 @@ +import Achievements from '../Structures/Static/Achievements/Achievements.js'; +import Client from '../Client.js'; +import GameAchievements from '../Structures/Static/Achievements/GameAchievements.js'; +import OneTimeAchievement from '../Structures/Static/Achievements/OneTimeAchievement.js'; +import RequestData from '../Private/RequestData.js'; +import TieredAchievement from '../Structures/Static/Achievements/TieredAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { AchievementTier } from '../Types/Static.js'; + +test('getAchievements (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getAchievements({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getAchievements', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getAchievements(); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Achievements); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.achievementsPerGame).toBeDefined(); + expectTypeOf(data.achievementsPerGame).toEqualTypeOf>(); + Object.keys(data.achievementsPerGame).forEach((game) => { + const gameData = data.achievementsPerGame[game]; + if (!gameData) return; + expect(gameData).toBeDefined(); + expect(gameData).toBeInstanceOf(GameAchievements); + expectTypeOf(gameData).toEqualTypeOf(); + expect(gameData.game).toBeDefined(); + expectTypeOf(gameData.game).toEqualTypeOf(); + expect(gameData.points).toBeDefined(); + expect(gameData.points).toBeGreaterThanOrEqual(0); + expectTypeOf(gameData.points).toEqualTypeOf(); + expect(gameData.legacyPoints).toBeDefined(); + expect(gameData.legacyPoints).toBeGreaterThanOrEqual(0); + expectTypeOf(gameData.legacyPoints).toEqualTypeOf(); + expect(gameData.oneTimeAchievements).toBeDefined(); + expectTypeOf(gameData.oneTimeAchievements).toEqualTypeOf(); + gameData.oneTimeAchievements.forEach((achievement) => { + expect(achievement.codeName).toBeDefined(); + expectTypeOf(achievement.codeName).toEqualTypeOf(); + expect(achievement.name).toBeDefined(); + expectTypeOf(achievement.name).toEqualTypeOf(); + expect(achievement.description).toBeDefined(); + expectTypeOf(achievement.description).toEqualTypeOf(); + expect(achievement.secret).toBeDefined(); + expectTypeOf(achievement.secret).toEqualTypeOf(); + expect(achievement.legacy).toBeDefined(); + expectTypeOf(achievement.legacy).toEqualTypeOf(); + expect(achievement.points).toBeDefined(); + expectTypeOf(achievement.points).toEqualTypeOf(); + expect(achievement.gamePercentUnlocked).toBeDefined(); + expectTypeOf(achievement.gamePercentUnlocked).toEqualTypeOf(); + expect(achievement.globalPercentUnlocked).toBeDefined(); + expectTypeOf(achievement.globalPercentUnlocked).toEqualTypeOf(); + expect(achievement.toString()).toBeDefined(); + expect(achievement.toString()).toBe(achievement.codeName); + expectTypeOf(achievement.toString()).toEqualTypeOf(); + }); + expect(gameData.tieredAchievements).toBeDefined(); + expectTypeOf(gameData.tieredAchievements).toEqualTypeOf(); + gameData.tieredAchievements.forEach((achievement) => { + expect(achievement.codeName).toBeDefined(); + expectTypeOf(achievement.codeName).toEqualTypeOf(); + expect(achievement.name).toBeDefined(); + expectTypeOf(achievement.name).toEqualTypeOf(); + expect(achievement.description).toBeDefined(); + expectTypeOf(achievement.description).toEqualTypeOf(); + expect(achievement.secret).toBeDefined(); + expectTypeOf(achievement.secret).toEqualTypeOf(); + expect(achievement.legacy).toBeDefined(); + expectTypeOf(achievement.legacy).toEqualTypeOf(); + expect(achievement.tiers).toBeDefined(); + expectTypeOf(achievement.tiers).toEqualTypeOf(); + achievement.tiers.forEach((tier) => { + expect(tier).toBeDefined(); + expectTypeOf(tier).toEqualTypeOf(); + expect(tier.tier).toBeDefined(); + expect(tier.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(tier.tier).toEqualTypeOf(); + expect(tier.points).toBeDefined(); + expect(tier.points).toBeGreaterThanOrEqual(0); + expectTypeOf(tier.points).toEqualTypeOf(); + expect(tier.amount).toBeDefined(); + expect(tier.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(tier.amount).toEqualTypeOf(); + }); + expect(achievement.toString()).toBeDefined(); + expect(achievement.toString()).toBe(achievement.codeName); + expectTypeOf(achievement.toString()).toEqualTypeOf(); + }); + }); + client.destroy(); +}); diff --git a/src/API/getAchievements.ts b/src/API/getAchievements.ts new file mode 100644 index 000000000..86879ff2e --- /dev/null +++ b/src/API/getAchievements.ts @@ -0,0 +1,14 @@ +import Achievements from '../Structures/Static/Achievements/Achievements.js'; +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getAchievements extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/achievements', options); + if (res.options.raw) return res; + return new Achievements(res.data); + } +} + +export default getAchievements; diff --git a/src/API/getActiveHouses.test.ts b/src/API/getActiveHouses.test.ts new file mode 100644 index 000000000..2b4040912 --- /dev/null +++ b/src/API/getActiveHouses.test.ts @@ -0,0 +1,49 @@ +import Client from '../Client.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getActiveHouses (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getActiveHouses({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getActiveHouses', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getActiveHouses(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((house: House) => { + expect(house).toBeDefined(); + expect(house).toBeInstanceOf(House); + expectTypeOf(house).toEqualTypeOf(); + expect(house.name).toBeDefined(); + expectTypeOf(house.name).toEqualTypeOf(); + expect(house.uuid).toBeDefined(); + expectTypeOf(house.uuid).toEqualTypeOf(); + expect(house.owner).toBeDefined(); + expectTypeOf(house.owner).toEqualTypeOf(); + expect(house.createdAtTimestamp).toBeDefined(); + expectTypeOf(house.createdAtTimestamp).toEqualTypeOf(); + expect(house.createdAt).toBeDefined(); + expectTypeOf(house.createdAt).toEqualTypeOf(); + expect(house.players).toBeDefined(); + expectTypeOf(house.players).toEqualTypeOf(); + expect(house.cookies).toBeDefined(); + expectTypeOf(house.cookies).toEqualTypeOf(); + expect(house.toString()).toBeDefined(); + expectTypeOf(house.toString()).toEqualTypeOf(); + expect(house.toString()).toBe(house.name); + }); + client.destroy(); +}); diff --git a/src/API/getActiveHouses.ts b/src/API/getActiveHouses.ts new file mode 100644 index 000000000..503cea5f5 --- /dev/null +++ b/src/API/getActiveHouses.ts @@ -0,0 +1,20 @@ +import Endpoint from '../Private/Endpoint.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getActiveHouses extends Endpoint { + override async execute(options?: RequestOptions): Promise | RequestData> { + const res = await this.client.requestHandler.request('/housing/active', options); + if (res.options.raw) return res; + const houses = res.data.map((b: any) => new House(b)); + return Object.assign(houses, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getActiveHouses; diff --git a/src/API/getBoosters.js b/src/API/getBoosters.js deleted file mode 100644 index 0660ca845..000000000 --- a/src/API/getBoosters.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const Booster = require('../structures/Boosters/Booster'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/boosters'); - if (res.raw) return res; - return res.boosters.length ? res.boosters.map((b) => new Booster(b)).reverse() : []; -}; diff --git a/src/API/getBoosters.test.ts b/src/API/getBoosters.test.ts new file mode 100644 index 000000000..f33901a85 --- /dev/null +++ b/src/API/getBoosters.test.ts @@ -0,0 +1,79 @@ +import Booster from '../Structures/Boosters/Booster.js'; +import Client from '../Client.js'; +import Game from '../Structures/Game.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; +import type { WithRaw } from '../Types/API.js'; + +test('getBoosters (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getBoosters({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getBoosters', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getBoosters(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((booster: Booster) => { + expect(booster).toBeDefined(); + expect(booster).toBeInstanceOf(Booster); + expectTypeOf(booster).toEqualTypeOf(); + expect(booster.purchaser).toBeDefined(); + expectTypeOf(booster.purchaser).toEqualTypeOf(); + expect(booster.amount).toBeDefined(); + expectTypeOf(booster.amount).toEqualTypeOf(); + expect(booster.originalLength).toBeDefined(); + expectTypeOf(booster.originalLength).toEqualTypeOf(); + expect(booster.remaining).toBeDefined(); + expectTypeOf(booster.remaining).toEqualTypeOf(); + expect(booster.activatedTimestamp).toBeDefined(); + expectTypeOf(booster.activatedTimestamp).toEqualTypeOf(); + expect(booster.activated).toBeDefined(); + expectTypeOf(booster.activated).toEqualTypeOf(); + expect(booster.game).toBeDefined(); + expectTypeOf(booster.game).toEqualTypeOf(); + expect(booster.game).toBeDefined(); + expectTypeOf(booster.game).toEqualTypeOf(); + expect(booster.game.game).toBeDefined(); + expectTypeOf(booster.game.game).toEqualTypeOf(); + expect(booster.game.id).toBeDefined(); + expectTypeOf(booster.game.id).toEqualTypeOf(); + expect(booster.game.code).toBeDefined(); + expectTypeOf(booster.game.code).toEqualTypeOf(); + expect(booster.game.name).toBeDefined(); + expectTypeOf(booster.game.name).toEqualTypeOf(); + expect(booster.game.found).toBeDefined(); + expectTypeOf(booster.game.found).toEqualTypeOf(); + expect(booster.game.toString()).toBeDefined(); + expect(booster.game.toString()).toBe(booster.game.name); + expectTypeOf(booster.game.toString()).toEqualTypeOf(); + expect(Game.IDS).toBeDefined(); + expectTypeOf(Game.IDS).toEqualTypeOf(); + expect(Game.CODES).toBeDefined(); + expectTypeOf(Game.CODES).toEqualTypeOf(); + expect(Game.NAMES).toBeDefined(); + expectTypeOf(Game.NAMES).toEqualTypeOf(); + expect(booster.isActive).toBeDefined(); + expectTypeOf(booster.isActive).toEqualTypeOf(); + expect(booster.type).toBeDefined(); + expectTypeOf(booster.type).toEqualTypeOf<'STACKED' | 'QUEUED' | 'ACTIVE'>(); + expect(booster.stackers).toBeDefined(); + expectTypeOf(booster.stackers).toEqualTypeOf(); + expect(booster.expired).toBeDefined(); + expectTypeOf(booster.expired).toEqualTypeOf(); + expect(booster.toString()).toBeDefined(); + expectTypeOf(booster.toString()).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getBoosters.ts b/src/API/getBoosters.ts new file mode 100644 index 000000000..64ddb84e9 --- /dev/null +++ b/src/API/getBoosters.ts @@ -0,0 +1,20 @@ +import Booster from '../Structures/Boosters/Booster.js'; +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getBoosters extends Endpoint { + override async execute(options?: RequestOptions): Promise | RequestData> { + const res = await this.client.requestHandler.request('/boosters', options); + if (res.options.raw) return res; + const boosters = res.data.boosters.map((b: any) => new Booster(b)).reverse(); + return Object.assign(boosters, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getBoosters; diff --git a/src/API/getChallenges.js b/src/API/getChallenges.js deleted file mode 100644 index dc0d79489..000000000 --- a/src/API/getChallenges.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const Challenges = require('../structures/Static/Challenges'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/challenges'); - if (res.raw) return res; - return new Challenges(res); -}; diff --git a/src/API/getChallenges.test.ts b/src/API/getChallenges.test.ts new file mode 100644 index 000000000..d03a9c86f --- /dev/null +++ b/src/API/getChallenges.test.ts @@ -0,0 +1,55 @@ +import Challenge from '../Structures/Static/Challenge.js'; +import Challenges from '../Structures/Static/Challenges.js'; +import Client from '../Client.js'; +import GameChallenges from '../Structures/Static/GameChallenges.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ChallengeReward } from '../Types/Static.js'; + +test('getChallenges (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getChallenges({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getChallenges', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getChallenges(); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Challenges); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThan(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.challengesPerGame).toBeDefined(); + expectTypeOf(data.challengesPerGame).toEqualTypeOf>(); + Object.keys(data.challengesPerGame).forEach((gameName) => { + if (undefined === data.challengesPerGame[gameName]) return; + expect(data.challengesPerGame[gameName]).toBeDefined(); + expect(data.challengesPerGame[gameName]).toBeInstanceOf(GameChallenges); + expectTypeOf(data.challengesPerGame[gameName]).toEqualTypeOf(); + expect(data.challengesPerGame[gameName].category).toBeDefined(); + expect(data.challengesPerGame[gameName].category).toEqual(gameName); + expect(data.challengesPerGame[gameName].challenges).toBeDefined(); + expectTypeOf(data.challengesPerGame[gameName].challenges).toEqualTypeOf(); + data.challengesPerGame[gameName].challenges.forEach((challenge: Challenge) => { + expect(challenge.id).toBeDefined(); + expectTypeOf(challenge.id).toEqualTypeOf(); + expect(challenge.name).toBeDefined(); + expectTypeOf(challenge.name).toEqualTypeOf(); + expect(challenge.rewards).toBeDefined(); + expectTypeOf(challenge.rewards).toEqualTypeOf(); + }); + }); + client.destroy(); +}); diff --git a/src/API/getChallenges.ts b/src/API/getChallenges.ts new file mode 100644 index 000000000..4fd0b2680 --- /dev/null +++ b/src/API/getChallenges.ts @@ -0,0 +1,13 @@ +import Challenges from '../Structures/Static/Challenges.js'; +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getChallenges extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/challenges', options); + if (res.options.raw) return res; + return new Challenges(res.data); + } +} +export default getChallenges; diff --git a/src/API/getGameCounts.js b/src/API/getGameCounts.js deleted file mode 100644 index 3378f40d2..000000000 --- a/src/API/getGameCounts.js +++ /dev/null @@ -1,7 +0,0 @@ -const GameCounts = require('../structures/GameCounts'); -module.exports = async function () { - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/counts'); - if (res.raw) return res; - return new GameCounts(res); -}; diff --git a/src/API/getGameCounts.test.ts b/src/API/getGameCounts.test.ts new file mode 100644 index 000000000..f5854e8d1 --- /dev/null +++ b/src/API/getGameCounts.test.ts @@ -0,0 +1,32 @@ +import Client from '../Client.js'; +import GameCounts from '../Structures/Static/GameCounts/GameCounts.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getGameCounts (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGameCounts({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + if (data.isRaw()) return; + client.destroy(); +}); + +test('getGameCounts', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGameCounts(); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCounts); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.playerCount).toBeDefined(); + expectTypeOf(data.playerCount).toEqualTypeOf(); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getGameCounts.ts b/src/API/getGameCounts.ts new file mode 100644 index 000000000..bacc2b892 --- /dev/null +++ b/src/API/getGameCounts.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import GameCounts from '../Structures/Static/GameCounts/GameCounts.ts'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getGameCounts extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/counts', options); + if (res.options.raw) return res; + return new GameCounts(res.data); + } +} + +export default getGameCounts; diff --git a/src/API/getGuild.js b/src/API/getGuild.js deleted file mode 100644 index fa28b0704..000000000 --- a/src/API/getGuild.js +++ /dev/null @@ -1,19 +0,0 @@ -const Errors = require('../Errors'); -const toUuid = require('../utils/toUuid'); -const isGuildID = require('../utils/isGuildID'); -module.exports = async function (searchParameter, query) { - if (!query) throw new Error(Errors.NO_GUILD_QUERY); - const Guild = require('../structures/Guild/Guild'); - if ('id' === searchParameter && !isGuildID(query)) throw new Error(Errors.INVALID_GUILD_ID); - const isPlayerQuery = 'player' === searchParameter; - if (isPlayerQuery) query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - if (!['id', 'name', 'player'].includes(searchParameter)) throw new Error(Errors.INVALID_GUILD_SEARCH_PARAMETER); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/guild?${searchParameter}=${encodeURI(query)}`); - if (res.raw) return res; - if (!res.guild && 'player' !== searchParameter) { - throw new Error(Errors.GUILD_DOES_NOT_EXIST); - } - - return res.guild ? new Guild(res.guild, isPlayerQuery ? query : null) : null; -}; diff --git a/src/API/getGuild.test.ts b/src/API/getGuild.test.ts new file mode 100644 index 000000000..bc3a3d5f3 --- /dev/null +++ b/src/API/getGuild.test.ts @@ -0,0 +1,608 @@ +import Client from '../Client.js'; +import Color from '../Structures/Color.js'; +import Errors from '../Errors.js'; +import Game from '../Structures/Game.js'; +import Guild from '../Structures/Guild/Guild.js'; +import GuildMember from '../Structures/Guild/GuildMember.js'; +import GuildRank from '../Structures/Guild/GuildRank.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorCode, ColorHex, ColorString, InGameCode } from '../Types/Color.js'; +import type { ExpHistory } from '../Types/Guild.js'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; + +test('Invalid Guild Type', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getGuild('invalid', 'invalid')).rejects.toThrowError(Errors.INVALID_GUILD_SEARCH_PARAMETER); + client.destroy(); +}); + +test('Invalid Guild', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getGuild('name', 'this guild dose not exist')).rejects.toThrowError( + Errors.GUILD_DOES_NOT_EXIST + ); + client.destroy(); +}); + +test('Invalid Guild ID', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getGuild('id', 'invalid guild id')).rejects.toThrowError(Errors.INVALID_GUILD_ID); + client.destroy(); +}); + +test('No Guild Query', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getGuild('id')).rejects.toThrowError(Errors.NO_GUILD_QUERY); + client.destroy(); +}); + +test('User not in a guild', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuild('player', '37501e7512b845ab8796e2baf9e9677a'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + client.destroy(); +}); + +test('getGuild (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuild('name', 'Pixelic', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + if (data === null) return; + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getGuild (Name)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuild('name', 'Pixelic'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Guild); + expectTypeOf(data).toEqualTypeOf(); + if (data === null) return; + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + data.members.forEach((member: GuildMember) => { + expect(member).toBeDefined(); + expectTypeOf(member).toEqualTypeOf(); + expect(member.uuid).toBeDefined(); + expectTypeOf(member.uuid).toEqualTypeOf(); + expect(member.joinedAtTimestamp).toBeDefined(); + expectTypeOf(member.joinedAtTimestamp).toEqualTypeOf(); + expect(member.joinedAt).toBeDefined(); + expectTypeOf(member.joinedAt).toEqualTypeOf(); + expect(member.questParticipation).toBeDefined(); + expectTypeOf(member.questParticipation).toEqualTypeOf(); + expect(member.rank).toBeDefined(); + expectTypeOf(member.rank).toEqualTypeOf(); + expect(member.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(member.mutedUntilTimestamp).toEqualTypeOf(); + expect(member.mutedUntil).toBeDefined(); + expectTypeOf(member.mutedUntil).toEqualTypeOf(); + expect(member.expHistory).toBeDefined(); + expectTypeOf(member.expHistory).toEqualTypeOf(); + expect(member.weeklyExperience).toBeDefined(); + expectTypeOf(member.weeklyExperience).toEqualTypeOf(); + expect(member.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(member.toString()).toBeDefined(); + expectTypeOf(member.toString()).toEqualTypeOf(); + expect(member.toString()).toEqual(member.uuid); + }); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + if (data.me !== null) { + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.me.uuid).toBeDefined(); + expectTypeOf(data.me.uuid).toEqualTypeOf(); + expect(data.me.joinedAtTimestamp).toBeDefined(); + expectTypeOf(data.me.joinedAtTimestamp).toEqualTypeOf(); + expect(data.me.joinedAt).toBeDefined(); + expectTypeOf(data.me.joinedAt).toEqualTypeOf(); + expect(data.me.questParticipation).toBeDefined(); + expectTypeOf(data.me.questParticipation).toEqualTypeOf(); + expect(data.me.rank).toBeDefined(); + expectTypeOf(data.me.rank).toEqualTypeOf(); + expect(data.me.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(data.me.mutedUntilTimestamp).toEqualTypeOf(); + expect(data.me.mutedUntil).toBeDefined(); + expectTypeOf(data.me.mutedUntil).toEqualTypeOf(); + expect(data.me.expHistory).toBeDefined(); + expectTypeOf(data.me.expHistory).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeDefined(); + expectTypeOf(data.me.weeklyExperience).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(data.me.toString()).toBeDefined(); + expectTypeOf(data.me.toString()).toEqualTypeOf(); + expect(data.me.toString()).toEqual(data.me.uuid); + } + expect(data.ranks).toBeDefined(); + expectTypeOf(data.ranks).toEqualTypeOf(); + data.ranks.forEach((rank: GuildRank) => { + expect(rank).toBeDefined(); + expect(rank).toBeInstanceOf(GuildRank); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank.name).toBeDefined(); + expectTypeOf(rank.name).toEqualTypeOf(); + expect(rank.default).toBeDefined(); + expectTypeOf(rank.default).toEqualTypeOf(); + expect(rank.tag).toBeDefined(); + expectTypeOf(rank.tag).toEqualTypeOf(); + expect(rank.createdAtTimestamp).toBeDefined(); + expectTypeOf(rank.createdAtTimestamp).toEqualTypeOf(); + expect(rank.createdAt).toBeDefined(); + expectTypeOf(rank.createdAt).toEqualTypeOf(); + expect(rank.priority).toBeDefined(); + expectTypeOf(rank.priority).toEqualTypeOf(); + expect(rank.toString()).toBeDefined(); + expectTypeOf(rank.toString()).toEqualTypeOf(); + expect(rank.toString()).toEqual(rank.name); + }); + expect(data.totalWeeklyGEXP).toBeDefined(); + expectTypeOf(data.totalWeeklyGEXP).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.joinable).toBeDefined(); + expectTypeOf(data.joinable).toEqualTypeOf(); + expect(data.publiclyListed).toBeDefined(); + expectTypeOf(data.publiclyListed).toEqualTypeOf(); + expect(data.chatMuteUntilTimestamp).toBeDefined(); + expectTypeOf(data.chatMuteUntilTimestamp).toEqualTypeOf(); + expect(data.chatMuteUntil).toBeDefined(); + expectTypeOf(data.chatMuteUntil).toEqualTypeOf(); + expect(data.banner).toBeDefined(); + expectTypeOf(data.banner).toEqualTypeOf<{ Pattern: string; Color: string }[]>(); + expect(data.tag).toBeDefined(); + expectTypeOf(data.tag).toEqualTypeOf(); + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + if (data.tagColor) { + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + expect(data.tagColor.color).toBeDefined(); + expectTypeOf(data.tagColor.color).toEqualTypeOf(); + expect(data.tagColor.toString).toBeDefined(); + expectTypeOf(data.tagColor.toString).toEqualTypeOf<() => ColorString>(); + expect(data.tagColor.toString()).toBeDefined(); + expectTypeOf(data.tagColor.toString()).toEqualTypeOf(); + expect(data.tagColor.toHex).toBeDefined(); + expectTypeOf(data.tagColor.toHex).toEqualTypeOf<() => ColorHex>(); + expect(data.tagColor.toHex()).toBeDefined(); + expectTypeOf(data.tagColor.toHex()).toEqualTypeOf(); + expect(data.tagColor.toCode).toBeDefined(); + expectTypeOf(data.tagColor.toCode).toEqualTypeOf<() => ColorCode>(); + expect(data.tagColor.toCode()).toBeDefined(); + expectTypeOf(data.tagColor.toCode()).toEqualTypeOf(); + expect(data.tagColor.toInGameCode).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode).toEqualTypeOf<() => InGameCode>(); + expect(data.tagColor.toInGameCode()).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode()).toEqualTypeOf(); + } + expect(data.expHistory).toBeDefined(); + expectTypeOf(data.expHistory).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expectTypeOf(data.achievements).toEqualTypeOf<{ winners: number; experienceKings: number; onlinePlayers: number }>(); + expect(data.achievements.winners).toBeDefined(); + expectTypeOf(data.achievements.winners).toEqualTypeOf(); + expect(data.achievements.winners).toBeGreaterThanOrEqual(0); + expect(data.achievements.experienceKings).toBeDefined(); + expectTypeOf(data.achievements.experienceKings).toEqualTypeOf(); + expect(data.achievements.experienceKings).toBeGreaterThanOrEqual(0); + expect(data.preferredGames).toBeDefined(); + expectTypeOf(data.preferredGames).toEqualTypeOf(); + data.preferredGames.forEach((game: Game) => { + expect(game).toBeDefined(); + expectTypeOf(game).toEqualTypeOf(); + expect(game.game).toBeDefined(); + expectTypeOf(game.game).toEqualTypeOf(); + expect(game.id).toBeDefined(); + expectTypeOf(game.id).toEqualTypeOf(); + expect(game.code).toBeDefined(); + expectTypeOf(game.code).toEqualTypeOf(); + expect(game.name).toBeDefined(); + expectTypeOf(game.name).toEqualTypeOf(); + expect(game.found).toBeDefined(); + expectTypeOf(game.found).toEqualTypeOf(); + expect(game.toString()).toBeDefined(); + expect(game.toString()).toBe(game.name); + expectTypeOf(game.toString()).toEqualTypeOf(); + expect(Game.IDS).toBeDefined(); + expectTypeOf(Game.IDS).toEqualTypeOf(); + expect(Game.CODES).toBeDefined(); + expectTypeOf(Game.CODES).toEqualTypeOf(); + expect(Game.NAMES).toBeDefined(); + expectTypeOf(Game.NAMES).toEqualTypeOf(); + }); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf(); + client.destroy(); +}); + +test('getGuild (Id)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuild('id', '64b54f9d8ea8c96aaedafe84'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Guild); + expectTypeOf(data).toEqualTypeOf(); + if (data === null) return; + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + data.members.forEach((member: GuildMember) => { + expect(member).toBeDefined(); + expectTypeOf(member).toEqualTypeOf(); + expect(member.uuid).toBeDefined(); + expectTypeOf(member.uuid).toEqualTypeOf(); + expect(member.joinedAtTimestamp).toBeDefined(); + expectTypeOf(member.joinedAtTimestamp).toEqualTypeOf(); + expect(member.joinedAt).toBeDefined(); + expectTypeOf(member.joinedAt).toEqualTypeOf(); + expect(member.questParticipation).toBeDefined(); + expectTypeOf(member.questParticipation).toEqualTypeOf(); + expect(member.rank).toBeDefined(); + expectTypeOf(member.rank).toEqualTypeOf(); + expect(member.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(member.mutedUntilTimestamp).toEqualTypeOf(); + expect(member.mutedUntil).toBeDefined(); + expectTypeOf(member.mutedUntil).toEqualTypeOf(); + expect(member.expHistory).toBeDefined(); + expectTypeOf(member.expHistory).toEqualTypeOf(); + expect(member.weeklyExperience).toBeDefined(); + expectTypeOf(member.weeklyExperience).toEqualTypeOf(); + expect(member.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(member.toString()).toBeDefined(); + expectTypeOf(member.toString()).toEqualTypeOf(); + expect(member.toString()).toEqual(member.uuid); + }); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + if (data.me !== null) { + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.me.uuid).toBeDefined(); + expectTypeOf(data.me.uuid).toEqualTypeOf(); + expect(data.me.joinedAtTimestamp).toBeDefined(); + expectTypeOf(data.me.joinedAtTimestamp).toEqualTypeOf(); + expect(data.me.joinedAt).toBeDefined(); + expectTypeOf(data.me.joinedAt).toEqualTypeOf(); + expect(data.me.questParticipation).toBeDefined(); + expectTypeOf(data.me.questParticipation).toEqualTypeOf(); + expect(data.me.rank).toBeDefined(); + expectTypeOf(data.me.rank).toEqualTypeOf(); + expect(data.me.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(data.me.mutedUntilTimestamp).toEqualTypeOf(); + expect(data.me.mutedUntil).toBeDefined(); + expectTypeOf(data.me.mutedUntil).toEqualTypeOf(); + expect(data.me.expHistory).toBeDefined(); + expectTypeOf(data.me.expHistory).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeDefined(); + expectTypeOf(data.me.weeklyExperience).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(data.me.toString()).toBeDefined(); + expectTypeOf(data.me.toString()).toEqualTypeOf(); + expect(data.me.toString()).toEqual(data.me.uuid); + } + expect(data.ranks).toBeDefined(); + expectTypeOf(data.ranks).toEqualTypeOf(); + data.ranks.forEach((rank: GuildRank) => { + expect(rank).toBeDefined(); + expect(rank).toBeInstanceOf(GuildRank); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank.name).toBeDefined(); + expectTypeOf(rank.name).toEqualTypeOf(); + expect(rank.default).toBeDefined(); + expectTypeOf(rank.default).toEqualTypeOf(); + expect(rank.tag).toBeDefined(); + expectTypeOf(rank.tag).toEqualTypeOf(); + expect(rank.createdAtTimestamp).toBeDefined(); + expectTypeOf(rank.createdAtTimestamp).toEqualTypeOf(); + expect(rank.createdAt).toBeDefined(); + expectTypeOf(rank.createdAt).toEqualTypeOf(); + expect(rank.priority).toBeDefined(); + expectTypeOf(rank.priority).toEqualTypeOf(); + expect(rank.toString()).toBeDefined(); + expectTypeOf(rank.toString()).toEqualTypeOf(); + expect(rank.toString()).toEqual(rank.name); + }); + expect(data.totalWeeklyGEXP).toBeDefined(); + expectTypeOf(data.totalWeeklyGEXP).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.joinable).toBeDefined(); + expectTypeOf(data.joinable).toEqualTypeOf(); + expect(data.publiclyListed).toBeDefined(); + expectTypeOf(data.publiclyListed).toEqualTypeOf(); + expect(data.chatMuteUntilTimestamp).toBeDefined(); + expectTypeOf(data.chatMuteUntilTimestamp).toEqualTypeOf(); + expect(data.chatMuteUntil).toBeDefined(); + expectTypeOf(data.chatMuteUntil).toEqualTypeOf(); + expect(data.banner).toBeDefined(); + expectTypeOf(data.banner).toEqualTypeOf<{ Pattern: string; Color: string }[]>(); + expect(data.tag).toBeDefined(); + expectTypeOf(data.tag).toEqualTypeOf(); + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + if (data.tagColor) { + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + expect(data.tagColor.color).toBeDefined(); + expectTypeOf(data.tagColor.color).toEqualTypeOf(); + expect(data.tagColor.toString).toBeDefined(); + expectTypeOf(data.tagColor.toString).toEqualTypeOf<() => ColorString>(); + expect(data.tagColor.toString()).toBeDefined(); + expectTypeOf(data.tagColor.toString()).toEqualTypeOf(); + expect(data.tagColor.toHex).toBeDefined(); + expectTypeOf(data.tagColor.toHex).toEqualTypeOf<() => ColorHex>(); + expect(data.tagColor.toHex()).toBeDefined(); + expectTypeOf(data.tagColor.toHex()).toEqualTypeOf(); + expect(data.tagColor.toCode).toBeDefined(); + expectTypeOf(data.tagColor.toCode).toEqualTypeOf<() => ColorCode>(); + expect(data.tagColor.toCode()).toBeDefined(); + expectTypeOf(data.tagColor.toCode()).toEqualTypeOf(); + expect(data.tagColor.toInGameCode).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode).toEqualTypeOf<() => InGameCode>(); + expect(data.tagColor.toInGameCode()).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode()).toEqualTypeOf(); + } + expect(data.expHistory).toBeDefined(); + expectTypeOf(data.expHistory).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expectTypeOf(data.achievements).toEqualTypeOf<{ winners: number; experienceKings: number; onlinePlayers: number }>(); + expect(data.achievements.winners).toBeDefined(); + expectTypeOf(data.achievements.winners).toEqualTypeOf(); + expect(data.achievements.winners).toBeGreaterThanOrEqual(0); + expect(data.achievements.experienceKings).toBeDefined(); + expectTypeOf(data.achievements.experienceKings).toEqualTypeOf(); + expect(data.achievements.experienceKings).toBeGreaterThanOrEqual(0); + expect(data.preferredGames).toBeDefined(); + expectTypeOf(data.preferredGames).toEqualTypeOf(); + data.preferredGames.forEach((game: Game) => { + expect(game).toBeDefined(); + expectTypeOf(game).toEqualTypeOf(); + expect(game.game).toBeDefined(); + expectTypeOf(game.game).toEqualTypeOf(); + expect(game.id).toBeDefined(); + expectTypeOf(game.id).toEqualTypeOf(); + expect(game.code).toBeDefined(); + expectTypeOf(game.code).toEqualTypeOf(); + expect(game.name).toBeDefined(); + expectTypeOf(game.name).toEqualTypeOf(); + expect(game.found).toBeDefined(); + expectTypeOf(game.found).toEqualTypeOf(); + expect(game.toString()).toBeDefined(); + expect(game.toString()).toBe(game.name); + expectTypeOf(game.toString()).toEqualTypeOf(); + expect(Game.IDS).toBeDefined(); + expectTypeOf(Game.IDS).toEqualTypeOf(); + expect(Game.CODES).toBeDefined(); + expectTypeOf(Game.CODES).toEqualTypeOf(); + expect(Game.NAMES).toBeDefined(); + expectTypeOf(Game.NAMES).toEqualTypeOf(); + }); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf(); + client.destroy(); +}); + +test('getGuild (Player)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuild('player', '14727faefbdc4aff848cd2713eb9939e'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Guild); + expectTypeOf(data).toEqualTypeOf(); + if (data === null) return; + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + data.members.forEach((member: GuildMember) => { + expect(member).toBeDefined(); + expectTypeOf(member).toEqualTypeOf(); + expect(member.uuid).toBeDefined(); + expectTypeOf(member.uuid).toEqualTypeOf(); + expect(member.joinedAtTimestamp).toBeDefined(); + expectTypeOf(member.joinedAtTimestamp).toEqualTypeOf(); + expect(member.joinedAt).toBeDefined(); + expectTypeOf(member.joinedAt).toEqualTypeOf(); + expect(member.questParticipation).toBeDefined(); + expectTypeOf(member.questParticipation).toEqualTypeOf(); + expect(member.rank).toBeDefined(); + expectTypeOf(member.rank).toEqualTypeOf(); + expect(member.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(member.mutedUntilTimestamp).toEqualTypeOf(); + expect(member.mutedUntil).toBeDefined(); + expectTypeOf(member.mutedUntil).toEqualTypeOf(); + expect(member.expHistory).toBeDefined(); + expectTypeOf(member.expHistory).toEqualTypeOf(); + expect(member.weeklyExperience).toBeDefined(); + expectTypeOf(member.weeklyExperience).toEqualTypeOf(); + expect(member.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(member.toString()).toBeDefined(); + expectTypeOf(member.toString()).toEqualTypeOf(); + expect(member.toString()).toEqual(member.uuid); + }); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + if (data.me !== null) { + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.me.uuid).toBeDefined(); + expectTypeOf(data.me.uuid).toEqualTypeOf(); + expect(data.me.joinedAtTimestamp).toBeDefined(); + expectTypeOf(data.me.joinedAtTimestamp).toEqualTypeOf(); + expect(data.me.joinedAt).toBeDefined(); + expectTypeOf(data.me.joinedAt).toEqualTypeOf(); + expect(data.me.questParticipation).toBeDefined(); + expectTypeOf(data.me.questParticipation).toEqualTypeOf(); + expect(data.me.rank).toBeDefined(); + expectTypeOf(data.me.rank).toEqualTypeOf(); + expect(data.me.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(data.me.mutedUntilTimestamp).toEqualTypeOf(); + expect(data.me.mutedUntil).toBeDefined(); + expectTypeOf(data.me.mutedUntil).toEqualTypeOf(); + expect(data.me.expHistory).toBeDefined(); + expectTypeOf(data.me.expHistory).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeDefined(); + expectTypeOf(data.me.weeklyExperience).toEqualTypeOf(); + expect(data.me.weeklyExperience).toBeGreaterThanOrEqual(0); + expect(data.me.toString()).toBeDefined(); + expectTypeOf(data.me.toString()).toEqualTypeOf(); + expect(data.me.toString()).toEqual(data.me.uuid); + } + expect(data.ranks).toBeDefined(); + expectTypeOf(data.ranks).toEqualTypeOf(); + data.ranks.forEach((rank: GuildRank) => { + expect(rank).toBeDefined(); + expect(rank).toBeInstanceOf(GuildRank); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank.name).toBeDefined(); + expectTypeOf(rank.name).toEqualTypeOf(); + expect(rank.default).toBeDefined(); + expectTypeOf(rank.default).toEqualTypeOf(); + expect(rank.tag).toBeDefined(); + expectTypeOf(rank.tag).toEqualTypeOf(); + expect(rank.createdAtTimestamp).toBeDefined(); + expectTypeOf(rank.createdAtTimestamp).toEqualTypeOf(); + expect(rank.createdAt).toBeDefined(); + expectTypeOf(rank.createdAt).toEqualTypeOf(); + expect(rank.priority).toBeDefined(); + expectTypeOf(rank.priority).toEqualTypeOf(); + expect(rank.toString()).toBeDefined(); + expectTypeOf(rank.toString()).toEqualTypeOf(); + expect(rank.toString()).toEqual(rank.name); + }); + expect(data.totalWeeklyGEXP).toBeDefined(); + expectTypeOf(data.totalWeeklyGEXP).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.joinable).toBeDefined(); + expectTypeOf(data.joinable).toEqualTypeOf(); + expect(data.publiclyListed).toBeDefined(); + expectTypeOf(data.publiclyListed).toEqualTypeOf(); + expect(data.chatMuteUntilTimestamp).toBeDefined(); + expectTypeOf(data.chatMuteUntilTimestamp).toEqualTypeOf(); + expect(data.chatMuteUntil).toBeDefined(); + expectTypeOf(data.chatMuteUntil).toEqualTypeOf(); + expect(data.banner).toBeDefined(); + expectTypeOf(data.banner).toEqualTypeOf<{ Pattern: string; Color: string }[]>(); + expect(data.tag).toBeDefined(); + expectTypeOf(data.tag).toEqualTypeOf(); + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + if (data.tagColor) { + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + expect(data.tagColor.color).toBeDefined(); + expectTypeOf(data.tagColor.color).toEqualTypeOf(); + expect(data.tagColor.toString).toBeDefined(); + expectTypeOf(data.tagColor.toString).toEqualTypeOf<() => ColorString>(); + expect(data.tagColor.toString()).toBeDefined(); + expectTypeOf(data.tagColor.toString()).toEqualTypeOf(); + expect(data.tagColor.toHex).toBeDefined(); + expectTypeOf(data.tagColor.toHex).toEqualTypeOf<() => ColorHex>(); + expect(data.tagColor.toHex()).toBeDefined(); + expectTypeOf(data.tagColor.toHex()).toEqualTypeOf(); + expect(data.tagColor.toCode).toBeDefined(); + expectTypeOf(data.tagColor.toCode).toEqualTypeOf<() => ColorCode>(); + expect(data.tagColor.toCode()).toBeDefined(); + expectTypeOf(data.tagColor.toCode()).toEqualTypeOf(); + expect(data.tagColor.toInGameCode).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode).toEqualTypeOf<() => InGameCode>(); + expect(data.tagColor.toInGameCode()).toBeDefined(); + expectTypeOf(data.tagColor.toInGameCode()).toEqualTypeOf(); + } + expect(data.expHistory).toBeDefined(); + expectTypeOf(data.expHistory).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expectTypeOf(data.achievements).toEqualTypeOf<{ winners: number; experienceKings: number; onlinePlayers: number }>(); + expect(data.achievements.winners).toBeDefined(); + expectTypeOf(data.achievements.winners).toEqualTypeOf(); + expect(data.achievements.winners).toBeGreaterThanOrEqual(0); + expect(data.achievements.experienceKings).toBeDefined(); + expectTypeOf(data.achievements.experienceKings).toEqualTypeOf(); + expect(data.achievements.experienceKings).toBeGreaterThanOrEqual(0); + expect(data.preferredGames).toBeDefined(); + expectTypeOf(data.preferredGames).toEqualTypeOf(); + data.preferredGames.forEach((game: Game) => { + expect(game).toBeDefined(); + expectTypeOf(game).toEqualTypeOf(); + expect(game.game).toBeDefined(); + expectTypeOf(game.game).toEqualTypeOf(); + expect(game.id).toBeDefined(); + expectTypeOf(game.id).toEqualTypeOf(); + expect(game.code).toBeDefined(); + expectTypeOf(game.code).toEqualTypeOf(); + expect(game.name).toBeDefined(); + expectTypeOf(game.name).toEqualTypeOf(); + expect(game.found).toBeDefined(); + expectTypeOf(game.found).toEqualTypeOf(); + expect(game.toString()).toBeDefined(); + expect(game.toString()).toBe(game.name); + expectTypeOf(game.toString()).toEqualTypeOf(); + expect(Game.IDS).toBeDefined(); + expectTypeOf(Game.IDS).toEqualTypeOf(); + expect(Game.CODES).toBeDefined(); + expectTypeOf(Game.CODES).toEqualTypeOf(); + expect(Game.NAMES).toBeDefined(); + expectTypeOf(Game.NAMES).toEqualTypeOf(); + }); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getGuild.ts b/src/API/getGuild.ts new file mode 100644 index 000000000..5deab5c1c --- /dev/null +++ b/src/API/getGuild.ts @@ -0,0 +1,32 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import Guild from '../Structures/Guild/Guild.js'; +import RequestData from '../Private/RequestData.js'; +import type { GuildFetchOptions } from '../Types/API.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getGuild extends Endpoint { + override async execute( + searchParameter: GuildFetchOptions, + query: string, + options?: RequestOptions + ): Promise { + if (!query) throw new Error(Errors.NO_GUILD_QUERY); + if (searchParameter === 'id' && !this.client.functions.isGuildID(query)) { + throw new Error(Errors.INVALID_GUILD_ID); + } + const isPlayerQuery = searchParameter === 'player'; + if (isPlayerQuery) query = await this.client.requestHandler.toUUID(query); + if (!['id', 'name', 'player'].includes(searchParameter)) { + throw new Error(Errors.INVALID_GUILD_SEARCH_PARAMETER); + } + const res = await this.client.requestHandler.request(`/guild?${searchParameter}=${encodeURI(query)}`, options); + if (res.options.raw) return res; + if (!res.data.guild && searchParameter !== 'player') { + throw new Error(Errors.GUILD_DOES_NOT_EXIST); + } + return res.data.guild ? new Guild(res.data.guild, isPlayerQuery ? query : undefined) : null; + } +} + +export default getGuild; diff --git a/src/API/getGuildAchievements.js b/src/API/getGuildAchievements.js deleted file mode 100644 index 982ebc7a1..000000000 --- a/src/API/getGuildAchievements.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const GuildAchievements = require('../structures/Static/GuildAchievements'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/guilds/achievements'); - if (res.raw) return res; - return new GuildAchievements(res); -}; diff --git a/src/API/getGuildAchievements.test.ts b/src/API/getGuildAchievements.test.ts new file mode 100644 index 000000000..95b2eb502 --- /dev/null +++ b/src/API/getGuildAchievements.test.ts @@ -0,0 +1,88 @@ +import Client from '../Client.js'; +import GuildAchievements from '../Structures/Static/Achievements/GuildAchievements.js'; +import OneTimeAchievement from '../Structures/Static/Achievements/OneTimeAchievement.js'; +import RequestData from '../Private/RequestData.js'; +import TieredAchievement from '../Structures/Static/Achievements/TieredAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { AchievementTier } from '../Types/Static.js'; + +test('getGuildAchievements (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuildAchievements({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + if (data.isRaw()) return; + client.destroy(); +}); + +test('getGuildAchievements', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getGuildAchievements(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.oneTimeAchievements).toBeDefined(); + expectTypeOf(data.oneTimeAchievements).toEqualTypeOf(); + data.oneTimeAchievements.forEach((achievement: OneTimeAchievement) => { + expect(achievement.codeName).toBeDefined(); + expectTypeOf(achievement.codeName).toEqualTypeOf(); + expect(achievement.name).toBeDefined(); + expectTypeOf(achievement.name).toEqualTypeOf(); + expect(achievement.description).toBeDefined(); + expectTypeOf(achievement.description).toEqualTypeOf(); + expect(achievement.secret).toBeDefined(); + expectTypeOf(achievement.secret).toEqualTypeOf(); + expect(achievement.legacy).toBeDefined(); + expectTypeOf(achievement.legacy).toEqualTypeOf(); + expect(achievement.points).toBeDefined(); + expectTypeOf(achievement.points).toEqualTypeOf(); + expect(achievement.gamePercentUnlocked).toBeDefined(); + expectTypeOf(achievement.gamePercentUnlocked).toEqualTypeOf(); + expect(achievement.globalPercentUnlocked).toBeDefined(); + expectTypeOf(achievement.globalPercentUnlocked).toEqualTypeOf(); + expect(achievement.toString()).toBeDefined(); + expect(achievement.toString()).toBe(achievement.codeName); + expectTypeOf(achievement.toString()).toEqualTypeOf(); + }); + expect(data.tieredAchievements).toBeDefined(); + expectTypeOf(data.tieredAchievements).toEqualTypeOf(); + data.tieredAchievements.forEach((achievement: TieredAchievement) => { + expect(achievement.codeName).toBeDefined(); + expectTypeOf(achievement.codeName).toEqualTypeOf(); + expect(achievement.name).toBeDefined(); + expectTypeOf(achievement.name).toEqualTypeOf(); + expect(achievement.description).toBeDefined(); + expectTypeOf(achievement.description).toEqualTypeOf(); + expect(achievement.secret).toBeDefined(); + expectTypeOf(achievement.secret).toEqualTypeOf(); + expect(achievement.legacy).toBeDefined(); + expectTypeOf(achievement.legacy).toEqualTypeOf(); + expect(achievement.tiers).toBeDefined(); + expectTypeOf(achievement.tiers).toEqualTypeOf(); + achievement.tiers.forEach((tier) => { + expect(tier).toBeDefined(); + expectTypeOf(tier).toEqualTypeOf(); + expect(tier.tier).toBeDefined(); + expect(tier.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(tier.tier).toEqualTypeOf(); + expect(tier.points).toBeUndefined(); + expectTypeOf(tier.points).toEqualTypeOf(); + expect(tier.amount).toBeDefined(); + expect(tier.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(tier.amount).toEqualTypeOf(); + }); + expect(achievement.toString()).toBeDefined(); + expect(achievement.toString()).toBe(achievement.codeName); + expectTypeOf(achievement.toString()).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getGuildAchievements.ts b/src/API/getGuildAchievements.ts new file mode 100644 index 000000000..bb87ca8cf --- /dev/null +++ b/src/API/getGuildAchievements.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import GuildAchievements from '../Structures/Static/Achievements/GuildAchievements.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getGuildAchievements extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/guilds/achievements', options); + if (res.options.raw) return res; + return new GuildAchievements(res.data); + } +} + +export default getGuildAchievements; diff --git a/src/API/getHouse.test.ts b/src/API/getHouse.test.ts new file mode 100644 index 000000000..7cf525baa --- /dev/null +++ b/src/API/getHouse.test.ts @@ -0,0 +1,58 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getHouse (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const houses = (await client.getActiveHouses()) as House[]; + if (undefined === houses[0]) return; + const data = await client.getHouse(houses[0].uuid, { raw: true }); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + if (data.isRaw()) return; + client.destroy(); +}); + +test('getHouse (no input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getHouse()).rejects.toThrowError(Errors.NO_UUID); + client.destroy(); +}); + +test('getHouse', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const houses = (await client.getActiveHouses()) as House[]; + if (undefined === houses[0]) return; + expect(houses).toBeDefined(); + expectTypeOf(houses).toEqualTypeOf(); + const data = await client.getHouse(houses[0].uuid); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.owner).toBeDefined(); + expectTypeOf(data.owner).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.players).toBeDefined(); + expectTypeOf(data.players).toEqualTypeOf(); + expect(data.cookies).toBeDefined(); + expectTypeOf(data.cookies).toEqualTypeOf(); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getHouse.ts b/src/API/getHouse.ts new file mode 100644 index 000000000..518717fda --- /dev/null +++ b/src/API/getHouse.ts @@ -0,0 +1,16 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getHouse extends Endpoint { + override async execute(query: string, options?: RequestOptions): Promise { + if (!query) throw new Error(Errors.NO_UUID); + const res = await this.client.requestHandler.request(`/housing/house?house=${query}`, options); + if (res.options.raw) return res; + return new House(res.data); + } +} + +export default getHouse; diff --git a/src/API/getLeaderboards.js b/src/API/getLeaderboards.js deleted file mode 100644 index d7e17a86f..000000000 --- a/src/API/getLeaderboards.js +++ /dev/null @@ -1,15 +0,0 @@ -const Errors = require('../Errors'); -module.exports = async function () { - const Leaderboard = require('../structures/Leaderboard'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/leaderboards'); - if (res.raw) return res; - if (!res.leaderboards) throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, 'Try again.')); - const lbnames = Object.create(require('../utils/Constants').leaderboardNames); - for (const name in lbnames) { - lbnames[name] = res.leaderboards[lbnames[name]].length - ? res.leaderboards[lbnames[name]].map((lb) => new Leaderboard(lb)) - : []; - } - return lbnames; -}; diff --git a/src/API/getLeaderboards.test.ts b/src/API/getLeaderboards.test.ts new file mode 100644 index 000000000..34050ccb7 --- /dev/null +++ b/src/API/getLeaderboards.test.ts @@ -0,0 +1,73 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import Leaderboard from '../Structures/Leaderboard.js'; +import RequestData from '../Private/RequestData.js'; +import { defaultRequestData } from '../../vitest.setup.js'; +import { expect, expectTypeOf, test, vi } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getLeaderboards (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getLeaderboards({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf> | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getLeaderboards', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getLeaderboards(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf> | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + Object.keys(data).forEach((key) => { + if (key === 'isRaw') return; + if (undefined === data[key]) return; + expect(data[key]).toBeDefined(); + expectTypeOf(data[key]).toEqualTypeOf(); + data[key].forEach((leaderboard: Leaderboard) => { + expect(leaderboard).toBeDefined(); + expect(leaderboard).instanceOf(Leaderboard); + expectTypeOf(leaderboard).toEqualTypeOf(); + + expect(leaderboard.path).toBeDefined(); + expectTypeOf(leaderboard.path).toEqualTypeOf(); + expect(leaderboard.prefix).toBeDefined(); + expectTypeOf(leaderboard.prefix).toEqualTypeOf(); + expect(leaderboard.title).toBeDefined(); + expectTypeOf(leaderboard.title).toEqualTypeOf(); + expect(leaderboard.location).toBeDefined(); + expectTypeOf(leaderboard.location).toEqualTypeOf(); + expect(leaderboard.count).toBeDefined(); + expect(leaderboard.count).toBeGreaterThanOrEqual(0); + expectTypeOf(leaderboard.count).toEqualTypeOf(); + expect(leaderboard.leaders).toBeDefined(); + expectTypeOf(leaderboard.leaders).toEqualTypeOf(); + leaderboard.leaders.forEach((leader: string) => { + expect(leader).toBeDefined(); + expectTypeOf(leader).toEqualTypeOf(); + }); + }); + }); + client.destroy(); +}); + +test('getLeaderboards (Missing Data)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? ''); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + json: () => Promise.resolve({ success: true }) + } as any); + + await expect(() => client.getLeaderboards()).rejects.toThrowError( + Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, 'Try again.') + ); + vi.restoreAllMocks(); + client.destroy(); +}); diff --git a/src/API/getLeaderboards.ts b/src/API/getLeaderboards.ts new file mode 100644 index 000000000..db88afa70 --- /dev/null +++ b/src/API/getLeaderboards.ts @@ -0,0 +1,27 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import Leaderboard from '../Structures/Leaderboard.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getLeaderboards extends Endpoint { + override async execute(options?: RequestOptions): Promise> | RequestData> { + const res = await this.client.requestHandler.request('/leaderboards', options); + if (res.options.raw) return res; + if (!res.data.leaderboards) { + throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, 'Try again.')); + } + const leaderboards: Record = {}; + Object.keys(res.data.leaderboards).forEach((key) => { + leaderboards[key] = res.data.leaderboards[key].map((l: Record) => new Leaderboard(l)); + }); + return Object.assign(leaderboards, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getLeaderboards; diff --git a/src/API/getPlayer.js b/src/API/getPlayer.js deleted file mode 100644 index c305cb03f..000000000 --- a/src/API/getPlayer.js +++ /dev/null @@ -1,23 +0,0 @@ -const Errors = require('../Errors'); -const toUuid = require('../utils/toUuid'); -const getGuild = require('./getGuild'); -const getRecentGames = require('./getRecentGames'); -module.exports = async function (query, options = { guild: false, recentGames: false }) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - const Player = require('../structures/Player'); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/player?uuid=${query}`); - if (res.raw) return res; - if (query && !res.player) throw new Error(Errors.PLAYER_HAS_NEVER_LOGGED); - let guild = null; - let recentGames = null; - if (options.guild) { - guild = getGuild.call(this, 'player', query); - } - if (options.recentGames) { - recentGames = getRecentGames.call(this, query); - } - [guild, recentGames] = await Promise.all([guild, recentGames]); - return new Player(res.player, { guild, recentGames }); -}; diff --git a/src/API/getPlayer.ts b/src/API/getPlayer.ts new file mode 100644 index 000000000..35409a1cb --- /dev/null +++ b/src/API/getPlayer.ts @@ -0,0 +1,25 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import Guild from '../Structures/Guild/Guild.js'; +import House from '../Structures/House.js'; +import Player from '../Structures/Player/Player.js'; +import RecentGame from '../Structures/RecentGame.js'; +import RequestData from '../Private/RequestData.js'; +import type { PlayerRequestOptions } from '../Types/API.js'; + +class getPlayer extends Endpoint { + override async execute(query: string, options?: PlayerRequestOptions): Promise { + if (!query) throw new Error(Errors.NO_NICKNAME_UUID); + query = await this.client.requestHandler.toUUID(query); + const res = await this.client.requestHandler.request(`/player?uuid=${query}`, options); + if (res.options.raw) return res; + if (query && !res.data.player) throw new Error(Errors.PLAYER_HAS_NEVER_LOGGED); + return new Player(res.data.player, { + guild: options?.guild ? ((await this.client.getGuild('player', query)) as Guild) : null, + houses: options?.houses ? ((await this.client.getPlayerHouses(query)) as House[]) : null, + recentGames: options?.recentGames ? ((await this.client.getRecentGames(query)) as RecentGame[]) : null + }); + } +} + +export default getPlayer; diff --git a/src/API/getPlayerHouses.test.ts b/src/API/getPlayerHouses.test.ts new file mode 100644 index 000000000..4bf3bfdef --- /dev/null +++ b/src/API/getPlayerHouses.test.ts @@ -0,0 +1,59 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getPlayerHouses (No input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getPlayerHouses()).rejects.toThrowError(Errors.NO_NICKNAME_UUID); + client.destroy(); +}); + +test('getPlayerHouses (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getPlayerHouses('69e04609da2a4e7dabb83546a971969e', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getPlayerHouses', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getPlayerHouses('69e04609da2a4e7dabb83546a971969e'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((house: House) => { + expect(house).toBeDefined(); + expect(house).toBeInstanceOf(House); + expectTypeOf(house).toEqualTypeOf(); + expect(house.name).toBeDefined(); + expectTypeOf(house.name).toEqualTypeOf(); + expect(house.uuid).toBeDefined(); + expectTypeOf(house.uuid).toEqualTypeOf(); + expect(house.owner).toBeDefined(); + expectTypeOf(house.owner).toEqualTypeOf(); + expect(house.createdAtTimestamp).toBeDefined(); + expectTypeOf(house.createdAtTimestamp).toEqualTypeOf(); + expect(house.createdAt).toBeDefined(); + expectTypeOf(house.createdAt).toEqualTypeOf(); + expect(house.players).toBeDefined(); + expectTypeOf(house.players).toEqualTypeOf(); + expect(house.cookies).toBeDefined(); + expectTypeOf(house.cookies).toEqualTypeOf(); + expect(house.toString()).toBeDefined(); + expectTypeOf(house.toString()).toEqualTypeOf(); + expect(house.toString()).toBe(house.name); + }); + client.destroy(); +}); diff --git a/src/API/getPlayerHouses.ts b/src/API/getPlayerHouses.ts new file mode 100644 index 000000000..a6cdedfd5 --- /dev/null +++ b/src/API/getPlayerHouses.ts @@ -0,0 +1,23 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import House from '../Structures/House.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getPlayerHouses extends Endpoint { + override async execute(query: string, options?: RequestOptions): Promise | RequestData> { + if (!query) throw new Error(Errors.NO_NICKNAME_UUID); + query = await this.client.requestHandler.toUUID(query); + const res = await this.client.requestHandler.request(`/housing/houses?player=${query}`, options); + if (res.options.raw) return res; + const houses = res.data.map((h: any) => new House(h)); + return Object.assign(houses, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getPlayerHouses; diff --git a/src/API/getQuests.js b/src/API/getQuests.js deleted file mode 100644 index 1c6e4d634..000000000 --- a/src/API/getQuests.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const Quests = require('../structures/Static/Quests'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/quests'); - if (res.raw) return res; - return new Quests(res); -}; diff --git a/src/API/getQuests.test.ts b/src/API/getQuests.test.ts new file mode 100644 index 000000000..80bc70a92 --- /dev/null +++ b/src/API/getQuests.test.ts @@ -0,0 +1,66 @@ +import Client from '../Client.js'; +import GameQuests from '../Structures/Static/GameQuests.js'; +import Quest from '../Structures/Static/Quest.js'; +import QuestObjective from '../Structures/Static/QuestObjective.js'; +import Quests from '../Structures/Static/Quests.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { QuestReward, QuestType } from '../Types/Static.js'; + +test('getQuests (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getQuests({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getQuests', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getQuests(); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Quests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.questsPerGame).toBeDefined(); + expectTypeOf(data.questsPerGame).toEqualTypeOf>(); + Object.keys(data.questsPerGame).forEach((game) => { + if (undefined === data.questsPerGame[game]) return; + expect(data.questsPerGame[game]).toBeDefined(); + expect(data.questsPerGame[game]).toBeInstanceOf(GameQuests); + expectTypeOf(data.questsPerGame[game]).toEqualTypeOf(); + expect(data.questsPerGame[game].game).toBeDefined(); + expect(data.questsPerGame[game].game).toBe(game); + expectTypeOf(data.questsPerGame[game].game).toEqualTypeOf(); + expect(data.questsPerGame[game].quests).toBeDefined(); + expectTypeOf(data.questsPerGame[game].quests).toEqualTypeOf(); + data.questsPerGame[game].quests.forEach((quest: Quest) => { + expect(quest).toBeDefined(); + expect(quest).toBeInstanceOf(Quest); + expectTypeOf(quest).toEqualTypeOf(); + expect(quest.id).toBeDefined(); + expectTypeOf(quest.id).toEqualTypeOf(); + expect(quest.name).toBeDefined(); + expectTypeOf(quest.name).toEqualTypeOf(); + expect(quest.description).toBeDefined(); + expectTypeOf(quest.description).toEqualTypeOf(); + expect(quest.rewards).toBeDefined(); + expectTypeOf(quest.rewards).toEqualTypeOf(); + expect(quest.type).toBeDefined(); + expectTypeOf(quest.type).toEqualTypeOf(); + expect(quest.objectives).toBeDefined(); + expectTypeOf(quest.objectives).toEqualTypeOf(); + }); + }); + client.destroy(); +}); diff --git a/src/API/getQuests.ts b/src/API/getQuests.ts new file mode 100644 index 000000000..dcc7120f9 --- /dev/null +++ b/src/API/getQuests.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import Quests from '../Structures/Static/Quests.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getQuests extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/quests', options); + if (res.options.raw) return res; + return new Quests(res.data); + } +} + +export default getQuests; diff --git a/src/API/getRecentGames.js b/src/API/getRecentGames.js deleted file mode 100644 index eb4b69e42..000000000 --- a/src/API/getRecentGames.js +++ /dev/null @@ -1,14 +0,0 @@ -const toUuid = require('../utils/toUuid'); -const Errors = require('../Errors'); -module.exports = async function (query) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - const RecentGame = require('../structures/RecentGame'); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/recentgames?uuid=${query}`); - if (res.raw) return res; - if (0 === res.games.length) { - return []; - } - return res.games.map((x) => new RecentGame(x)); -}; diff --git a/src/API/getRecentGames.test.ts b/src/API/getRecentGames.test.ts new file mode 100644 index 000000000..704705cca --- /dev/null +++ b/src/API/getRecentGames.test.ts @@ -0,0 +1,63 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import Game from '../Structures/Game.js'; +import RecentGame from '../Structures/RecentGame.js'; +import RequestData from '../Private/RequestData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getRecentGames (no input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getRecentGames()).rejects.toThrowError(Errors.NO_NICKNAME_UUID); + client.destroy(); +}); + +test('getRecentGames (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getRecentGames('3b76b69ae5134296a730ed49171ad6f8', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getRecentGames', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getRecentGames('ea805d40e8284d8d8e64e9fc8ac301ca'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + + data.forEach((game: RecentGame) => { + expect(game).toBeDefined(); + expectTypeOf(game).toEqualTypeOf(); + expect(game).toBeInstanceOf(RecentGame); + expect(game.game).toBeDefined(); + expectTypeOf(game.game).toEqualTypeOf(); + expect(game.dateTimestamp).toBeDefined(); + expectTypeOf(game.dateTimestamp).toEqualTypeOf(); + expect(game.dateAt).toBeDefined(); + expectTypeOf(game.dateAt).toEqualTypeOf(); + expect(game.mode).toBeDefined(); + expectTypeOf(game.mode).toEqualTypeOf(); + expect(game.map).toBeDefined(); + expectTypeOf(game.map).toEqualTypeOf(); + expect(game.ongoing).toBeDefined(); + expectTypeOf(game.ongoing).toEqualTypeOf(); + expect(game.endedTimestamp).toBeDefined(); + expectTypeOf(game.endedTimestamp).toEqualTypeOf(); + expect(game.endedAt).toBeDefined(); + expectTypeOf(game.endedAt).toEqualTypeOf(); + expect(game.toString()).toBeDefined(); + expect(game.toString()).toEqual(game.mode); + expectTypeOf(game.toString()).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getRecentGames.ts b/src/API/getRecentGames.ts new file mode 100644 index 000000000..a813fecae --- /dev/null +++ b/src/API/getRecentGames.ts @@ -0,0 +1,23 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RecentGame from '../Structures/RecentGame.js'; +import RequestData from '../Private/RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getRecentGames extends Endpoint { + override async execute(query: string, options?: RequestOptions): Promise | RequestData> { + if (!query) throw new Error(Errors.NO_NICKNAME_UUID); + query = await this.client.requestHandler.toUUID(query); + const res = await this.client.requestHandler.request(`/recentgames?uuid=${query}`, options); + if (res.options.raw) return res; + const games = res.data.games.map((x: any) => new RecentGame(x)); + return Object.assign(games, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getRecentGames; diff --git a/src/API/getServerInfo.js b/src/API/getServerInfo.js deleted file mode 100644 index 505a16b03..000000000 --- a/src/API/getServerInfo.js +++ /dev/null @@ -1,71 +0,0 @@ -/* eslint-disable jsdoc/require-jsdoc */ -const ServerInfo = require('../structures/ServerInfo'); -const varInt = require('../utils/varInt'); -const Errors = require('../Errors'); -const net = require('net'); -const packetsToSend = ['1500E0050E6D632E6879706978656C2E6E657463DD01', '0100', '09010000000000000000'].map((x) => - // To avoid dependency hell, these are precompiled as hex. - Buffer.from(x, 'hex') -); - -async function ping(cli) { - await cli.write(packetsToSend[2]); - const time = Date.now(); - return new Promise((resolve) => { - cli.once('data', () => { - resolve(Date.now() - time); - }); - }); -} - -async function getPing(amount, cli) { - let pingSum = 0; - for (let i = 0; i < amount; i++) { - pingSum += await ping(cli); - } - cli.destroy(); - return Math.round(pingSum / amount); -} - -function parseData(stringJson, ping) { - try { - return new ServerInfo(JSON.parse(stringJson), ping); - } catch { - return undefined; - } -} - -module.exports = async function (repeats) { - if (0 > repeats || 'number' !== typeof repeats) repeats = 3; - if (10 < repeats) repeats = 10; - let aggregatedData = ''; - let dataLength = 0; - return await new Promise((resolve, reject) => { - const cli = net.createConnection(25565, 'mc.hypixel.net', () => { - cli.write(packetsToSend[0]); - cli.write(packetsToSend[1]); - }); - cli.on('error', () => { - reject(Errors.CONNECTION_ERROR); - }); - cli.on('data', async (data) => { - if (!aggregatedData) { - const varIntBorder = data.findIndex((x) => 0x00 === x) + 1; - dataLength = varInt( - data - .toString('hex', 0, varIntBorder) - .match(/(..)/g) - .map((x) => parseInt(x, 16)) - ); - dataLength -= varIntBorder * 8; - aggregatedData += data.toString('utf-8', 5); - } else { - aggregatedData += data.toString('utf-8'); - } - - if (dataLength >= aggregatedData.length) return; - cli.removeAllListeners('data'); - resolve(parseData(aggregatedData, await getPing(repeats, cli))); - }); - }); -}; diff --git a/src/API/getSkyBlockAuction.test.ts b/src/API/getSkyBlockAuction.test.ts new file mode 100644 index 000000000..98edf5581 --- /dev/null +++ b/src/API/getSkyBlockAuction.test.ts @@ -0,0 +1,87 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockBaseAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockAuctionResult } from '../Types/API.js'; + +test('getSkyBlockAuction (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const auctions = await client.getSkyBlockAuctions(1); + if (auctions.isRaw()) return; + if (undefined === auctions.auctions[0]) return; + if (!auctions.auctions[0].auctioneerUuid) throw new Error("Something wen't wrong while fetching auctions"); + const data = await client.getSkyBlockAuction('AUCTION_ID', auctions.auctions[0].auctionId, { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockAuction (No Type Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockAuction()).rejects.toThrowError(Errors.BAD_AUCTION_FILTER); + client.destroy(); +}); + +test('getSkyBlockAuction (Bad Type Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockAuction('meow', 'meow')).rejects.toThrowError(Errors.BAD_AUCTION_FILTER); + client.destroy(); +}); + +test('getSkyBlockAuction (No Query Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockAuction('AUCTION_ID')).rejects.toThrowError(Errors.NO_UUID); + client.destroy(); +}); + +test('getSkyBlockAuction (PROFILE)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const auctions = await client.getSkyBlockAuctions(1); + if (auctions.isRaw()) return; + if (undefined === auctions.auctions[0]) return; + if (!auctions.auctions[0].auctioneerUuid) throw new Error("Something wen't wrong while fetching auctions"); + const data = await client.getSkyBlockAuction('PROFILE', auctions.auctions[0].auctioneerProfile); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.info).toBeDefined(); + expectTypeOf(data.info).toEqualTypeOf(); + expect(data.auctions).toBeDefined(); + expectTypeOf(data.auctions).toEqualTypeOf(); + client.destroy(); +}); + +test('getSkyBlockAuction (PLAYER)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const auctions = await client.getSkyBlockAuctions(1); + if (auctions.isRaw()) return; + if (undefined === auctions.auctions[0]) return; + if (!auctions.auctions[0].auctioneerUuid) throw new Error("Something wen't wrong while fetching auctions"); + const data = await client.getSkyBlockAuction('PLAYER', auctions.auctions[0].auctioneerUuid); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.info).toBeDefined(); + expectTypeOf(data.info).toEqualTypeOf(); + expect(data.auctions).toBeDefined(); + expectTypeOf(data.auctions).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockAuction.ts b/src/API/getSkyBlockAuction.ts new file mode 100644 index 000000000..0daebe64a --- /dev/null +++ b/src/API/getSkyBlockAuction.ts @@ -0,0 +1,53 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockBaseAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import type { AuctionFetchOptions, AuctionRequestOptions, SkyBlockAuctionResult } from '../Types/API.js'; + +class getSkyBlockAction extends Endpoint { + override async execute( + type: AuctionFetchOptions, + query: string, + options?: AuctionRequestOptions + ): Promise { + let filter: string | null; + if (type === undefined) throw new Error(Errors.BAD_AUCTION_FILTER); + if (query === undefined) throw new Error(Errors.NO_UUID); + + switch (type) { + case 'PROFILE': { + filter = 'profile'; + break; + } + case 'PLAYER': { + filter = 'player'; + break; + } + case 'AUCTION_ID': { + filter = 'uuid'; + break; + } + default: { + filter = null; + break; + } + } + + if (filter === null) throw new Error(Errors.BAD_AUCTION_FILTER); + + const res = await this.client.requestHandler.request(`/skyblock/auction?${filter}=${query}`, options); + if (res.options.raw) return res; + return { + info: new SkyBlockBaseAuctionInfo(res.data), + auctions: res.data.auctions.map( + (Auction: Record) => new SkyBlockAuction(Auction, options?.includeItemBytes ?? false) + ), + isRaw(): this is RequestData { + return false; + } + }; + } +} + +export default getSkyBlockAction; diff --git a/src/API/getSkyBlockAuctions.test.ts b/src/API/getSkyBlockAuctions.test.ts new file mode 100644 index 000000000..71315c571 --- /dev/null +++ b/src/API/getSkyBlockAuctions.test.ts @@ -0,0 +1,80 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type SkyBlockAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.js'; +import type { SkyBlockAuctionsResult } from '../Types/API.js'; + +test('getSkyBlockAuctions (No Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockAuctions()).rejects.toThrowError(Errors.INVALID_OPTION_VALUE); + client.destroy(); +}); + +test('getSkyBlockAuctions (Negative Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getSkyBlockAuctions(-1)).rejects.toThrowError(Errors.INVALID_OPTION_VALUE); + client.destroy(); +}); + +test('getSkyBlockAuctions (Page 0)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getSkyBlockAuctions(0)).rejects.toThrowError(Errors.INVALID_OPTION_VALUE); + client.destroy(); +}); + +test('getSkyBlockAuctions (String Input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockAuctions('hi')).rejects.toThrowError(Errors.INVALID_OPTION_VALUE); + client.destroy(); +}); + +test('getSkyBlockAuctions (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockAuctions(1, { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockAuctions (One Page)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockAuctions(1); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.info).toBeDefined(); + expectTypeOf(data.info).toEqualTypeOf(); + expect(data.auctions).toBeDefined(); + expectTypeOf(data.auctions).toEqualTypeOf(); + client.destroy(); +}); + +test('getSkyBlockAuctions (All Pages)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockAuctions('*'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.info).toBeDefined(); + expectTypeOf(data.info).toEqualTypeOf(); + expect(data.auctions).toBeDefined(); + expectTypeOf(data.auctions).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockAuctions.ts b/src/API/getSkyBlockAuctions.ts new file mode 100644 index 000000000..93042bdf3 --- /dev/null +++ b/src/API/getSkyBlockAuctions.ts @@ -0,0 +1,56 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.js'; +import type RequestData from '../Private/RequestData.js'; +import type { AuctionRequestOptions, SkyBlockAuctionsResult } from '../Types/API.js'; + +class getSkyBlockAuctions extends Endpoint { + override async execute( + query: number | '*', + options?: AuctionRequestOptions + ): Promise { + if (!query) throw new Error(Errors.INVALID_OPTION_VALUE); + if (typeof query === 'number' && query <= 0) throw new Error(Errors.INVALID_OPTION_VALUE); + if (typeof query !== 'number' && query !== '*') throw new Error(Errors.INVALID_OPTION_VALUE); + if (query === '*') return await this.getAllPages(); + return await this.getPage(query, options); + } + + async getAllPages(): Promise { + const page = 0; + const { info, auctions } = (await this.getPage(page)) as SkyBlockAuctionsResult; + const pages = info.totalPages; + const requests = []; + for (let i = 1; i < pages; i++) { + requests.push(this.getPage(i)); + } + const results = (await Promise.all(requests)) as SkyBlockAuctionsResult[]; + results.forEach(({ auctions: newAuctions }) => { + auctions.push(...newAuctions); + }); + return { + info, + auctions, + isRaw(): this is RequestData { + return false; + } + }; + } + + private async getPage(page: number, options?: AuctionRequestOptions): Promise { + const res = await this.client.requestHandler.request(`/skyblock/auctions?page=${page}`, options); + if (options?.raw) return res; + return { + info: new SkyBlockAuctionInfo(res.data), + auctions: res.data.auctions.map( + (Auction: Record) => new SkyBlockAuction(Auction, options?.includeItemBytes || false) + ), + isRaw(): this is RequestData { + return false; + } + }; + } +} + +export default getSkyBlockAuctions; diff --git a/src/API/getSkyBlockBazaar.test.ts b/src/API/getSkyBlockBazaar.test.ts new file mode 100644 index 000000000..4bb9a51b4 --- /dev/null +++ b/src/API/getSkyBlockBazaar.test.ts @@ -0,0 +1,33 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockBazaar from '../Structures/SkyBlock/Bazaar/SkyBlockBazaar.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type SkyBlockBazaarProduct from '../Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.js'; + +test('getSkyBlockBazaar (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockBazaar({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockBazaar', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockBazaar(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdated).toBeDefined(); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.products).toBeDefined(); + expectTypeOf(data.products).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockBazaar.ts b/src/API/getSkyBlockBazaar.ts new file mode 100644 index 000000000..e183aefad --- /dev/null +++ b/src/API/getSkyBlockBazaar.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockBazaar from '../Structures/SkyBlock/Bazaar/SkyBlockBazaar.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockBazaar extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/skyblock/bazaar', options); + if (res.options.raw) return res; + return new SkyBlockBazaar(res.data); + } +} + +export default getSkyBlockBazaar; diff --git a/src/API/getSkyBlockBingo.test.ts b/src/API/getSkyBlockBingo.test.ts new file mode 100644 index 000000000..72419513d --- /dev/null +++ b/src/API/getSkyBlockBingo.test.ts @@ -0,0 +1,45 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockBingo from '../Structures/SkyBlock/Bingo/SkyBlockBingo.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type SkyBlockBingoGoal from '../Structures/SkyBlock/Bingo/SkyBlockBingoGoal.js'; + +test('getSkyBlockBingo (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockBingo({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockBingo', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockBingo(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.start).toBeDefined(); + expectTypeOf(data.start).toEqualTypeOf(); + expect(data.startAt).toBeDefined(); + expectTypeOf(data.startAt).toEqualTypeOf(); + expect(data.end).toBeDefined(); + expectTypeOf(data.end).toEqualTypeOf(); + expect(data.endAt).toBeDefined(); + expectTypeOf(data.endAt).toEqualTypeOf(); + expect(data.goals).toBeDefined(); + expectTypeOf(data.goals).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockBingo.ts b/src/API/getSkyBlockBingo.ts new file mode 100644 index 000000000..1369770fb --- /dev/null +++ b/src/API/getSkyBlockBingo.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockBingo from '../Structures/SkyBlock/Bingo/SkyBlockBingo.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockBingo extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/skyblock/bingo', options); + if (res.options.raw) return res; + return new SkyBlockBingo(res.data); + } +} + +export default getSkyBlockBingo; diff --git a/src/API/getSkyBlockCollections.test.ts b/src/API/getSkyBlockCollections.test.ts new file mode 100644 index 000000000..42690d571 --- /dev/null +++ b/src/API/getSkyBlockCollections.test.ts @@ -0,0 +1,45 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockCollection from '../Structures/SkyBlock/Collections/SkyBlockCollection.js'; +import SkyBlockCollections from '../Structures/SkyBlock/Collections/SkyBlockCollections.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getSkyBlockCollections (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockCollections({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockCollections', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockCollections(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdated).toBeDefined(); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.version).toBeDefined(); + expectTypeOf(data.version).toEqualTypeOf(); + expect(data.farming).toBeDefined(); + expectTypeOf(data.farming).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.combat).toBeDefined(); + expectTypeOf(data.combat).toEqualTypeOf(); + expect(data.foraging).toBeDefined(); + expectTypeOf(data.foraging).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.rift).toBeDefined(); + expectTypeOf(data.rift).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockCollections.ts b/src/API/getSkyBlockCollections.ts new file mode 100644 index 000000000..de7d73797 --- /dev/null +++ b/src/API/getSkyBlockCollections.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockCollections from '../Structures/SkyBlock/Collections/SkyBlockCollections.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockCollections extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/skyblock/items', options); + if (res.options.raw) return res; + return new SkyBlockCollections(res.data); + } +} + +export default getSkyBlockCollections; diff --git a/src/API/getSkyBlockElection.test.ts b/src/API/getSkyBlockElection.test.ts new file mode 100644 index 000000000..c1a0f5f2d --- /dev/null +++ b/src/API/getSkyBlockElection.test.ts @@ -0,0 +1,35 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockElection from '../Structures/SkyBlock/Election/SkyBlockElection.js'; +import SkyBlockElectionData from '../Structures/SkyBlock/Election/SkyBlockElectionData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getSkyBlockElection (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockElection({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockElection', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockElection(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdatedTimestamp).toBeDefined(); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.lastElectionResults).toBeDefined(); + expectTypeOf(data.lastElectionResults).toEqualTypeOf(); + expect(data.currentElection).toBeDefined(); + expectTypeOf(data.currentElection).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockElection.ts b/src/API/getSkyBlockElection.ts new file mode 100644 index 000000000..eb8e0282c --- /dev/null +++ b/src/API/getSkyBlockElection.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockElectionData from '../Structures/SkyBlock/Election/SkyBlockElectionData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockElection extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/skyblock/election', options); + if (res.options.raw) return res; + return new SkyBlockElectionData(res.data); + } +} + +export default getSkyBlockElection; diff --git a/src/API/getSkyBlockEndedAuctions.test.ts b/src/API/getSkyBlockEndedAuctions.test.ts new file mode 100644 index 000000000..fc42c663c --- /dev/null +++ b/src/API/getSkyBlockEndedAuctions.test.ts @@ -0,0 +1,32 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockBaseAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockAuctionResult } from '../Types/API.js'; + +test('getSkyBlockEndedAuctions (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockEndedAuctions({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockEndedAuctions', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockEndedAuctions(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.info).toBeDefined(); + expectTypeOf(data.info).toEqualTypeOf(); + expect(data.auctions).toBeDefined(); + expectTypeOf(data.auctions).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockEndedAuctions.ts b/src/API/getSkyBlockEndedAuctions.ts new file mode 100644 index 000000000..b48e7eb6c --- /dev/null +++ b/src/API/getSkyBlockEndedAuctions.ts @@ -0,0 +1,21 @@ +import Endpoint from '../Private/Endpoint.js'; +import SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockBaseAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import type RequestData from '../Private/RequestData.js'; +import type { AuctionRequestOptions, SkyBlockAuctionResult } from '../Types/API.js'; + +class getSkyBlockEndedAuctions extends Endpoint { + override async execute(options?: AuctionRequestOptions): Promise { + const res = await this.client.requestHandler.request('/skyblock/auctions_ended', options); + if (res.options.raw) return res; + return { + info: new SkyBlockBaseAuctionInfo(res.data), + auctions: res.data.auctions.map((Auction: Record) => new SkyBlockAuction(Auction)), + isRaw(): this is RequestData { + return false; + } + }; + } +} + +export default getSkyBlockEndedAuctions; diff --git a/src/API/getSkyBlockFireSales.test.ts b/src/API/getSkyBlockFireSales.test.ts new file mode 100644 index 000000000..5178eb802 --- /dev/null +++ b/src/API/getSkyBlockFireSales.test.ts @@ -0,0 +1,64 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockFireSale from '../Structures/SkyBlock/FireSale/SkyBlockFireSale.js'; +import { defaultRequestData } from '../../vitest.setup.js'; +import { expect, expectTypeOf, test, vi } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getSkyBlockFireSales (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockFireSales({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockFireSales', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + json: () => + /* eslint-disable camelcase */ + Promise.resolve({ + success: true, + sales: [ + { item_id: 'PET_SKIN_LION_WHITE', start: 1725120000000, end: 1725552000000, amount: 6500, price: 650 }, + { item_id: 'PET_SKIN_LION_BLACK', start: 1725120000000, end: 1725552000000, amount: 6500, price: 650 } + ] + }) + /* eslint-enable camelcase */ + } as any); + + const data = await client.getSkyBlockFireSales(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((FireSale: SkyBlockFireSale) => { + expect(FireSale.itemId).toBeDefined(); + expectTypeOf(FireSale.itemId).toEqualTypeOf(); + expect(FireSale.startTimestamp).toBeDefined(); + expectTypeOf(FireSale.startTimestamp).toEqualTypeOf(); + expect(FireSale.startAt).toBeDefined(); + expectTypeOf(FireSale.startAt).toEqualTypeOf(); + expect(FireSale.endTimestamp).toBeDefined(); + expectTypeOf(FireSale.endTimestamp).toEqualTypeOf(); + expect(FireSale.endAt).toBeDefined(); + expectTypeOf(FireSale.endAt).toEqualTypeOf(); + expect(FireSale.amount).toBeDefined(); + expectTypeOf(FireSale.amount).toEqualTypeOf(); + expect(FireSale.price).toBeDefined(); + expectTypeOf(FireSale.price).toEqualTypeOf(); + expect(FireSale.toString).toBeDefined(); + expectTypeOf(FireSale.toString).toEqualTypeOf<() => string>(); + expect(FireSale.toString()).toBeDefined(); + expect(FireSale.toString()).toBe(FireSale.itemId); + expectTypeOf(FireSale.toString()).toEqualTypeOf(); + }); + vi.restoreAllMocks(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockFireSales.ts b/src/API/getSkyBlockFireSales.ts new file mode 100644 index 000000000..675c808e2 --- /dev/null +++ b/src/API/getSkyBlockFireSales.ts @@ -0,0 +1,20 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockFireSale from '../Structures/SkyBlock/FireSale/SkyBlockFireSale.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getSkyBlockSkyBlockFireSales extends Endpoint { + override async execute(options?: RequestOptions): Promise | RequestData> { + const res = await this.client.requestHandler.request('/skyblock/firesales', options); + if (res.options.raw) return res; + const fileSales = res.data.sales.map((sale: any) => new SkyBlockFireSale(sale)); + return Object.assign(fileSales, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getSkyBlockSkyBlockFireSales; diff --git a/src/API/getSkyBlockGarden.test.ts b/src/API/getSkyBlockGarden.test.ts new file mode 100644 index 000000000..5c10cc16c --- /dev/null +++ b/src/API/getSkyBlockGarden.test.ts @@ -0,0 +1,60 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockGardenActiveVisitor from '../Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.js'; +import SkyBlockGardenComposter from '../Structures/SkyBlock/Garden/SkyBlockGardenComposter.js'; +import SkyBlockGardenCropMilestones from '../Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.js'; +import SkyBlockGardenCropsUpgrades from '../Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.js'; +import SkyBlockGardenVisitors from '../Structures/SkyBlock/Garden/SkyBlockGardenVisitors.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BarnPlot, BarnSkin, SkillLevelData } from '../Types/SkyBlock.js'; + +test('getSkyBlockGarden (no input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockGarden()).rejects.toThrowError(Errors.NO_UUID); + client.destroy(); +}); + +test('getSkyBlockGarden (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockGarden('ed9b9d6d-d9b7-43b1-9841-5d0c20b55494', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + client.destroy(); +}); + +test('getSkyBlockGarden', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockGarden('ed9b9d6d-d9b7-43b1-9841-5d0c20b55494'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGarden); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.barnSkin).toBeDefined(); + expectTypeOf(data.barnSkin).toEqualTypeOf(); + expect(data.unlockedBarnSkins).toBeDefined(); + expectTypeOf(data.unlockedBarnSkins).toEqualTypeOf(); + expect(data.unlockedPlots).toBeDefined(); + expectTypeOf(data.unlockedPlots).toEqualTypeOf(); + expect(data.visitors).toBeDefined(); + expectTypeOf(data.visitors).toEqualTypeOf(); + expect(data.currentVisitors).toBeDefined(); + expectTypeOf(data.currentVisitors).toEqualTypeOf(); + expect(data.cropMilestones).toBeDefined(); + expectTypeOf(data.cropMilestones).toEqualTypeOf(); + expect(data.composter).toBeDefined(); + expectTypeOf(data.composter).toEqualTypeOf(); + expect(data.cropUpgrades).toBeDefined(); + expectTypeOf(data.cropUpgrades).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockGarden.ts b/src/API/getSkyBlockGarden.ts new file mode 100644 index 000000000..99d154b6c --- /dev/null +++ b/src/API/getSkyBlockGarden.ts @@ -0,0 +1,16 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockGarden extends Endpoint { + override async execute(profileId: string, options?: RequestOptions): Promise { + if (!profileId) throw new Error(Errors.NO_UUID); + const res = await this.client.requestHandler.request(`/skyblock/garden?profile=${profileId}`, options); + if (res.options.raw) return res; + return new SkyBlockGarden(res.data.garden); + } +} + +export default getSkyBlockGarden; diff --git a/src/API/getSkyBlockItems.test.ts b/src/API/getSkyBlockItems.test.ts new file mode 100644 index 000000000..4684d64ff --- /dev/null +++ b/src/API/getSkyBlockItems.test.ts @@ -0,0 +1,32 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockItem from '../Structures/SkyBlock/SkyBlockItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getSkyBlockItems (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockItems({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockItems', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockItems(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((item: SkyBlockItem) => { + expect(item).toBeDefined(); + expect(item).toBeInstanceOf(SkyBlockItem); + expectTypeOf(item).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getSkyBlockItems.ts b/src/API/getSkyBlockItems.ts new file mode 100644 index 000000000..30ba15361 --- /dev/null +++ b/src/API/getSkyBlockItems.ts @@ -0,0 +1,20 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockItem from '../Structures/SkyBlock/SkyBlockItem.js'; +import type { RequestOptions } from '../Types/Requests.js'; +import type { WithRaw } from '../Types/API.js'; + +class getSkyBlockItems extends Endpoint { + override async execute(options?: RequestOptions): Promise | RequestData> { + const res = await this.client.requestHandler.request('/resources/skyblock/items', options); + if (res.options.raw) return res; + const items = res.data.items.map((item: Record) => new SkyBlockItem(item)); + return Object.assign(items, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getSkyBlockItems; diff --git a/src/API/getSkyBlockMuseum.test.ts b/src/API/getSkyBlockMuseum.test.ts new file mode 100644 index 000000000..d54dab5fd --- /dev/null +++ b/src/API/getSkyBlockMuseum.test.ts @@ -0,0 +1,40 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockMuseum from '../Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import SkyBlockMuseumMember from '../Structures/SkyBlock/Museum/SkyBlockMuseumMember.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UUID } from '../Types/Global.js'; + +test('getSkyBlockMuseum (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockMuseum('63fe6f4c-4b06-43b2-abd0-2d15dc303e41', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockMuseum (No input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockMuseum()).rejects.toThrowError(Errors.NO_UUID); + client.destroy(); +}); + +test('getSkyBlockMuseum', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockMuseum('63fe6f4c-4b06-43b2-abd0-2d15dc303e41'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf>(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockMuseum.ts b/src/API/getSkyBlockMuseum.ts new file mode 100644 index 000000000..6c2f329d0 --- /dev/null +++ b/src/API/getSkyBlockMuseum.ts @@ -0,0 +1,16 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockMuseum from '../Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockMuseum extends Endpoint { + override async execute(profileId: string, options?: RequestOptions): Promise { + if (!profileId) throw new Error(Errors.NO_UUID); + const res = await this.client.requestHandler.request(`/skyblock/museum?profile=${profileId}`, options); + if (res.options.raw) return res; + return new SkyBlockMuseum(res.data); + } +} + +export default getSkyBlockMuseum; diff --git a/src/API/getSkyBlockNews.test.ts b/src/API/getSkyBlockNews.test.ts new file mode 100644 index 000000000..ec1986933 --- /dev/null +++ b/src/API/getSkyBlockNews.test.ts @@ -0,0 +1,37 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockNews from '../Structures/SkyBlock/News/SkyBlockNews.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WithRaw } from '../Types/API.js'; + +test('getSkyBlockNews (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockNews({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockNews', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockNews(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf | RequestData>(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((news: SkyBlockNews) => { + expect(news.title).toBeDefined(); + expectTypeOf(news.title).toEqualTypeOf(); + expect(news.link).toBeDefined(); + expectTypeOf(news.link).toEqualTypeOf(); + expect(news.date).toBeDefined(); + expectTypeOf(news.date).toEqualTypeOf(); + expect(news.version).toBeDefined(); + expectTypeOf(news.version).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getSkyBlockNews.ts b/src/API/getSkyBlockNews.ts new file mode 100644 index 000000000..550efdca2 --- /dev/null +++ b/src/API/getSkyBlockNews.ts @@ -0,0 +1,19 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockNews from '../Structures/SkyBlock/News/SkyBlockNews.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockNews extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/skyblock/news', options); + if (res.options.raw) return res; + const news = res.data.items.map((news: any) => new SkyBlockNews(news)); + return Object.assign(news, { + isRaw(): this is RequestData { + return false; + } + }); + } +} + +export default getSkyBlockNews; diff --git a/src/API/getSkyBlockProfile.test.ts b/src/API/getSkyBlockProfile.test.ts new file mode 100644 index 000000000..c5df80acc --- /dev/null +++ b/src/API/getSkyBlockProfile.test.ts @@ -0,0 +1,76 @@ +/* eslint-disable @stylistic/max-len */ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockMember from '../Structures/SkyBlock/Member/SkyBlockMember.js'; +import SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import SkyBlockProfileBanking from '../Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.js'; +import SkyBlockProfileCommunityUpgrades from '../Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockProfileName, SkyBlockProfileType } from '../Types/SkyBlock.js'; +/* eslint-enable @stylistic/max-len */ + +test('getSkyBlockProfile (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockProfile('14727faefbdc4aff848cd2713eb9939e', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockProfile (no input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockProfile()).rejects.toThrowError(Errors.NO_UUID); + client.destroy(); +}); + +test('getSkyBlockProfile (no profiles)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getSkyBlockProfile('ce6685dd-78dd-4418-9f6f-b01cf9778daa')).rejects.toThrowError( + Errors.NO_SKYBLOCK_PROFILES + ); + client.destroy(); +}); + +test('getSkyBlockProfile', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockProfile('ed9b9d6d-d9b7-43b1-9841-5d0c20b55494'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.profileId).toBeDefined(); + expectTypeOf(data.profileId).toEqualTypeOf(); + expect(data.communityUpgrades).toBeDefined(); + expectTypeOf(data.communityUpgrades).toEqualTypeOf(); + expect(data.createdTimestamp).toBeDefined(); + expectTypeOf(data.createdTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.gameMode).toBeDefined(); + expectTypeOf(data.gameMode).toEqualTypeOf(); + expect(data.banking).toBeDefined(); + expectTypeOf(data.banking).toEqualTypeOf(); + expect(data.profileName).toBeDefined(); + expectTypeOf(data.profileName).toEqualTypeOf(); + expect(data.selected).toBeDefined(); + expectTypeOf(data.selected).toEqualTypeOf(); + expect(data.garden).toBeDefined(); + expectTypeOf(data.garden).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockProfile.ts b/src/API/getSkyBlockProfile.ts new file mode 100644 index 000000000..e4ceb5ec1 --- /dev/null +++ b/src/API/getSkyBlockProfile.ts @@ -0,0 +1,40 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import type SkyBlockMuseum from '../Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import type { SkyBlockRequestOptions } from '../Types/API.js'; + +class getSkyBlockProfile extends Endpoint { + override async execute(profileId: string, options?: SkyBlockRequestOptions): Promise { + if (!profileId) throw new Error(Errors.NO_UUID); + const res = await this.client.requestHandler.request(`/skyblock/profile?profile=${profileId}`, options); + if (res.options.raw) return res; + if (!res.data.profile) throw new Error(Errors.NO_SKYBLOCK_PROFILES); + const garden = options?.museum ? await this.handleGettingSkyBlockGarden(res.data.profile.profile_id) : undefined; + const museum = options?.museum ? await this.handleGettingSkyBlockMuseum(res.data.profile.profile_id) : undefined; + const parsedProfile = new SkyBlockProfile(res.data.profile, { uuid: null, garden, museum }); + return parsedProfile; + } + + private async handleGettingSkyBlockGarden(profileId: string): Promise { + try { + const garden = await this.client.getSkyBlockGarden(profileId); + return garden as SkyBlockGarden; + } catch { + return undefined; + } + } + + private async handleGettingSkyBlockMuseum(profileId: string): Promise { + try { + const museum = await this.client.getSkyBlockMuseum(profileId); + return museum as SkyBlockMuseum; + } catch { + return undefined; + } + } +} + +export default getSkyBlockProfile; diff --git a/src/API/getSkyBlockProfiles.test.ts b/src/API/getSkyBlockProfiles.test.ts new file mode 100644 index 000000000..1356a243f --- /dev/null +++ b/src/API/getSkyBlockProfiles.test.ts @@ -0,0 +1,83 @@ +/* eslint-disable @stylistic/max-len */ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockMember from '../Structures/SkyBlock/Member/SkyBlockMember.js'; +import SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import SkyBlockProfileBanking from '../Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.js'; +import SkyBlockProfileCommunityUpgrades from '../Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockProfileName, SkyBlockProfileType } from '../Types/SkyBlock.js'; +import type { WithSelectedProfile } from '../Types/API.js'; +/* eslint-enable @stylistic/max-len */ + +test('getSkyBlockProfiles (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf< + WithSelectedProfile> | RequestData + >(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockProfiles (no input)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.getSkyBlockProfiles()).rejects.toThrowError(Errors.NO_NICKNAME_UUID); + client.destroy(); +}); + +test('getSkyBlockProfiles (no profiles)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + await expect(() => client.getSkyBlockProfiles('b491990d53fd4c5fa61e19d58cc7eddf')).rejects.toThrowError( + Errors.NO_SKYBLOCK_PROFILES + ); + client.destroy(); +}); + +test('getSkyBlockProfiles', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockProfiles('14727faefbdc4aff848cd2713eb9939e'); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf< + WithSelectedProfile> | RequestData + >(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + data.forEach((profile) => { + expect(profile).toBeDefined(); + expectTypeOf(profile).toEqualTypeOf(); + expect(profile.profileId).toBeDefined(); + expectTypeOf(profile.profileId).toEqualTypeOf(); + expect(profile.communityUpgrades).toBeDefined(); + expectTypeOf(profile.communityUpgrades).toEqualTypeOf(); + expect(profile.createdTimestamp).toBeDefined(); + expectTypeOf(profile.createdTimestamp).toEqualTypeOf(); + expect(profile.createdAt).toBeDefined(); + expectTypeOf(profile.createdAt).toEqualTypeOf(); + expect(profile.members).toBeDefined(); + expectTypeOf(profile.members).toEqualTypeOf(); + expect(profile.me).toBeDefined(); + expectTypeOf(profile.me).toEqualTypeOf(); + expect(profile.gameMode).toBeDefined(); + expectTypeOf(profile.gameMode).toEqualTypeOf(); + expect(profile.banking).toBeDefined(); + expectTypeOf(profile.banking).toEqualTypeOf(); + expect(profile.profileName).toBeDefined(); + expectTypeOf(profile.profileName).toEqualTypeOf(); + expect(profile.selected).toBeDefined(); + expectTypeOf(profile.selected).toEqualTypeOf(); + expect(profile.garden).toBeDefined(); + expectTypeOf(profile.garden).toEqualTypeOf(); + }); + client.destroy(); +}); diff --git a/src/API/getSkyBlockProfiles.ts b/src/API/getSkyBlockProfiles.ts new file mode 100644 index 000000000..d0a5a6930 --- /dev/null +++ b/src/API/getSkyBlockProfiles.ts @@ -0,0 +1,64 @@ +import Endpoint from '../Private/Endpoint.js'; +import Errors from '../Errors.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockGarden from '../Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import type SkyBlockMuseum from '../Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import type { SkyBlockProfileName } from '../Types/SkyBlock.js'; +import type { SkyBlockRequestOptions, WithSelectedProfile } from '../Types/API.js'; + +class getSkyBlockProfiles extends Endpoint { + override async execute( + query: string, + options?: SkyBlockRequestOptions + ): Promise> | RequestData> { + if (!query) throw new Error(Errors.NO_NICKNAME_UUID); + query = await this.client.requestHandler.toUUID(query); + const res = await this.client.requestHandler.request(`/skyblock/profiles?uuid=${query}`, options); + if (res.options.raw) return res; + if (!res.data.profiles || !res.data.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES); + const profiles: Map = new Map(); + for (const profile of res.data.profiles) { + const garden = options?.garden ? await this.handleGettingSkyBlockGarden(profile.profile_id) : undefined; + const museum = options?.museum ? await this.handleGettingSkyBlockMuseum(profile.profile_id) : undefined; + const parsedProfile = new SkyBlockProfile(profile, { uuid: query, garden, museum }); + profiles.set(parsedProfile.profileName, parsedProfile); + } + + const selectedProfile = Array.from(profiles.values()).find( + (profile): profile is SkyBlockProfile & { me: NonNullable } => + profile.selected === true && this.hasMe(profile) + ); + + return Object.assign(profiles, { + isRaw(): this is RequestData { + return false; + }, + selectedProfile + }); + } + + private hasMe(profile: SkyBlockProfile): profile is SkyBlockProfile & { me: NonNullable } { + return profile.me !== null; + } + + private async handleGettingSkyBlockGarden(profileId: string): Promise { + try { + const garden = await this.client.getSkyBlockGarden(profileId); + return garden as SkyBlockGarden; + } catch { + return undefined; + } + } + + private async handleGettingSkyBlockMuseum(profileId: string): Promise { + try { + const museum = await this.client.getSkyBlockMuseum(profileId); + return museum as SkyBlockMuseum; + } catch { + return undefined; + } + } +} + +export default getSkyBlockProfiles; diff --git a/src/API/getSkyBlockSkills.test.ts b/src/API/getSkyBlockSkills.test.ts new file mode 100644 index 000000000..4a671e28d --- /dev/null +++ b/src/API/getSkyBlockSkills.test.ts @@ -0,0 +1,55 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockSkill from '../Structures/SkyBlock/Skills/SkyBlockSkill.js'; +import SkyBlockSkills from '../Structures/SkyBlock/Skills/SkyBlockSkills.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getSkyBlockSkills (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockSkills({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getSkyBlockSkills', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getSkyBlockSkills(); + expect(data).toBeDefined(); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.lastUpdated).toBeDefined(); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.version).toBeDefined(); + expectTypeOf(data.version).toEqualTypeOf(); + expect(data.farming).toBeDefined(); + expectTypeOf(data.farming).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.combat).toBeDefined(); + expectTypeOf(data.combat).toEqualTypeOf(); + expect(data.foraging).toBeDefined(); + expectTypeOf(data.foraging).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.enchanting).toBeDefined(); + expectTypeOf(data.enchanting).toEqualTypeOf(); + expect(data.alchemy).toBeDefined(); + expectTypeOf(data.alchemy).toEqualTypeOf(); + expect(data.carpentry).toBeDefined(); + expectTypeOf(data.carpentry).toEqualTypeOf(); + expect(data.runecrafting).toBeDefined(); + expectTypeOf(data.runecrafting).toEqualTypeOf(); + expect(data.social).toBeDefined(); + expectTypeOf(data.social).toEqualTypeOf(); + expect(data.taming).toBeDefined(); + expectTypeOf(data.taming).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getSkyBlockSkills.ts b/src/API/getSkyBlockSkills.ts new file mode 100644 index 000000000..c84892ad3 --- /dev/null +++ b/src/API/getSkyBlockSkills.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import SkyBlockSkills from '../Structures/SkyBlock/Skills/SkyBlockSkills.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getSkyBlockSkills extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/resources/skyblock/skills', options); + if (res.options.raw) return res; + return new SkyBlockSkills(res.data); + } +} + +export default getSkyBlockSkills; diff --git a/src/API/getStatus.js b/src/API/getStatus.js deleted file mode 100644 index e66ec8eb8..000000000 --- a/src/API/getStatus.js +++ /dev/null @@ -1,9 +0,0 @@ -const toUuid = require('../utils/toUuid'); -module.exports = async function (query) { - const Status = require('../structures/Status'); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/status?uuid=${query}`); - if (res.raw) return res; - return new Status(res.session); -}; diff --git a/src/API/getStatus.test.ts b/src/API/getStatus.test.ts new file mode 100644 index 000000000..d3c143207 --- /dev/null +++ b/src/API/getStatus.test.ts @@ -0,0 +1,63 @@ +import Client from '../Client.js'; +import Game from '../Structures/Game.js'; +import RequestData from '../Private/RequestData.js'; +import Status from '../Structures/Status.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; + +test('getStatus (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getStatus('4982eac19ae7422891b61a17a74c87a2', { raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getStatus', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getStatus('370d6421b761456fadf28c43fe5c4bcf'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Status); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.online).toBeDefined(); + expectTypeOf(data.online).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + if (data.game) { + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.game.game).toBeDefined(); + expectTypeOf(data.game.game).toEqualTypeOf(); + expect(data.game.id).toBeDefined(); + expectTypeOf(data.game.id).toEqualTypeOf(); + expect(data.game.code).toBeDefined(); + expectTypeOf(data.game.code).toEqualTypeOf(); + expect(data.game.name).toBeDefined(); + expectTypeOf(data.game.name).toEqualTypeOf(); + expect(data.game.found).toBeDefined(); + expectTypeOf(data.game.found).toEqualTypeOf(); + expect(data.game.toString()).toBeDefined(); + expect(data.game.toString()).toBe(data.game.name); + expectTypeOf(data.game.toString()).toEqualTypeOf(); + expect(Game.IDS).toBeDefined(); + expectTypeOf(Game.IDS).toEqualTypeOf(); + expect(Game.CODES).toBeDefined(); + expectTypeOf(Game.CODES).toEqualTypeOf(); + expect(Game.NAMES).toBeDefined(); + expectTypeOf(Game.NAMES).toEqualTypeOf(); + } + expect(data.mode).toBeDefined(); + expectTypeOf(data.mode).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.toString()).toBeDefined(); + expectTypeOf(data.toString()).toEqualTypeOf<'Online' | 'Offline'>(); + expect(data.toString()).toBe(data.online ? 'Online' : 'Offline'); + client.destroy(); +}); diff --git a/src/API/getStatus.ts b/src/API/getStatus.ts new file mode 100644 index 000000000..c4ac62d84 --- /dev/null +++ b/src/API/getStatus.ts @@ -0,0 +1,15 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import Status from '../Structures/Status.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getStatus extends Endpoint { + override async execute(query: string, options?: RequestOptions): Promise { + query = await this.client.requestHandler.toUUID(query); + const res = await this.client.requestHandler.request(`/status?uuid=${query}`, options); + if (res.options.raw) return res; + return new Status(res.data.session); + } +} + +export default getStatus; diff --git a/src/API/getWatchdogStats.js b/src/API/getWatchdogStats.js deleted file mode 100644 index 693d73e10..000000000 --- a/src/API/getWatchdogStats.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const WatchdogStats = require('../structures/Watchdog/Stats'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/punishmentstats'); - if (res.raw) return res; - return new WatchdogStats(res); -}; diff --git a/src/API/getWatchdogStats.test.ts b/src/API/getWatchdogStats.test.ts new file mode 100644 index 000000000..bee815fc8 --- /dev/null +++ b/src/API/getWatchdogStats.test.ts @@ -0,0 +1,42 @@ +import Client from '../Client.js'; +import RequestData from '../Private/RequestData.js'; +import WatchdogStats from '../Structures/WatchdogStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('getWatchdogStats (raw)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getWatchdogStats({ raw: true }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RequestData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(true); + client.destroy(); +}); + +test('getWatchdogStats', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const data = await client.getWatchdogStats(); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WatchdogStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isRaw()).toBe(false); + if (data.isRaw()) return; + expect(data.byWatchdogTotal).toBeDefined(); + expect(data.byWatchdogTotal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogTotal).toEqualTypeOf(); + expect(data.byWatchdogLastMinute).toBeDefined(); + expect(data.byWatchdogLastMinute).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogLastMinute).toEqualTypeOf(); + expect(data.byWatchdogRollingDay).toBeDefined(); + expect(data.byWatchdogRollingDay).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogRollingDay).toEqualTypeOf(); + expect(data.byStaffTotal).toBeDefined(); + expect(data.byStaffTotal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byStaffTotal).toEqualTypeOf(); + expect(data.byStaffRollingDay).toBeDefined(); + expect(data.byStaffRollingDay).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byStaffRollingDay).toEqualTypeOf(); + client.destroy(); +}); diff --git a/src/API/getWatchdogStats.ts b/src/API/getWatchdogStats.ts new file mode 100644 index 000000000..e9e5706a2 --- /dev/null +++ b/src/API/getWatchdogStats.ts @@ -0,0 +1,14 @@ +import Endpoint from '../Private/Endpoint.js'; +import RequestData from '../Private/RequestData.js'; +import WatchdogStats from '../Structures/WatchdogStats.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class getWatchdogStats extends Endpoint { + override async execute(options?: RequestOptions): Promise { + const res = await this.client.requestHandler.request('/punishmentstats', options); + if (res.options.raw) return res; + return new WatchdogStats(res.data); + } +} + +export default getWatchdogStats; diff --git a/src/API/housing/getActiveHouses.js b/src/API/housing/getActiveHouses.js deleted file mode 100644 index db04c041d..000000000 --- a/src/API/housing/getActiveHouses.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const House = require('../../structures/House'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/housing/active'); - if (res.raw) return res; - return res.length ? res.map((b) => new House(b)) : []; -}; diff --git a/src/API/housing/getHouse.js b/src/API/housing/getHouse.js deleted file mode 100644 index 6034403ac..000000000 --- a/src/API/housing/getHouse.js +++ /dev/null @@ -1,9 +0,0 @@ -const Errors = require('../../Errors'); -module.exports = async function (query) { - if (!query) throw new Error(Errors.NO_UUID); - const House = require('../../structures/House'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/housing/house?house=${query}`); - if (res.raw) return res; - return new House(res); -}; diff --git a/src/API/housing/getPlayerHouses.js b/src/API/housing/getPlayerHouses.js deleted file mode 100644 index 4c5050389..000000000 --- a/src/API/housing/getPlayerHouses.js +++ /dev/null @@ -1,11 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -module.exports = async function (query) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - const House = require('../../structures/House'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/housing/houses?player=${query}`); - if (res.raw) return res; - return res.length ? res.map((b) => new House(b)) : []; -}; diff --git a/src/API/index.js b/src/API/index.js deleted file mode 100644 index 575ed9874..000000000 --- a/src/API/index.js +++ /dev/null @@ -1,35 +0,0 @@ -module.exports = { - getAchievements: require('./getAchievements.js'), - getAPIStatus: require('./getAPIStatus.js'), - getBoosters: require('./getBoosters.js'), - getChallenges: require('./getChallenges.js'), - getGameCounts: require('./getGameCounts.js'), - getGuild: require('./getGuild.js'), - getGuildAchievements: require('./getGuildAchievements.js'), - getLeaderboards: require('./getLeaderboards.js'), - getPlayer: require('./getPlayer.js'), - getQuests: require('./getQuests.js'), - getRecentGames: require('./getRecentGames.js'), - getServerInfo: require('./getServerInfo.js'), - getStatus: require('./getStatus.js'), - getWatchdogStats: require('./getWatchdogStats.js'), - - getSkyblockAuction: require('./skyblock/getAuction.js'), - getSkyblockAuctions: require('./skyblock/getAuctions.js'), - getSkyblockAuctionsByPlayer: require('./skyblock/getAuctionsByPlayer.js'), - getSkyblockBazaar: require('./skyblock/getBazaar.js'), - getSkyblockBingo: require('./skyblock/getBingo.js'), - getSkyblockBingoByPlayer: require('./skyblock/getBingoByPlayer.js'), - getSkyblockEndedAuctions: require('./skyblock/getEndedAuctions.js'), - getSkyblockFireSales: require('./skyblock/getFireSales.js'), - getSkyblockGarden: require('./skyblock/getGarden.js'), - getSkyblockGovernment: require('./skyblock/getGovernment.js'), - getSkyblockMember: require('./skyblock/getMember.js'), - getSkyblockMuseum: require('./skyblock/getMuseum.js'), - getSkyblockNews: require('./skyblock/getNews.js'), - getSkyblockProfiles: require('./skyblock/getProfiles.js'), - - getActiveHouses: require('./housing/getActiveHouses.js'), - getPlayerHouses: require('./housing/getPlayerHouses.js'), - getHouse: require('./housing/getHouse.js') -}; diff --git a/src/API/index.ts b/src/API/index.ts new file mode 100644 index 000000000..302f8267f --- /dev/null +++ b/src/API/index.ts @@ -0,0 +1,65 @@ +/* v8 ignore next 10000 */ + +import getAchievements from './getAchievements.js'; +import getActiveHouses from './getActiveHouses.js'; +import getBoosters from './getBoosters.js'; +import getChallenges from './getChallenges.js'; +import getGameCounts from './getGameCounts.js'; +import getGuild from './getGuild.js'; +import getGuildAchievements from './getGuildAchievements.js'; +import getHouse from './getHouse.js'; +import getLeaderboards from './getLeaderboards.js'; +import getPlayer from './getPlayer.js'; +import getPlayerHouses from './getPlayerHouses.js'; +import getQuests from './getQuests.js'; +import getRecentGames from './getRecentGames.js'; +import getSkyBlockAuction from './getSkyBlockAuction.js'; +import getSkyBlockAuctions from './getSkyBlockAuctions.js'; +import getSkyBlockBazaar from './getSkyBlockBazaar.js'; +import getSkyBlockBingo from './getSkyBlockBingo.js'; +import getSkyBlockCollections from './getSkyBlockCollections.js'; +import getSkyBlockElection from './getSkyBlockElection.js'; +import getSkyBlockEndedAuctions from './getSkyBlockEndedAuctions.js'; +import getSkyBlockFireSales from './getSkyBlockFireSales.js'; +import getSkyBlockGarden from './getSkyBlockGarden.js'; +import getSkyBlockItems from './getSkyBlockItems.js'; +import getSkyBlockMuseum from './getSkyBlockMuseum.js'; +import getSkyBlockNews from './getSkyBlockNews.js'; +import getSkyBlockProfile from './getSkyBlockProfile.js'; +import getSkyBlockProfiles from './getSkyBlockProfiles.js'; +import getSkyBlockSkills from './getSkyBlockSkills.js'; +import getStatus from './getStatus.js'; +import getWatchdogStats from './getWatchdogStats.js'; + +export default { + getAchievements, + getActiveHouses, + getBoosters, + getChallenges, + getGameCounts, + getGuild, + getGuildAchievements, + getHouse, + getLeaderboards, + getPlayer, + getPlayerHouses, + getQuests, + getRecentGames, + getSkyBlockAuction, + getSkyBlockAuctions, + getSkyBlockBazaar, + getSkyBlockBingo, + getSkyBlockCollections, + getSkyBlockElection, + getSkyBlockEndedAuctions, + getSkyBlockFireSales, + getSkyBlockGarden, + getSkyBlockItems, + getSkyBlockMuseum, + getSkyBlockNews, + getSkyBlockProfile, + getSkyBlockProfiles, + getSkyBlockSkills, + getStatus, + getWatchdogStats +}; diff --git a/src/API/skyblock/getAuction.js b/src/API/skyblock/getAuction.js deleted file mode 100644 index 390417e89..000000000 --- a/src/API/skyblock/getAuction.js +++ /dev/null @@ -1,21 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -module.exports = async function (type, query, includeItemBytes = false) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - const Auction = require('../../structures/SkyBlock/Auctions/Auction'); - let filter; - if ('PROFILE' === type) { - filter = 'profile'; - } else if ('PLAYER' === type) { - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - filter = 'player'; - } else if ('AUCTION' === type) { - filter = 'uuid'; - } else { - throw new Error(Errors.BAD_AUCTION_FILTER); - } - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/auction?${filter}=${query}`); - if (res.raw) return res; - return res.auctions.length ? res.auctions.map((a) => new Auction(a, includeItemBytes)) : []; -}; diff --git a/src/API/skyblock/getAuctions.js b/src/API/skyblock/getAuctions.js deleted file mode 100644 index 2def61e71..000000000 --- a/src/API/skyblock/getAuctions.js +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable jsdoc/require-jsdoc */ -const Auction = require('../../structures/SkyBlock/Auctions/Auction'); -const AuctionInfo = require('../../structures/SkyBlock/Auctions/AuctionInfo'); -const Errors = require('../../Errors'); -// eslint-disable-next-line no-underscore-dangle -let _makeRequest; -async function getPage(page = 0, options = {}) { - const content = await _makeRequest(`/skyblock/auctions?page=${page}`, false); - const result = {}; - if (!options.noInfo) result.info = new AuctionInfo(content); - if (options.raw) result.auctions = content.auctions; - else if (options.noAuctions) result.auctions = []; - else result.auctions = content.auctions.map((x) => new Auction(x, options.includeItemBytes)); - return result; -} -async function noReject(promise, args = [], retries = 3, cooldown = 100) { - try { - const result = await promise.call(null, ...args); - return result; - } catch { - if (retries) { - await new Promise((resolve) => setTimeout(resolve, cooldown)); - return await noReject(promise, args, retries - 1, cooldown); - } - return null; - } -} -module.exports = async function (range, options = {}) { - // eslint-disable-next-line no-underscore-dangle - _makeRequest = this._makeRequest; - options.retries ||= 3; - options.cooldown ||= 100; - if (null === range || '*' === range) range = [0, (await getPage(0, { noAuctions: true })).info.totalPages]; - if (!Array.isArray(range)) range = [parseInt(range), parseInt(range)]; - if (isNaN(range[0])) throw new Error(Errors.PAGE_INDEX_ERROR); - if (parseInt(options.retries) !== options.retries || 10 < options.retries || 0 > options.retries) { - throw new Error(Errors.INVALID_OPTION_VALUE); - } - if (parseInt(options.cooldown) !== options.cooldown || 3000 < options.cooldown || 0 > options.cooldown) { - throw new Error(Errors.INVALID_OPTION_VALUE); - } - range = range.sort(); - const result = { info: null, Auctions: [] }; - const fetches = []; - const failedPages = []; - if (options.noAuctions) return { info: options.noInfo ? null : (await getPage(range[1], { noAuctions: true })).info }; - for (let i = range[0]; i <= range[1]; i++) { - if (options.race) { - fetches.push(noReject(getPage, [i, options], options.retries, options.cooldown)); - } else { - const resp = await noReject(getPage, [i, options], options.retries, options.cooldown); - if (resp) { - result.Auctions = result.Auctions.concat(resp.auctions); - if (resp.info) result.info = resp.info; - } else { - failedPages.push(i); - } - } - } - if (fetches.length) { - result.Auctions = (await Promise.all(fetches)).reduce((pV, cV, index) => { - if (!cV) { - failedPages.push(index + range[0]); - return pV; - } - if (cV.info) result.info = cV.info; - if (cV.auctions.length) return pV.concat(cV.auctions); - return pV; - }, []); - } - // eslint-disable-next-line no-underscore-dangle - result.info = result.info ? result.info._extend('failedPages', failedPages) : { failedPages }; - return result; -}; diff --git a/src/API/skyblock/getAuctionsByPlayer.js b/src/API/skyblock/getAuctionsByPlayer.js deleted file mode 100644 index 4e24f381b..000000000 --- a/src/API/skyblock/getAuctionsByPlayer.js +++ /dev/null @@ -1,11 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -module.exports = async function (query, includeItemBytes = false) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - const Auction = require('../../structures/SkyBlock/Auctions/Auction'); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/auction?player=${query}`); - if (res.raw) return res; - return res.auctions.length ? res.auctions.map((a) => new Auction(a, includeItemBytes)) : []; -}; diff --git a/src/API/skyblock/getBazaar.js b/src/API/skyblock/getBazaar.js deleted file mode 100644 index 1576917e8..000000000 --- a/src/API/skyblock/getBazaar.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = async function () { - const Product = require('../../structures/SkyBlock/Bazzar/Product'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/skyblock/bazaar'); - if (res.raw) return res; - const productsKeys = Object.keys(res.products); - return productsKeys.map((x) => new Product(res.products[x])); -}; diff --git a/src/API/skyblock/getBingo.js b/src/API/skyblock/getBingo.js deleted file mode 100644 index 978c9e0f2..000000000 --- a/src/API/skyblock/getBingo.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const BingoData = require('../../structures/SkyBlock/Static/BingoData'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/skyblock/bingo'); - if (res.raw) return res; - return new BingoData(res); -}; diff --git a/src/API/skyblock/getBingoByPlayer.js b/src/API/skyblock/getBingoByPlayer.js deleted file mode 100644 index 634f8e4c3..000000000 --- a/src/API/skyblock/getBingoByPlayer.js +++ /dev/null @@ -1,14 +0,0 @@ -const toUuid = require('../../utils/toUuid'); -const getBingo = require('./getBingo'); -const Errors = require('../../Errors'); -module.exports = async function (query, { fetchBingoData = false }) { - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - const PlayerBingo = require('../../structures/SkyBlock/PlayerBingo'); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/uuid?player=${query}`); - if (res.raw) return res; - let bingoData = null; - if (fetchBingoData) bingoData = await getBingo.call(this); - return new PlayerBingo(res, bingoData); -}; diff --git a/src/API/skyblock/getEndedAuctions.js b/src/API/skyblock/getEndedAuctions.js deleted file mode 100644 index b6b993ed5..000000000 --- a/src/API/skyblock/getEndedAuctions.js +++ /dev/null @@ -1,11 +0,0 @@ -const PartialAuction = require('../../structures/SkyBlock/Auctions/PartialAuction'); -const AuctionInfo = require('../../structures/SkyBlock/Auctions/AuctionInfo'); -module.exports = async function (includeItemBytes = false) { - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/skyblock/auctions_ended', false); - if (res.raw) return res; - return { - info: new AuctionInfo({ ...res, totalAuctions: res.auctions.length, totalPages: 1 }), - auctions: res.auctions.length ? res.auctions.map((a) => new PartialAuction(a, includeItemBytes)) : [] - }; -}; diff --git a/src/API/skyblock/getFireSales.js b/src/API/skyblock/getFireSales.js deleted file mode 100644 index e96cdc7d8..000000000 --- a/src/API/skyblock/getFireSales.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const FireSale = require('../../structures/SkyBlock/Static/FireSale'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/skyblock/firesales'); - if (res.raw) return res; - return res.sales.length ? res.sales.map((sale) => new FireSale(sale)) : []; -}; diff --git a/src/API/skyblock/getGarden.js b/src/API/skyblock/getGarden.js deleted file mode 100644 index a3caa8fe5..000000000 --- a/src/API/skyblock/getGarden.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = async function (profileId) { - const SkyblockGarden = require('../../structures/SkyBlock/SkyblockGarden'); - let res; - try { - // eslint-disable-next-line no-underscore-dangle - res = await this._makeRequest(`/skyblock/garden?profile=${profileId}`).catch(); - // eslint-disable-next-line no-unused-vars, no-empty - } catch (e) {} - if (res?.raw) return res; - return new SkyblockGarden(res); -}; diff --git a/src/API/skyblock/getGovernment.js b/src/API/skyblock/getGovernment.js deleted file mode 100644 index 1e4657509..000000000 --- a/src/API/skyblock/getGovernment.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = async function () { - const GovernmentData = require('../../structures/SkyBlock/Static/Government.js'); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/resources/skyblock/election'); - if (res.raw) return res; - return new GovernmentData(res); -}; diff --git a/src/API/skyblock/getMember.js b/src/API/skyblock/getMember.js deleted file mode 100644 index d4d71ec62..000000000 --- a/src/API/skyblock/getMember.js +++ /dev/null @@ -1,35 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -const getPlayer = require('../getPlayer'); -module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false, getGarden: false }) { - const SkyblockMember = require('../../structures/SkyBlock/SkyblockMember'); - const getSkyblockMuseum = require('./getMuseum'); - const getSkyblockGarden = require('./getGarden'); - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/profiles?uuid=${query}`); - if (res.raw) return res; - if (!res.profiles || !res.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES); - const player = options.fetchPlayer ? await getPlayer.call(this, query, options) : null; - const memberByProfileName = new Map(); - for (const profile of res.profiles) { - profile.members[query].player = player; - memberByProfileName.set( - profile.cute_name, - new SkyblockMember({ - uuid: query, - profileId: profile.profile_id, - profileName: profile.cute_name, - gameMode: profile.game_mode || null, - m: profile.members[query], - banking: profile.banking, - communityUpgrades: profile.community_upgrades, - museum: options.getMuseum ? await getSkyblockMuseum.call(this, query, profile.profile_id) : null, - garden: options.getGarden ? await getSkyblockGarden.call(this, profile.profile_id) : null, - selected: profile.selected - }) - ); - } - return memberByProfileName; -}; diff --git a/src/API/skyblock/getMuseum.js b/src/API/skyblock/getMuseum.js deleted file mode 100644 index 370c88793..000000000 --- a/src/API/skyblock/getMuseum.js +++ /dev/null @@ -1,15 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -module.exports = async function (query, profileId) { - const SkyblockMuseum = require('../../structures/SkyBlock/SkyblockMuseum'); - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/museum?uuid=${query}&profile=${profileId}`); - if (res.raw) return res; - return new SkyblockMuseum({ - uuid: query, - m: res, - profileId: profileId - }); -}; diff --git a/src/API/skyblock/getNews.js b/src/API/skyblock/getNews.js deleted file mode 100644 index a4cee6267..000000000 --- a/src/API/skyblock/getNews.js +++ /dev/null @@ -1,7 +0,0 @@ -const SkyblockNews = require('../../structures/SkyBlock/News/SkyblockNews'); -module.exports = async function () { - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest('/skyblock/news'); - if (res.raw) return res; - return res.items.map((i) => new SkyblockNews(i)); -}; diff --git a/src/API/skyblock/getProfiles.js b/src/API/skyblock/getProfiles.js deleted file mode 100644 index 6faa3c532..000000000 --- a/src/API/skyblock/getProfiles.js +++ /dev/null @@ -1,49 +0,0 @@ -const Errors = require('../../Errors'); -const toUuid = require('../../utils/toUuid'); -const getPlayer = require('../getPlayer'); -module.exports = async function (query, options = { fetchPlayer: false, getMuseum: false, getGarden: false }) { - const SkyblockProfile = require('../../structures/SkyBlock/SkyblockProfile'); - const getSkyblockMuseum = require('./getMuseum'); - const getSkyblockGarden = require('./getGarden'); - if (!query) throw new Error(Errors.NO_NICKNAME_UUID); - query = await toUuid(query, this.options.mojangCacheTime, this.options.useThirdPartyAPI); - // eslint-disable-next-line no-underscore-dangle - const res = await this._makeRequest(`/skyblock/profiles?uuid=${query}`); - if (res.raw) return res; - if (!res.profiles || !res.profiles.length) throw new Error(Errors.NO_SKYBLOCK_PROFILES); - const players = new Map(); - if (options.fetchPlayer) { - const uniqueUuids = [...new Set(res.profiles.map((profile) => Object.keys(profile.members)).flat())]; - await Promise.all( - uniqueUuids.map(async (uuid) => { - const player = await getPlayer.call(this, uuid, options); - players.set(uuid, player); - }) - ); - } - - const profiles = []; - for (let i = 0; i < res.profiles.length; i++) { - if (options.fetchPlayer) { - for (const memberUuid of Object.keys(res.profiles[i].members)) { - res.profiles[i].members[memberUuid].player = players.get(memberUuid); - } - } - - profiles.push({ - uuid: query, - profileId: res.profiles[i].profile_id, - profileName: res.profiles[i].cute_name, - gameMode: res.profiles[i].game_mode || null, - m: res.profiles[i].members[query], - banking: res.profiles[i].banking, - communityUpgrades: res.profiles[i].community_upgrades, - museum: options.getMuseum ? await getSkyblockMuseum.call(this, query, res.profiles[i].profile_id) : null, - garden: options.getGarden ? await getSkyblockGarden.call(this, res.profiles[i].profile_id) : null, - selected: res.profiles[i].selected, - members: res.profiles[i].members - }); - } - - return profiles.map((p) => new SkyblockProfile(p)); -}; diff --git a/src/Client.js b/src/Client.js deleted file mode 100644 index a35efaff0..000000000 --- a/src/Client.js +++ /dev/null @@ -1,547 +0,0 @@ -const rateLimit = new (require('./Private/rateLimit'))(); -const validate = new (require('./Private/validate'))(); -const updater = new (require('./Private/updater'))(); -const Requests = require('./Private/requests'); -const EventEmitter = require('events'); -const Errors = require('./Errors'); -const API = require('./API/index'); -const clients = []; - -/* eslint-disable */ -const Player = require('./structures/Player'); -const Guild = require('./structures/Guild/Guild'); -const WatchdogStats = require('./structures/Watchdog/Stats'); -const Booster = require('./structures/Boosters/Booster'); -const SkyblockProfile = require('./structures/SkyBlock/SkyblockProfile'); -const SkyblockMember = require('./structures/SkyBlock/SkyblockMember'); -const SkyblockMuseum = require('./structures/SkyBlock/SkyblockMuseum'); -const SkyblockGarden = require('./structures/SkyBlock/SkyblockGarden'); -const APIStatus = require('./structures/APIStatus'); -const Leaderboard = require('./structures/Leaderboard'); -const ServerInfo = require('./structures/ServerInfo'); -const RecentGame = require('./structures/RecentGame'); -const Status = require('./structures/Status'); -const Auction = require('./structures/SkyBlock/Auctions/Auction'); -const AuctionInfo = require('./structures/SkyBlock/Auctions/AuctionInfo'); -const PartialAuction = require('./structures/SkyBlock/Auctions/PartialAuction'); -const Product = require('./structures/SkyBlock/Bazzar/Product'); -const BingoData = require('./structures/SkyBlock/Static/BingoData'); -const PlayerBingo = require('./structures/SkyBlock/PlayerBingo'); -const GovernmentData = require('./structures/SkyBlock/Static/Government'); -const FireSale = require('./structures/SkyBlock/Static/FireSale'); -const SkyblockNews = require('./structures/SkyBlock/News/SkyblockNews'); -const GameCounts = require('./structures/GameCounts'); -const House = require('./structures/House.js'); -/* eslint-enable */ - -/** - * Client class - */ -class Client extends EventEmitter { - /** - * @param {string} key API key - * @param {ClientOptions} [options={}] Client options - */ - constructor(key, options = {}) { - super(); - this.requests = new Requests(this, options.cacheHandler); - // eslint-disable-next-line no-console - if (options && !options.silent) this.on('warn', console.warn); - // Test to check for multiple instances of client - if (clients.find((x) => x.key === key)) { - this.emit('warn', Errors.MULTIPLE_INSTANCES); - return clients.find((x) => x.key === key); - } - validate.validateNodeVersion(); - this.key = validate.validateKey(key); - this.options = validate.parseOptions(options); - validate.validateOptions(this.options); - - for (const func in API) { - Client.prototype[func] = (...args) => { - const lastArg = args[args.length - 1]; - return API[func].apply( - { - // eslint-disable-next-line no-underscore-dangle - _makeRequest: this._makeRequest.bind(this, validate.cacheSuboptions(lastArg) ? lastArg : {}), - ...this - }, - args - ); - }; - } - - if (this.options.checkForUpdates) { - updater.checkForUpdates().catch(() => { - // eslint-disable-next-line no-console - if (!this.options.silent) console.warn('[hypixel-api-reborn] Error whilst checking for updates!'); - }); - } - /** - * All cache entries - * @type {Map} - */ - this.cache = this.requests.cache; - clients.push(this); - rateLimit.init(this.getGameCounts(), this.options, this).then(() => this.emit('ready')); - } - /** - * Private function - make request - * @param {MethodOptions} options Options for request - * @param {string} url Endpoint URL to request - * @param {boolean} [useRateLimitManager=true] Use rate limit - * @returns {Promise} Response - * @private - */ - async _makeRequest(options, url, useRateLimitManager = true) { - if (!url) return; - if ('/key' !== url && !options.noCacheCheck && (await this.requests.cache.has(url))) { - return Object.assign(await this.requests.cache.get(url), { raw: Boolean(options.raw) }); - } - if (useRateLimitManager) await rateLimit.rateLimitManager(); - this.emit('outgoingRequest', url, { ...options, headers: { ...options.headers, ...this.options.headers } }); - const result = await this.requests.request.call(this.requests, url, { - ...options, - headers: { ...options.headers, ...this.options.headers } - }); - // eslint-disable-next-line no-underscore-dangle - if (this.options.syncWithHeaders) rateLimit.sync(result._headers); - return result; - } - /** - * Emitted when rate limiter is ready. ( You don't have to wait for this event to emit UNLESS you are planning to do data scraping which means spamming requests ) - * @event ready - * @name Client#ready - * @example - * // This example gets player's uuid. - * hypixel.once('ready',()=>{ - * hypixel.getPlayer('stavzdev') - * .then(player => player.uuid) - * .catch(console.log); - * }) - */ - /** - * Emitted when a request is going to be sent - * @event outgoingRequest - * @name Client#outgoingRequest - * @param {string} url URL - * @param {object} [options] Options, if any - */ - /** - * Emitted when there is a warning. - * @event warn - * @name Client#warn - * @param {string} error Warning Message - */ - /** - * Allows you to get statistics of player - * @method - * @name Client#getPlayer - * @param {string} query Player nickname or UUID - * @param {PlayerMethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getPlayer('StavZDev').then(player => { - * console.log(player.level); // 141 - * console.log(player.rank); // 'MVP+' - * }).catch(e => { - * console.log(e); - * }) - * @example - * // Get player's guild along with player stats - * hypixel.getPlayer('Minikloon', { guild: true }).then(player => { - * console.log(player.guild) // null if player isn't is guild - * console.log(player.guild.name) // Mini Squid - * console.log(player.guild.level) // 110 - * }).catch(e => { - * console.log(e); - * }); - * @example - * // async/await - * const player = await hypixel.getPlayer('Minikloon').catch(console.log); - * // If player doesn't exist, or if an error occurred ( check console ) - * console.log(player); // null - * // Check if player exists - * if(player) console.log(player.uuid); // 20934ef9488c465180a78f861586b4cf - */ - /** - * Allows you to get statistics of hypixel guild - * @method - * @name Client#getGuild - * @param {'id'|'name'|'player'} searchParameter Search for guild by id, name or player (if player is in guild) - * @param {string} query Guild ID, Guild name or player uuid/nickname - * @param {MethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getGuild('name', 'The Foundation').then(guild => { - * console.log(guild.level); // 111 - * console.log(guild.id); // '52e5719284ae51ed0c716c69' - * }).catch(e => { - * console.log(e); - * }) - * @example - * // async/await - * const guild = await hypixel.getGuild('name', 'The Foundation').catch(console.log); - * console.log(guild.level); // 111 - * console.log(guild.id); // '52e5719284ae51ed0c716c69' - */ - /** - * Allows you to get statistics of watchdog, the server anticheat - * @method - * @name Client#getWatchdogStats - * @param {MethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getWatchdogStats().then(watchdog => { - * console.log(watchdog.byWatchdogTotal); // 5931897 - * }).catch(e => { - * console.log(e); - * }) - * @example - * // async/await - * const watchdog = await hypixel.getWatchdogStats().catch(console.log); - * console.log(watchdog.byWatchdogTotal); // 5931897 - */ - /** - * Allows you to get all active boosters - * @method - * @name Client#getBoosters - * @param {MethodOptions} [options={}] Method options - * @return {Promise>} - * @example - * hypixel.getBoosters().then(boosters => { - * console.log(boosters[0].purchaser); // '978ddb705a8e43618e41749178c020b0' - * }).catch(e => { - * console.log(e); - * }) - * @example - * // async/await - * const boosters = await hypixel.getBoosters().catch(console.log); - * console.log(boosters[0].purchaser); // '978ddb705a8e43618e41749178c020b0' - */ - /** - * Allows you to get all skyblock profiles of player - * @method - * @name Client#getSkyblockProfiles - * @param {string} query Player nickname or UUID - * @param {SkyblockMethodOptions} [options={}] Method options - * @return {Promise>} - * @example - * hypixel.getSkyblockProfiles('StavZDev').then(profiles => { - * console.log(profiles[0].members[0].uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - * }).catch(e => { - * console.log(e); - * }) - * @example - * const profiles = await hypixel.getSkyblockProfiles('StavZDev').catch(console.log); - * console.log(profiles[0].members[0].uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - */ - /** - * Allows you to get a player's skyblock member data from all their profiles - * @method - * @name Client#getSkyblockMember - * @param {string} query Player nickname or UUID - * @param {SkyblockMethodOptions} [options={}] Method options - * @return {Promise>} - * @example - * hypixel.getSkyblockMember('StavZDev').then(member => { - * // 'Cucumber' - profile name - * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - * }).catch(e => { - * console.log(e); - * }) - * @example - * const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log); - * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - */ - /** - * Allows you to get a player's skyblock member data from all their profiles - * @method - * @name Client#getSkyblockGarden - * @param {string} profileId Profile id of the garden you want - * @param {MethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getSkyblockMember('StavZDev').then(member => { - * // 'Cucumber' - profile name - * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - * }).catch(e => { - * console.log(e); - * }) - * @example - * const member = await hypixel.getSkyblockMember('StavZDev').catch(console.log); - * console.log(member.get('Cucumber').uuid); // '52d9a36f66ce4cdf9a56ad9724ae9fb4' - */ - /** - * Allows you to get a player's skyblock profile museum - * @method - * @name Client#getSkyblockMuseum - * @param {string} query Player nickname or UUID - * @param {string} profileId Profile ID - * @return {Promise} - */ - /** - * Allows you to get the Hypixel API's Status and past Incidents, no key needed. - * @method - * @name Client#getAPIStatus - * @return {Promise} - * @example - * hypixel.getAPIStatus().then(status => { - * console.log(status.incidents[0].link); // 'https://status.hypixel.net/incidents/zdd5gppdtcc3' - * }).catch(e => { - * console.log(e); - * }) - */ - /** - * Gets all leaderboards - * @method - * @name Client#getLeaderboards - * @param {MethodOptions} [options={}] Method options - * @return {Promise<{ ARENA: Leaderboard[], COPS_AND_CRIMS: Leaderboard[], WARLORDS: Leaderboard[], BLITZ_SURVIVAL_GAMES: Leaderboard[], UHC: Leaderboard[], WALLS: Leaderboard[], PROTOTYPE: Leaderboard[], PAINTBALL: Leaderboard[], SKYWARS: Leaderboard[], MURDER_MYSTERY: Leaderboard[], SMASH_HEROES: Leaderboard[], DUELS: Leaderboard[], SPEED_UHC: Leaderboard[], TNTGAMES: Leaderboard[], BEDWARS: Leaderboard[], TURBO_KART_RACERS: Leaderboard[], BUILD_BATTLE: Leaderboard[], ARCADE: Leaderboard[], SKYCLASH: Leaderboard[], QUAKECRAFT: Leaderboard[], CRAZY_WALLS: Leaderboard[], MEGA_WALLS: Leaderboard[], VAMPIREZ: Leaderboard[] }>} - * @example - * hypixel.getLeaderboards().then(leaderboards => { - * console.log(leaderboards.ARENA[0].name); // 'Wins' - * }).catch(e => { - * console.log(e); - * }) - */ - /** - * Sends a STATUS packet to hypixel and parses the return info (a 0x00 and 0x01 packet) - * @method - * @name Client#getServerInfo - * @param {number} [repeats=3] Sends x amount of ping requests and gets the average. Should be between 1 and 10 - * @return {Promise} - * @example - * hypixel.getServerInfo(3).then(serverInfo =>{ - * console.log(serverInfo.ping); // 69 - * }).catch(console.log) - */ - /** - * Allows you to get recent games of a player - * @method - * @name Client#getRecentGames - * @param {string} query Player nickname or UUID - * @param {MethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getRecentGames().then(recentGames =>{ - * console.log(recentGames[0].endedTimestamp); // 1609670588789 - * }) - * .catch(console.log); - */ - /** - * Allows you to get the status of a player - * @method - * @name Client#getStatus - * @param {string} query Player nickname or UUID - * @param {MethodOptions} [options={}] Method options - * @return {Promise} - * @example - * hypixel.getStatus('Stavzdev').then(status =>{ - * console.log(status.online); // true - * }) - * .catch(console.log); - */ - /** - * Allows you to get skyblock auctions - * @method - * @name Client#getSkyblockAuctions - * @param {string|number|number[]} page - "*", a page number, or an array with the start and the end page number ( automatically sorted ) - * @param {auctionsOptions} [options={}] Options - * @return {Promise<{info:AuctionInfo,Auctions:Auction[]}>} - */ - /** - * Allows you to get player's skyblock auctions - * @method - * @name Client#getSkyblockAuctionsByPlayer - * @param {string} query - player nickname or uuid - * @param {boolean} [includeItemBytes=false] - include item bytes (optional) - * @param {MethodOptions} [options={}] Options - * @return {Promise} - * @example - * hypixel.getSkyblockAuctionsByPlayer('hypixel').then(auctions =>{ - * console.log(auctions[0].auctionId); // b0491da3e81c43c88fd287ea3b3eacc0 - * }) - * .catch(console.log); - */ - /** - * Allows you to get all ended auctions in around the last 60 seconds - * @method - * @name Client#getEndedSkyblockAuctions - * @param {boolean} [includeItemBytes=false] - include item bytes (optional) - * @param {MethodOptions} [options={}] Options - * @return {Promise<{info:AuctionInfo,auctions:PartialAuction[]}>} - * @example - * hypixel.getEndedSkyblockAuctions().then(ended =>{ - * console.log(ended.auctions[0].auctionId); // 0fe7fd132367474e86ff3022b4a84a13 - * }) - * .catch(console.log); - */ - /** - * Allows you to get list of products - * @method - * @name Client#getSkyblockBazaar - * @param {MethodOptions} [options={}] Options - * @return {Promise} - * @example - * hypixel.getSkyblockBazaar().then(products =>{ - * console.log(products[0].productId); // INK_SACK:3 - * }) - * .catch(console.log); - */ - /** - * Allows you to get bingo data - * @method - * @name Client#getSkyblockBingo - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Allows you to get bingo data of a player - * @method - * @name Client#getSkyblockBingoByPlayer - * @param {string} query UUID / IGN of player - * @param {PlayerBingoOptions} [options={}] Options - * @return {Promise} - */ - /** - * Allows you to get SB government - * @method - * @name Client#getSkyblockGovernment - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Allows you to get SB government - * @method - * @name Client#getSkyblockFireSale - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Get a array of active houses - * @method - * @name Client#getActiveHouses - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Get a array of houses for a user - * @method - * @name Client#getPlayerHouses - * @param {string} query UUID / IGN of player - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Get a house - * @method - * @name Client#getHouse - * @param {string} query House UUID - * @param {MethodOptions} [options={}] Options - * @return {Promise} - */ - /** - * Allows you to get skyblock news - * @method - * @name Client#getSkyblockNews - * @param {MethodOptions} [options={}] Options - * @return {Promise} - * @example - * hypixel.getSkyblockNews().then((news) => { - * console.log(news[0].link); // https://hypixel.net/threads/3749492/ - * }) - * .catch(console.log) - */ - /** - * Allows you to get player count along with the player count of each public game - * @method - * @name Client#getGameCounts - * @param {MethodOptions} [options={}] Options - * @return {Promise} - * @example - * hypixel.getGameCounts().then((gameCounts) => { - * console.log(gameCounts.mainLobby.players); - * }) - * .catch(console.log) - */ - /** - * Delete x (by default all) cache entries - * @param {?number} amount Amount of cache to delete - * @return {Promise} - */ - sweepCache(amount) { - return this.requests.sweepCache(amount); - } -} -/** - * @typedef {object} ClientOptions - * @prop {boolean} [cache=true] Enable/Disable request caching. - * @prop {number} [hypixelCacheTime=60] Amount of time in seconds to cache the hypixel api requests. - * @prop {number} [mojangCacheTime=600] Amount of time in seconds to cache the mojang api requests. - * @prop {CacheHandler} [cacheHandler] Custom Cache Handler - * @prop {'AUTO'|'HARD'|'NONE'} [rateLimit='AUTO'] Rate limit mode. - * @prop {boolean} [syncWithHeaders=false] Sync with headers rate limit information. Usually not necessary nor recommended ( because of latency ) - * @prop {number} [keyLimit=60] Key limit of your key. - * @prop {number} [cacheSize=-1] The amount how many results will be cached. (`-1` for infinity) - * @prop {boolean} [silent=false] Don't automatically put warnings into console. - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. - * @prop {boolean} [checkForUpdates=true] Enable/Disable check for new version of hypixel-api-reborn. - * @prop {boolean|string} [useThirdPartyAPI=false] Enable/Disable Mojang Third Party API - */ -// eslint-disable-next-line no-unused-vars -const defaultCache = require('./Private/defaultCache.js'); -/** - * @typedef {defaultCache} Cache - */ -/** - * @typedef {Cache} CacheHandler - */ -/** - * @typedef {object} MethodOptions - * @property {boolean} [raw=false] Raw data - * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking - * @property {boolean} [noCaching=false] Disable/Enable writing to cache - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided. - */ -/** - * @typedef {object} PlayerMethodOptions - * @property {boolean} [raw=false] Raw data - * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking - * @property {boolean} [noCaching=false] Disable/Enable writing to cache - * @property {boolean} [guild=false] Disable/Enable request for player's guild - * @property {boolean} [recentGames=false] Disable/Enable request for player's recent game - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided. - */ -/** - * @typedef {object} SkyblockMethodOptions - * @property {boolean} [raw=false] Raw data - * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking - * @property {boolean} [noCaching=false] Disable/Enable writing to cache - * @property {?boolean} [fetchPlayer=false] Disable/Enable player profile request for each member - * @property {?boolean} [getMuseum=false] Disable/Enable player museum request for each member - * @property {?boolean} [getGarden=false] Disable/Enable player garden request for each member - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided. - */ -/** - * @typedef {object} auctionsOptions - * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking - * @property {boolean} [noCaching=false] Disable/Enable writing to cache - * @property {boolean} [noInfo=false] If true, result doesn't show Auction Info - * @property {boolean} [noAuctions=false] If true, result doesn't show auctions - * @property {boolean} [raw=false] If true, result will not contain parsed auctions, but will present them as it is received. This can speed up performance in some cases. - * @property {number} [retries=3] Number of times to retry fetching a page before abandoning - * @property {number} [cooldown=100] Cooldown between each fetch, only works if race is unset or false; - * @property {boolean} [race=false] Issues simultaneous requests to the API, instead of requesting then parsing one by one. Can largely increase speed at the cost of hogging bandwidth and memory - * @property {boolean} [includeItemBytes=false] Whether to include item bytes in the result - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided. - */ -/** - * @typedef {object} PlayerBingoOptions - * @property {boolean} [raw=false] Raw data - * @property {boolean} [noCacheCheck=false] Disable/Enable cache checking - * @property {boolean} [noCaching=false] Disable/Enable writing to cache - * @property {boolean} [fetchBingoData=false] Fetches bingo data to give more information - * @prop {object} [headers={}] Extra Headers ( like User-Agent ) to add to request. Overrides the headers globally provided. - */ -module.exports = Client; diff --git a/src/Client.test.ts b/src/Client.test.ts new file mode 100644 index 000000000..ba098d668 --- /dev/null +++ b/src/Client.test.ts @@ -0,0 +1,140 @@ +import CacheHandler from './Private/CacheHandler.js'; +import Client from './Client.js'; +import Errors from './Errors.js'; +import RequestHandler from './Private/RequestHandler.js'; +import Updater from './Private/Updater.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ClientOptions } from './Types/Client.js'; + +test('Client (No Key)', () => { + expect(() => new Client('')).toThrowError(Errors.NO_API_KEY); +}); + +test('Client (No Options)', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? ''); + expect(client).toBeDefined(); + expect(client).toBeInstanceOf(Client); + expectTypeOf(client).toEqualTypeOf(); + + expect(client.key).toBe(process.env.HYPIXEL_KEY ?? ''); + expectTypeOf(client.key).toBeString(); + + expect(client.options).toBeDefined(); + expectTypeOf(client.options).toEqualTypeOf(); + + expect(client.options.cache).toBeDefined(); + expect(client.options.cache).toBe(true); + expect(client.options.cache).toBeTruthy(); + + expect(client.options.cacheTime).toBeDefined(); + expectTypeOf(client.options.cacheTime).toEqualTypeOf(); + expect(client.options.cacheTime).toBe(300); + + expect(client.options.cacheMaxKeys).toBeDefined(); + expectTypeOf(client.options.cacheMaxKeys).toEqualTypeOf(); + expect(client.options.cacheMaxKeys).toBe(-1); + + expect(client.options.cacheCheckPeriod).toBeDefined(); + expectTypeOf(client.options.cacheCheckPeriod).toEqualTypeOf(); + expect(client.options.cacheCheckPeriod).toBe(180); + + expect(client.options.rateLimit).toBeDefined(); + expectTypeOf(client.options.rateLimit).toEqualTypeOf<'AUTO' | 'NONE' | undefined>(); + expect(client.options.rateLimit).toBe('AUTO'); + + expect(client.options.silent).toBeDefined(); + expectTypeOf(client.options.silent).toEqualTypeOf(); + expect(client.options.silent).toBe(false); + expect(client.options.silent).toBeFalsy(); + + expect(client.options.checkForUpdates).toBeDefined(); + expect(client.options.checkForUpdates).toBeTruthy(); + expect(client.options.checkForUpdates).toBe(true); + + expect(client.options.checkForUpdatesInterval).toBeDefined(); + expectTypeOf(client.options.checkForUpdatesInterval).toEqualTypeOf(); + expect(client.options.checkForUpdatesInterval).toBe(60); + + expect(client.requestHandler).toBeDefined(); + expect(client.requestHandler).toBeInstanceOf(RequestHandler); + expectTypeOf(client.requestHandler).toEqualTypeOf(); + + expect(client.cacheHandler).toBeDefined(); + expect(client.cacheHandler).toBeInstanceOf(CacheHandler); + expectTypeOf(client.cacheHandler).toEqualTypeOf(); + + expect(client.updater).toBeDefined(); + expect(client.updater).toBeInstanceOf(Updater); + expectTypeOf(client.updater).toEqualTypeOf(); + + client.destroy(); +}); + +test('Client (Options)', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { + cache: false, + cacheTime: 600, + cacheMaxKeys: 100, + cacheCheckPeriod: 300, + rateLimit: 'NONE', + silent: true, + checkForUpdates: false, + checkForUpdatesInterval: 120 + }); + expect(client).toBeDefined(); + expect(client).toBeInstanceOf(Client); + expectTypeOf(client).toEqualTypeOf(); + + expect(client.key).toBe(process.env.HYPIXEL_KEY ?? ''); + expectTypeOf(client.key).toBeString(); + + expect(client.options).toBeDefined(); + expectTypeOf(client.options).toEqualTypeOf(); + + expect(client.options.cache).toBeDefined(); + expect(client.options.cache).toBe(false); + expect(client.options.cache).toBeFalsy(); + + expect(client.options.cacheTime).toBeDefined(); + expectTypeOf(client.options.cacheTime).toEqualTypeOf(); + expect(client.options.cacheTime).toBe(600); + + expect(client.options.cacheMaxKeys).toBeDefined(); + expectTypeOf(client.options.cacheMaxKeys).toEqualTypeOf(); + expect(client.options.cacheMaxKeys).toBe(100); + + expect(client.options.cacheCheckPeriod).toBeDefined(); + expectTypeOf(client.options.cacheCheckPeriod).toEqualTypeOf(); + expect(client.options.cacheCheckPeriod).toBe(300); + + expect(client.options.rateLimit).toBeDefined(); + expectTypeOf(client.options.rateLimit).toEqualTypeOf<'AUTO' | 'NONE' | undefined>(); + expect(client.options.rateLimit).toBe('NONE'); + + expect(client.options.silent).toBeDefined(); + expectTypeOf(client.options.silent).toEqualTypeOf(); + expect(client.options.silent).toBe(true); + expect(client.options.silent).toBeTruthy(); + + expect(client.options.checkForUpdates).toBeDefined(); + expect(client.options.checkForUpdates).toBeFalsy(); + expect(client.options.checkForUpdates).toBe(false); + + expect(client.options.checkForUpdatesInterval).toBeDefined(); + expectTypeOf(client.options.checkForUpdatesInterval).toEqualTypeOf(); + expect(client.options.checkForUpdatesInterval).toBe(120); + + expect(client.requestHandler).toBeDefined(); + expect(client.requestHandler).toBeInstanceOf(RequestHandler); + expectTypeOf(client.requestHandler).toEqualTypeOf(); + + expect(client.cacheHandler).toBeDefined(); + expect(client.cacheHandler).toBeInstanceOf(CacheHandler); + expectTypeOf(client.cacheHandler).toEqualTypeOf(); + + expect(client.updater).toBeDefined(); + expect(client.updater).toBeInstanceOf(Updater); + expectTypeOf(client.updater).toEqualTypeOf(); + + client.destroy(); +}); diff --git a/src/Client.ts b/src/Client.ts new file mode 100644 index 000000000..3c9178ffa --- /dev/null +++ b/src/Client.ts @@ -0,0 +1,256 @@ +import API from './API/index.js'; +import CacheHandler from './Private/CacheHandler.js'; +import Errors from './Errors.js'; +import Functions from './Private/Functions.js'; +import RateLimit from './Private/RateLimit.js'; +import RequestHandler from './Private/RequestHandler.js'; +import Updater from './Private/Updater.js'; +import type Achievements from './Structures/Static/Achievements/Achievements.js'; +import type Booster from './Structures/Boosters/Booster.js'; +import type Challenges from './Structures/Static/Challenges.js'; +import type GameCounts from './Structures/Static/GameCounts/GameCounts.ts'; +import type Guild from './Structures/Guild/Guild.js'; +import type GuildAchievements from './Structures/Static/Achievements/GuildAchievements.js'; +import type House from './Structures/House.js'; +import type Leaderboard from './Structures/Leaderboard.js'; +import type Player from './Structures/Player/Player.js'; +import type Quests from './Structures/Static/Quests.js'; +import type RecentGame from './Structures/RecentGame.js'; +import type RequestData from './Private/RequestData.js'; +import type SkyBlockBazaar from './Structures/SkyBlock/Bazaar/SkyBlockBazaar.js'; +import type SkyBlockBingo from './Structures/SkyBlock/Bingo/SkyBlockBingo.js'; +import type SkyBlockCollections from './Structures/SkyBlock/Collections/SkyBlockCollections.js'; +import type SkyBlockElectionData from './Structures/SkyBlock/Election/SkyBlockElectionData.js'; +import type SkyBlockFireSale from './Structures/SkyBlock/FireSale/SkyBlockFireSale.js'; +import type SkyBlockGarden from './Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import type SkyBlockItem from './Structures/SkyBlock/SkyBlockItem.js'; +import type SkyBlockMuseum from './Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import type SkyBlockNews from './Structures/SkyBlock/News/SkyBlockNews.js'; +import type SkyBlockProfile from './Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import type SkyBlockSkills from './Structures/SkyBlock/Skills/SkyBlockSkills.js'; +import type Status from './Structures/Status.js'; +import type WatchdogStats from './Structures/WatchdogStats.js'; +import type { + AuctionFetchOptions, + AuctionRequestOptions, + GuildFetchOptions, + PlayerRequestOptions, + SkyBlockAuctionResult, + SkyBlockAuctionsResult, + SkyBlockRequestOptions, + WithRaw, + WithSelectedProfile +} from './Types/API.js'; +import type { ClientOptions } from './Types/Client.js'; +import type { RequestOptions } from './Types/Requests.js'; +import type { SkyBlockProfileName } from './Types/SkyBlock.js'; + +const clients: Client[] = []; + +class Client { + declare options: ClientOptions; + declare requestHandler: RequestHandler; + declare cacheHandler: CacheHandler; + declare functions: Functions; + declare updater: Updater; + declare rateLimit: RateLimit; + readonly key: string; + declare interval: NodeJS.Timeout; + constructor(key: string, options?: ClientOptions) { + this.key = key; + if (!this.key.length) throw new Error(Errors.NO_API_KEY); + this.options = this.parasOptions(options); + this.requestHandler = new RequestHandler(this); + this.cacheHandler = new CacheHandler(this); + this.functions = new Functions(this); + this.updater = new Updater(this); + this.rateLimit = new RateLimit(this); + if (this.options.rateLimit !== 'NONE') this.rateLimit.initialize(); + for (const func in API) { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + const endpoint = new API[func](this); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + this[func] = endpoint.execute.bind(endpoint); + } + if (clients.find((x) => x.key === key)) { + console.warn(Errors.MULTIPLE_INSTANCES); + const found = clients.find((x) => x.key === key); + if (found) { + this.destroy(); + Object.assign(this, found); + } + return; + } + if (this.options.checkForUpdates) { + this.interval = setInterval( + () => { + this.updater.checkForUpdates(); + }, + 1000 * 60 * (this.options.checkForUpdatesInterval ?? 60) + ); + } + clients.push(this); + } + + destroy() { + const clientIndex = clients.findIndex((client) => client.key === this.key); + if (clientIndex !== -1) clients.splice(clientIndex, 1); + if (this.interval) clearInterval(this.interval); + if (this.rateLimit.interval) clearInterval(this.rateLimit.interval); + } + + private parasOptions(options?: ClientOptions): ClientOptions { + return { + cache: options?.cache ?? true, + cacheTime: options?.cacheTime ?? 300, + cacheMaxKeys: options?.cacheMaxKeys ?? -1, + cacheCheckPeriod: options?.cacheCheckPeriod ?? 180, + rateLimit: options?.rateLimit ?? 'AUTO', + silent: options?.silent ?? false, + checkForUpdates: options?.checkForUpdates ?? true, + checkForUpdatesInterval: options?.checkForUpdatesInterval ?? 60 + }; + } + + /* v8 ignore next 140 */ + public getAchievements(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getActiveHouses(options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getBoosters(options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getChallenges(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getGameCounts(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getGuild( + searchParameter: GuildFetchOptions, + query: string, + options?: RequestOptions + ): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getGuildAchievements(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getHouse(query: string, options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getLeaderboards(options?: RequestOptions): Promise> | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getPlayer(query: string, options?: PlayerRequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getPlayerHouses(query: string, options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getQuests(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getRecentGames(query: string, options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockAuction( + type: AuctionFetchOptions, + query: string, + options?: AuctionRequestOptions + ): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockAuctions( + query: number | '*', + options?: AuctionRequestOptions + ): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockBazaar(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockBingo(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockCollections(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockElection(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockEndedAuctions(options?: AuctionRequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockFireSales(options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockGarden(profileId: string, options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockItems(options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockMuseum(profileId: string, options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockNews(options?: RequestOptions): Promise | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockProfile( + profileId: string, + options?: SkyBlockRequestOptions + ): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockProfiles( + query: string, + options?: SkyBlockRequestOptions + ): Promise> | RequestData> { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getSkyBlockSkills(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getStatus(query: string, options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } + + public getWatchdogStats(options?: RequestOptions): Promise { + throw new Error(Errors.ENDPOINT_NOT_LOADED); + } +} + +export default Client; diff --git a/src/Errors.js b/src/Errors.js deleted file mode 100644 index b1d597cd4..000000000 --- a/src/Errors.js +++ /dev/null @@ -1,68 +0,0 @@ -/* eslint-disable max-len */ -module.exports = { - INVALID_API_KEY: '[hypixel-api-reborn] Invalid API Key! For help join our Discord Server https://discord.gg/NSEBNMM', - NO_API_KEY: '[hypixel-api-reborn] No API Key specified! For help join our Discord Server https://discord.gg/NSEBNMM', - ERROR_CODE_CAUSE: - '[hypixel-api-reborn] Code: {code} - {cause}! For help join our Discord Server https://discord.gg/NSEBNMM', - ERROR_STATUSTEXT: '[hypixel-api-reborn] {statustext}! For help join our Discord Server https://discord.gg/NSEBNMM', - KEY_MUST_BE_A_STRING: - '[hypixel-api-reborn] Specified API Key must be a string! For help join our Discord Server https://discord.gg/NSEBNMM', - OPTIONS_MUST_BE_AN_OBJECT: - '[hypixel-api-reborn] Options must be an object! For help join our Discord Server https://discord.gg/NSEBNMM', - CACHE_TIME_MUST_BE_A_NUMBER: - '[hypixel-api-reborn] Cache Time must be a number! For help join our Discord Server https://discord.gg/NSEBNMM', - CACHE_LIMIT_MUST_BE_A_NUMBER: - '[hypixel-api-reborn] Cache Limit must be a number! For help join our Discord Server https://discord.gg/NSEBNMM', - CACHE_FILTER_INVALID: - '[hypixel-api-reborn] Cache Filter must be a function returning a boolean, an object, an array, or a string!', - NO_NICKNAME_UUID: '[hypixel-api-reborn] No nickname or uuid specified.', - NO_UUID: '[hypixel-api-reborn] No uuid specified.', - UUID_NICKNAME_MUST_BE_A_STRING: '[hypixel-api-reborn] Nickname or uuid must be a string.', - MALFORMED_UUID: '[hypixel-api-reborn] Malformed UUID!', - PLAYER_DOES_NOT_EXIST: '[hypixel-api-reborn] Player does not exist.', - PLAYER_HAS_NEVER_LOGGED: '[hypixel-api-reborn] Player has never logged into Hypixel.', - PLAYER_IS_INACTIVE: - "[hypixel-api-reborn] No records of recent games because player hasn't been online for more than 3 days or is lacking data to determine the cause of an empty response", - PLAYER_DISABLED_ENDPOINT: '[hypixel-api-reborn] Player has disabled this endpoint.', - NO_GUILD_QUERY: '[hypixel-api-reborn] No guild search query specified.', - INVALID_GUILD_ID: '[hypixel-api-reborn] Specified Guild ID is invalid.', - INVALID_GUILD_SEARCH_PARAMETER: "[hypixel-api-reborn] getGuild() searchParameter must be 'id', 'guild' or 'player'.", - SOMETHING_WENT_WRONG: '[hypixel-api-reborn] Something went wrong. {cause}', - GUILD_DOES_NOT_EXIST: '[hypixel-api-reborn] Guild does not exist.', - PAGE_INDEX_ERROR: - '[hypixel-api-reborn] Invalid page index. Must be an integer, an array of 2 integers, or a keyword. For help join our Discord Server https://discord.gg/NSEBNMM', - INVALID_OPTION_VALUE: - '[hypixel-api-reborn] Invalid option value! For help join our Discord Server https://discord.gg/NSEBNMM', - INVALID_RESPONSE_BODY: - '[hypixel-api-reborn] An error occurred while converting to JSON. Perhaps this is due to an update or maintenance. For help join our Discord Server https://discord.gg/NSEBNMM', - INVALID_RATE_LIMIT_OPTION: - "[hypixel-api-reborn] Rate Limit provided in Client options must be 'HARD', 'AUTO', or 'NONE'. For help join our Discord Server https://discord.gg/NSEBNMM", - INVALID_KEY_LIMIT_OPTION: - '[hypixel-api-reborn] Key Limit provided in Client options must be an integer representing the amount of requests possible in one minute with your key.', - INVALID_HEADER_SYNC_OPTION: '[hypixel-api-reborn] Invalid Value for maxSyncHeaders : must be a boolean', - INVALID_BURST_OPTION: '[hypixel-api-reborn] maxBurstRequests provided in Client options must be a number', - NODE_VERSION_ERR: - "[hypixel-api-reborn] You are using a version of Nodejs that doesn't support certain features we use. Please upgrade to version 14 or above.", - UPDATER_REQUEST_NOT_OK: '[hypixel-api-reborn] An error occurred checking for updates.', - CONNECTION_ERROR: '[hypixel-api-reborn] Failed to connect.', - RATE_LIMIT_INIT_ERROR: - '[hypixel-api-reborn] An error happened whilst initializing rate limit. We strongly recommend restarting the code as this can lead to desynchronization.', - MULTIPLE_INSTANCES: - '[hypixel-api-reborn] Multiple instances of hypixel-api-reborn are found so we merged them for you. Please refrain from spawning multiple instances in the future. For more information, join our Discord Server https://discord.gg/NSEBNMM.', - INVALID_HEADERS: - '[hypixel-api-reborn] Invalid Headers are provided in ClientOptions. For help join our Discord Server https://discord.gg/NSEBNMM', - INVALID_CACHE_HANDLER: - '[hypixel-api-reborn] An invalid cache handler is provideed. For help join our Discord Server https://discord.gg/NSEBNMM', - UNEXPECTED_ERROR: - "[hypixel-api-reborn] The data provided to hypixel API is malformed and thus not recognized by hypixel, but this shouldn't be your fault. Please report this error in our Discord Server https://discord.gg/NSEBNMM or GitHub. ", - RATE_LIMIT_EXCEEDED: - "[hypixel-api-reborn] The rate limitations on your API Key has been exceeded. There might be an outage (Check Hypixel's status page), or you simply did too many requests in a short time. Hint: Enable rate limit options! They can help you avoid this error! For help join our Discord Server https://discord.gg/NSEBNMM", - NO_SKYBLOCK_PROFILES: '[hypixel-api-reborn] The player has no skyblock profiles.', - INVALID_SILENT_OPTION: '[hypixel-api-reborn] Invalid Value for silent : must be a boolean', - INVALID_UPDATE_OPTION: '[hypixel-api-reborn] Invalid Value for update : must be a boolean', - INVALID_THIRD_PARTY_API_OPTION: '[hypixel-api-reborn] Invalid Third Party API option : must be a boolean or string', - BAD_AUCTION_FILTER: - '[hypixel-api-reborn] Unexpected filter for Client#getSkyblockAuction. Expected one of "PLAYER", "AUCTION", "PROFILE", but got something else.', - RECENT_REQUEST: - '[Hypixel-API-Reborn] You have requested that player recently. Try turning on cache. For help join our Discord Server https://discord.gg/NSEBNMM' -}; diff --git a/src/Errors.ts b/src/Errors.ts new file mode 100644 index 000000000..eade9b6c4 --- /dev/null +++ b/src/Errors.ts @@ -0,0 +1,48 @@ +/* eslint-disable @stylistic/max-len */ +class Errors { + static INVALID_API_KEY: string = + '[Hypixel-API-Reborn] Invalid API Key! For help join our Discord Server https://discord.gg/NSEBNMM'; + static NO_API_KEY: string = + '[Hypixel-API-Reborn] No API Key specified! For help join our Discord Server https://discord.gg/NSEBNMM'; + static ERROR_CODE_CAUSE: string = + '[Hypixel-API-Reborn] Code: {code} - {cause}! For help join our Discord Server https://discord.gg/NSEBNMM'; + static ERROR_STATUSTEXT: string = + '[Hypixel-API-Reborn] {statustext}! For help join our Discord Server https://discord.gg/NSEBNMM'; + static NO_NICKNAME_UUID: string = '[Hypixel-API-Reborn] No nickname or uuid specified.'; + static NO_UUID: string = '[Hypixel-API-Reborn] No uuid specified.'; + static UUID_NICKNAME_MUST_BE_A_STRING: string = '[Hypixel-API-Reborn] Nickname or uuid must be a string.'; + static MALFORMED_UUID: string = '[Hypixel-API-Reborn] Malformed UUID!'; + static PLAYER_HAS_NEVER_LOGGED: string = '[Hypixel-API-Reborn] Player has never logged into Hypixel.'; + static NO_GUILD_QUERY: string = '[Hypixel-API-Reborn] No guild search query specified.'; + static INVALID_GUILD_ID: string = '[Hypixel-API-Reborn] Specified Guild ID is invalid.'; + static INVALID_GUILD_SEARCH_PARAMETER: string = + "[Hypixel-API-Reborn] getGuild() searchParameter must be 'id'; 'guild' or 'player'."; + static SOMETHING_WENT_WRONG: string = '[Hypixel-API-Reborn] Something went wrong. {cause}'; + static GUILD_DOES_NOT_EXIST: string = '[Hypixel-API-Reborn] Guild does not exist.'; + static PAGE_INDEX_ERROR: string = + '[Hypixel-API-Reborn] Invalid page index. Must be an integer, an array of 2 integers, or a keyword. For help join our Discord Server https://discord.gg/NSEBNMM'; + static INVALID_OPTION_VALUE: string = + '[Hypixel-API-Reborn] Invalid option value! For help join our Discord Server https://discord.gg/NSEBNMM'; + static UPDATER_REQUEST_NOT_OK: string = '[Hypixel-API-Reborn] Something went wrong while checking for updates.'; + static MULTIPLE_INSTANCES: string = + '[Hypixel-API-Reborn] Multiple instances of hypixel-api-reborn are found so we merged them for you. Please refrain from spawning multiple instances in the future. For more information, join our Discord Server https://discord.gg/NSEBNMM.'; + static UNEXPECTED_ERROR: string = + "[Hypixel-API-Reborn] The data provided to hypixel API is malformed and thus not recognized by hypixel, but this shouldn't be your fault. Please report this error in our Discord Server https://discord.gg/NSEBNMM or GitHub. "; + static RATE_LIMIT_EXCEEDED: string = + "[Hypixel-API-Reborn] The rate limitations on your API Key has been exceeded. There might be an outage (Check Hypixel's status page), or you simply did too many requests in a short time. Hint: Enable rate limit options! They can help you avoid this error! For help join our Discord Server https://discord.gg/NSEBNMM"; + static RECENT_REQUEST: string = + '[Hypixel-API-Reborn] You have requested that player recently. Try turning on cache. For help join our Discord Server https://discord.gg/NSEBNMM'; + static NO_SKYBLOCK_PROFILES: string = '[Hypixel-API-Reborn] The player has no SkyBlock profiles.'; + static BAD_AUCTION_FILTER: string = + '[Hypixel-API-Reborn] Unexpected filter for Client#getSkyBlockAuction. Expected one of "PROFILE", "PLAYER", "AUCTION_ID", but got something else.'; + static NOT_IMPLEMENTED: string = + '[Hypixel-API-Reborn] Endpoint execute method is not implemented yet! Please report this https://discord.gg/NSEBNMM'; + static RATE_LIMIT_INIT_ERROR: string = + '[hypixel-api-reborn] An error happened whilst initializing rate limit. We strongly recommend restarting the code as this can lead to de-synchronization.'; + static ENDPOINT_NOT_LOADED: string = + '[hypixel-api-reborn] This endpoint has not been loaded yet. Please restart your code'; + static INVALID_BASE_URL: string = '[Hypixel-API-Reborn] Invalid Request URL.'; + static INVALID_BASE_URL_SLASH: string = "[Hypixel-API-Reborn] Invalid Request URL. Please don't end with a /"; +} + +export default Errors; diff --git a/src/Private/CacheHandler.test.ts b/src/Private/CacheHandler.test.ts new file mode 100644 index 000000000..8f5699520 --- /dev/null +++ b/src/Private/CacheHandler.test.ts @@ -0,0 +1,50 @@ +import CacheHandler from './CacheHandler.js'; +import Client from '../Client.js'; +import NodeCache from 'node-cache'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('CacheHandler', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client).toBeDefined(); + expectTypeOf(client).toEqualTypeOf(); + + expect(client.cacheHandler).toBeDefined(); + expectTypeOf(client.cacheHandler).toEqualTypeOf(); + + expect(client.cacheHandler.cache).toBeDefined(); + expectTypeOf(client.cacheHandler.cache).toEqualTypeOf(); + + expect(client.cacheHandler.set).toBeDefined(); + expectTypeOf(client.cacheHandler.set).toBeFunction(); + expect(() => client.cacheHandler.set('test', 'value')).not.toThrow(); + + expect(client.cacheHandler.get).toBeDefined(); + expectTypeOf(client.cacheHandler.get).toBeFunction(); + expect(() => client.cacheHandler.has('test')).not.toThrow(); + expect(client.cacheHandler.has('test')).toBe(true); + + expect(client.cacheHandler.get).toBeDefined(); + expectTypeOf(client.cacheHandler.get).toBeFunction(); + expect(() => client.cacheHandler.get('test')).not.toThrow(); + expect(client.cacheHandler.get('test')).toBe('value'); + + expect(client.cacheHandler.keys).toBeDefined(); + expectTypeOf(client.cacheHandler.keys).toBeFunction(); + expect(() => client.cacheHandler.keys()).not.toThrow(); + expect(client.cacheHandler.keys()).toEqual(['test']); + expectTypeOf(client.cacheHandler.keys()).toEqualTypeOf(); + + expect(client.cacheHandler.size).toBeDefined(); + expectTypeOf(client.cacheHandler.size).toBeFunction(); + expect(() => client.cacheHandler.size()).not.toThrow(); + expect(client.cacheHandler.size()).toBe(1); + expectTypeOf(client.cacheHandler.size()).toEqualTypeOf(); + + expect(client.cacheHandler.clear).toBeDefined(); + expectTypeOf(client.cacheHandler.clear).toBeFunction(); + expect(() => client.cacheHandler.clear()).not.toThrow(); + expect(client.cacheHandler.size()).toBe(0); + + client.destroy(); +}); diff --git a/src/Private/CacheHandler.ts b/src/Private/CacheHandler.ts new file mode 100644 index 000000000..6d73bf76a --- /dev/null +++ b/src/Private/CacheHandler.ts @@ -0,0 +1,41 @@ +import Client from '../Client.js'; +import NodeCache from 'node-cache'; + +class CacheHandler { + readonly client: Client; + declare cache: NodeCache; + constructor(client: Client) { + this.client = client; + this.cache = new NodeCache({ + stdTTL: this.client.options.cacheTime, + maxKeys: this.client.options.cacheMaxKeys, + checkperiod: this.client.options.cacheCheckPeriod + }); + } + + set(key: string, value: any): any { + return this.cache.set(key, value); + } + + has(key: string): boolean { + return this.cache.has(key); + } + + get(key: string): any { + return this.cache.get(key); + } + + keys(): string[] { + return this.cache.keys(); + } + + size(): number { + return this.cache.keys().length; + } + + clear(): void { + this.cache.flushAll(); + } +} + +export default CacheHandler; diff --git a/src/Private/Endpoint.test.ts b/src/Private/Endpoint.test.ts new file mode 100644 index 000000000..c2252c504 --- /dev/null +++ b/src/Private/Endpoint.test.ts @@ -0,0 +1,25 @@ +import Client from '../Client.js'; +import Endpoint from './Endpoint.js'; +import Errors from '../Errors.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Endpoint', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client).toBeDefined(); + expectTypeOf(client).toEqualTypeOf(); + + const endpoint = new Endpoint(client); + + expect(endpoint).toBeDefined(); + expectTypeOf(endpoint).toEqualTypeOf(); + + expect(endpoint.client).toBeDefined(); + expectTypeOf(endpoint.client).toEqualTypeOf(); + + expect(endpoint.execute).toBeDefined(); + expectTypeOf(endpoint.execute).toBeFunction(); + expect(() => endpoint.execute()).toThrowError(Errors.NOT_IMPLEMENTED); + + client.destroy(); +}); diff --git a/src/Private/Endpoint.ts b/src/Private/Endpoint.ts new file mode 100644 index 000000000..7292a7575 --- /dev/null +++ b/src/Private/Endpoint.ts @@ -0,0 +1,15 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; + +class Endpoint { + readonly client: Client; + constructor(client: Client) { + this.client = client; + } + + execute(...args: any[]): Promise | any { + throw new Error(Errors.NOT_IMPLEMENTED); + } +} + +export default Endpoint; diff --git a/src/Private/Functions.test.ts b/src/Private/Functions.test.ts new file mode 100644 index 000000000..610569505 --- /dev/null +++ b/src/Private/Functions.test.ts @@ -0,0 +1,57 @@ +import Client from '../Client.js'; +import Functions from './Functions.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Functions', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client).toBeDefined(); + expectTypeOf(client).toEqualTypeOf(); + expect(client.functions).toBeDefined(); + expectTypeOf(client.functions).toEqualTypeOf(); + + expect(client.functions.isUUID).toBeDefined(); + const valid = [ + 'add71246c46e455c8345c129ea6f146c', + '17ec71b4e5fa467481344b319a2958c3', + '37501e7512b845ab8796e2baf9e9677a' + ]; + const dashed = [ + 'add71246-c46e-455c-8345-c129ea6f146c', + '1ac8f319-1ac8-4c44-93ac-fcae2848cd9f', + '337a48bf-57e9-44eb-8acb-83b885936e83' + ]; + const Invalid = ['invalid', 'hello why are you here?', '']; + + valid.forEach((uuid) => { + expect(client.functions.isUUID(uuid)).toBe(true); + expectTypeOf(client.functions.isUUID(uuid)).toBeBoolean(); + }); + + dashed.forEach((uuid) => { + expect(client.functions.isUUID(uuid)).toBe(true); + expectTypeOf(client.functions.isUUID(uuid)).toBeBoolean(); + }); + + Invalid.forEach((uuid) => { + expect(client.functions.isUUID(uuid)).toBe(false); + expectTypeOf(client.functions.isUUID(uuid)).toBeBoolean(); + }); + + expect(client.functions.isGuildID).toBeDefined(); + + const ids = ['5b8dd8cb0cf24573ab84c9ad', '656618008ea8c9dca6f3668d', '5ba94ed50cf2cc24cf043706']; + const idsInvalid = ['invalid', 'hello why are you here?', '']; + + ids.forEach((id) => { + expect(client.functions.isGuildID(id)).toBe(true); + expectTypeOf(client.functions.isGuildID(id)).toBeBoolean(); + }); + + idsInvalid.forEach((id) => { + expect(client.functions.isGuildID(id)).toBe(false); + expectTypeOf(client.functions.isGuildID(id)).toBeBoolean(); + }); + + client.destroy(); +}); diff --git a/src/Private/Functions.ts b/src/Private/Functions.ts new file mode 100644 index 000000000..8cda06708 --- /dev/null +++ b/src/Private/Functions.ts @@ -0,0 +1,20 @@ +import Client from '../Client.js'; + +class Functions { + client: Client; + constructor(client: Client) { + this.client = client; + } + + isUUID(uuid: string): boolean { + const regexp = /^[0-9a-f]{32}$/i; + uuid = uuid.replace(/-/g, ''); + return regexp.test(uuid); + } + + isGuildID(id: string): boolean { + return id.length === 24; + } +} + +export default Functions; diff --git a/src/Private/RateLimit.test.ts b/src/Private/RateLimit.test.ts new file mode 100644 index 000000000..349a278e7 --- /dev/null +++ b/src/Private/RateLimit.test.ts @@ -0,0 +1,92 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RateLimit from './RateLimit.js'; +import { defaultRequestData } from '../../vitest.setup.js'; +import { expect, expectTypeOf, test, vi } from 'vitest'; + +test('RateLimit (None)', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client).toBeDefined(); + expectTypeOf(client).toEqualTypeOf(); + + expect(client.rateLimit).toBeDefined(); + expectTypeOf(client.rateLimit).toEqualTypeOf(); + + expect(client.rateLimit.requests).toBe(0); + expectTypeOf(client.rateLimit.requests).toEqualTypeOf(); + expect(client.rateLimit.limit).toBe(0); + expectTypeOf(client.rateLimit.limit).toEqualTypeOf(); + expect(client.rateLimit.initialized).toBe(false); + expectTypeOf(client.rateLimit.initialized).toEqualTypeOf(); + + expect(client.rateLimit.sync).toBeDefined(); + expectTypeOf(client.rateLimit.sync).toBeFunction(); + expect(() => client.rateLimit.sync()).not.toThrow(); + + expect(client.rateLimit.reset).toBeDefined(); + expectTypeOf(client.rateLimit.reset).toBeFunction(); + expect(() => client.rateLimit.reset()).not.toThrow(); + + expect(client.rateLimit.initialize).toBeDefined(); + expectTypeOf(client.rateLimit.initialize).toBeFunction(); + expect(() => client.rateLimit.initialize()).not.toThrow(); + + client.destroy(); +}); + +test('RateLimit (Auto)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + + expect(client.rateLimit).toBeDefined(); + expectTypeOf(client.rateLimit).toEqualTypeOf(); + await client.rateLimit.initialize(); + + expect(client.rateLimit.requests).greaterThan(0); + expectTypeOf(client.rateLimit.requests).toEqualTypeOf(); + expect(client.rateLimit.limit).toBe(300); + expectTypeOf(client.rateLimit.limit).toEqualTypeOf(); + expect(client.rateLimit.initialized).toBe(true); + expectTypeOf(client.rateLimit.initialized).toEqualTypeOf(); + + expect(client.rateLimit.sync).toBeDefined(); + expectTypeOf(client.rateLimit.sync).toBeFunction(); + expect(() => client.rateLimit.sync()).not.toThrow(); + + expect(client.rateLimit.reset).toBeDefined(); + expectTypeOf(client.rateLimit.reset).toBeFunction(); + expect(() => client.rateLimit.reset()).not.toThrow(); + + expect(client.rateLimit.initialize).toBeDefined(); + expectTypeOf(client.rateLimit.initialize).toBeFunction(); + expect(() => client.rateLimit.initialize()).not.toThrow(); + + client.destroy(); +}); + +test('Ratelimit (Sync)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? ''); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + client.updater.currentVersion = '1.0.0'; + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + headers: new Headers({ 'ratelimit-limit': '30', 'ratelimit-remaining': '27' }) + } as any); + expect(() => client.rateLimit.sync()).not.toThrowError(); + await client.rateLimit.sync(); + expect(client.rateLimit.requests).toBe(3); + expect(client.rateLimit.limit).toBe(30); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('Ratelimit (Bad Sync Data)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? ''); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + client.updater.currentVersion = '1.0.0'; + vi.spyOn(global, 'fetch').mockResolvedValue({ ...defaultRequestData, headers: new Headers({ hello: '100' }) } as any); + await expect(() => client.rateLimit.sync()).rejects.toThrowError(Errors.RATE_LIMIT_INIT_ERROR); + vi.restoreAllMocks(); + client.destroy(); +}); diff --git a/src/Private/RateLimit.ts b/src/Private/RateLimit.ts new file mode 100644 index 000000000..86fd39740 --- /dev/null +++ b/src/Private/RateLimit.ts @@ -0,0 +1,39 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; + +class RateLimit { + readonly client: Client; + declare requests: number; + declare limit: number; + declare initialized: boolean; + declare interval: NodeJS.Timeout; + constructor(client: Client) { + this.client = client; + this.requests = 0; + this.limit = 0; + this.initialized = false; + this.interval = setInterval(() => this.reset(), 300000); + } + + async sync() { + const { headers } = await this.client.requestHandler.request('/boosters', { raw: true }); + if (headers?.['ratelimit-limit'] === undefined || headers?.['ratelimit-remaining'] === undefined) { + throw new Error(Errors.RATE_LIMIT_INIT_ERROR); + } + this.requests = headers['ratelimit-limit'] - headers['ratelimit-remaining']; + this.limit = Number(headers['ratelimit-limit']); + } + + reset() { + if (this.initialized === false) return; + this.requests = 0; + } + + async initialize() { + if (this.initialized) return; + await this.sync(); + this.initialized = true; + } +} + +export default RateLimit; diff --git a/src/Private/RequestData.ts b/src/Private/RequestData.ts new file mode 100644 index 000000000..93dea40bf --- /dev/null +++ b/src/Private/RequestData.ts @@ -0,0 +1,32 @@ +import type { RequestOptions } from '../Types/Requests.js'; + +class RequestData { + readonly data: any; + readonly headers: Record; + readonly statusCode: number; + readonly options: RequestOptions; + readonly requestTimestamp: number; + readonly requestAt: Date; + readonly requestUrl: string; + readonly cached: boolean; + constructor( + data: Record, + headers: Record, + info: { status: number; url: string; options: RequestOptions; cached: boolean; timestamp?: number } + ) { + this.data = data; + this.headers = headers; + this.statusCode = info.status; + this.options = info.options; + this.requestTimestamp = info.timestamp || Date.now(); + this.requestAt = new Date(this.requestTimestamp); + this.requestUrl = info.url; + this.cached = info.cached; + } + + isRaw(): this is RequestData { + return true; + } +} + +export default RequestData; diff --git a/src/Private/RequestHandler.test.ts b/src/Private/RequestHandler.test.ts new file mode 100644 index 000000000..6f3c722e0 --- /dev/null +++ b/src/Private/RequestHandler.test.ts @@ -0,0 +1,104 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestHandler from './RequestHandler.js'; +import { defaultRequestData } from '../../vitest.setup.js'; +import { expect, expectTypeOf, test, vi } from 'vitest'; + +test('RequestHandler', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler).toBeDefined(); + expectTypeOf(client.requestHandler).toEqualTypeOf(); + + expect(client.requestHandler.toUUID).toBeDefined(); + expectTypeOf(client.requestHandler.toUUID).toBeFunction(); + const data = await client.requestHandler.toUUID('pixelic'); + expect(data).toBe('14727faefbdc4aff848cd2713eb9939e'); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.requestHandler.toUUID()).rejects.toThrowError(Errors.NO_NICKNAME_UUID); + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + await expect(() => client.requestHandler.toUUID(-1)).rejects.toThrowError(Errors.UUID_NICKNAME_MUST_BE_A_STRING); + + client.destroy(); +}); + +test('RequestHandler (Invalid API Key)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler.request).toBeDefined(); + expectTypeOf(client.requestHandler.request).toBeFunction(); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 403, + json: () => Promise.resolve({ success: false }) + } as any); + await expect(() => client.requestHandler.request('/boosters')).rejects.toThrowError(Errors.INVALID_API_KEY); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('RequestHandler (400 Bad Request)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler.request).toBeDefined(); + expectTypeOf(client.requestHandler.request).toBeFunction(); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 400, + json: () => Promise.resolve({ success: false, cause: 'meow' }) + } as any); + await expect(() => client.requestHandler.request('/boosters')).rejects.toThrowError( + Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, 'meow') + ); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('RequestHandler (400 Bad Request No Cause)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler.request).toBeDefined(); + expectTypeOf(client.requestHandler.request).toBeFunction(); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 400, + json: () => Promise.resolve({ success: false }) + } as any); + await expect(() => client.requestHandler.request('/boosters')).rejects.toThrowError( + Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, 'UNKNOWN') + ); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('RequestHandler (Unprocessable Entity)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler.request).toBeDefined(); + expectTypeOf(client.requestHandler.request).toBeFunction(); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 422, + json: () => Promise.resolve({ success: false }) + } as any); + await expect(() => client.requestHandler.request('/boosters')).rejects.toThrowError(Errors.UNEXPECTED_ERROR); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('RequestHandler (Rate Limited)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client.requestHandler.request).toBeDefined(); + expectTypeOf(client.requestHandler.request).toBeFunction(); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 429, + json: () => Promise.resolve({ success: false }) + } as any); + await expect(() => client.requestHandler.request('/boosters')).rejects.toThrowError(Errors.RATE_LIMIT_EXCEEDED); + vi.restoreAllMocks(); + client.destroy(); +}); diff --git a/src/Private/RequestHandler.ts b/src/Private/RequestHandler.ts new file mode 100644 index 000000000..ef7558925 --- /dev/null +++ b/src/Private/RequestHandler.ts @@ -0,0 +1,140 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import RequestData from './RequestData.js'; +import type { RequestOptions } from '../Types/Requests.js'; + +class RequestHandler { + readonly client: Client; + private BASE_URL: string; + constructor(client: Client) { + this.client = client; + this.BASE_URL = 'https://api.hypixel.net/v2'; + } + + setBaseURL(url: string = 'https://api.hypixel.net/v2'): this { + if (!url.startsWith('http') || !url.includes('://')) throw new Error(Errors.INVALID_BASE_URL); + if (url.endsWith('/')) throw new Error(Errors.INVALID_BASE_URL_SLASH); + this.BASE_URL = url; + return this; + } + + async request(endpoint: string, options?: RequestOptions): Promise { + options = { + raw: options?.raw ?? false, + noCache: options?.noCache ?? false, + noCacheCheck: options?.noCacheCheck ?? false + }; + if (!options.noCacheCheck && this.client.cacheHandler.has(endpoint)) { + const data = this.client.cacheHandler.get(endpoint); + return new RequestData(data.data, data.headers, { + status: 200, + options, + url: endpoint, + cached: true, + timestamp: data.timestamp + }); + } + const res = await fetch(this.BASE_URL + endpoint, { headers: { 'API-Key': this.client.key } }); + if (res.status >= 500 && res.status < 528) { + throw new Error( + Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`) + ); + } + const parsedRes = (await res.json()) as Record; + if (res.status === 400) { + throw new Error( + Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || 'UNKNOWN') + ); + } + if (res.status === 403) throw new Error(Errors.INVALID_API_KEY); + if (res.status === 422) throw new Error(Errors.UNEXPECTED_ERROR); + if ( + res.status === 429 && + parsedRes.cause === 'You have already looked up this player too recently, please try again shortly' + ) { + throw new Error(Errors.RECENT_REQUEST); + } + if (res.status === 429) throw new Error(Errors.RATE_LIMIT_EXCEEDED); + if (res.status !== 200) { + throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText)); + } + if (!parsedRes.success && !endpoint.startsWith('/housing')) { + throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.statusText)); + } + this.client.rateLimit.requests++; + const headers: Record = {}; + res.headers.forEach((value, key) => (headers[key] = value)); + const requestData = new RequestData(parsedRes, headers, { + status: res.status, + options, + url: endpoint, + cached: false + }); + if (options.noCache) return requestData; + if (this.client.options.cache) { + this.client.cacheHandler.set(endpoint, requestData); + } + return requestData; + } + + async toUUID(input: string): Promise { + if (!input) throw new Error(Errors.NO_NICKNAME_UUID); + if (typeof input !== 'string') throw new Error(Errors.UUID_NICKNAME_MUST_BE_A_STRING); + if (this.client.functions.isUUID(input)) return input.replace(/-/g, ''); + const url = `https://mowojang.matdoes.dev/${input}`; + if (this.client.cacheHandler.has(url)) { + return this.client.cacheHandler.get(url); + } + const res = await fetch(url); + if (res.status >= 500 && res.status < 528) { + throw new Error( + Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`) + ); + } + const parsedRes = (await res.json()) as Record; + if (res.status === 400) { + throw new Error( + Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || '') + ); + } + if (res.status !== 200) { + throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText)); + } + if (typeof parsedRes.id !== 'string' || typeof parsedRes.name !== 'string') { + throw new Error(Errors.MALFORMED_UUID); + } + if (this.client.options.cache) { + this.client.cacheHandler.set(url, parsedRes.id); + } + return parsedRes.id; + } + + async fetchExternalData(url: string): Promise { + if (this.client.cacheHandler.has(url)) { + const data = this.client.cacheHandler.get(url); + return new RequestData(data.data, data.headers, { + status: 200, + options: { raw: false, noCache: false }, + url, + cached: true, + timestamp: data.timestamp + }); + } + const res = await fetch(url); + const parsedRes = (await res.json()) as Record; + const headers: Record = {}; + res.headers.forEach((value, key) => (headers[key] = value)); + const requestData = new RequestData(parsedRes, headers, { + status: res.status, + options: { raw: false, noCache: false }, + url, + cached: false + }); + if (this.client.options.cache) { + this.client.cacheHandler.set(url, requestData); + } + return requestData; + } +} + +export default RequestHandler; diff --git a/src/Private/Updater.test.ts b/src/Private/Updater.test.ts new file mode 100644 index 000000000..21f17a7b4 --- /dev/null +++ b/src/Private/Updater.test.ts @@ -0,0 +1,81 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import Updater from './Updater.js'; +import packageJSON from '../../package.json' with { type: 'json' }; +import { defaultRequestData } from '../../vitest.setup.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import { vi } from 'vitest'; + +test('Updater', () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + expect(client).toBeDefined(); + expectTypeOf(client).toEqualTypeOf(); + + expect(client.updater).toBeDefined(); + expectTypeOf(client.updater).toEqualTypeOf(); + + expect(client.updater.currentVersion).toBe(packageJSON.version); + expect(client.updater.latestVersion).toBe('0.0.0'); + + expect(client.updater.checkForUpdates).toBeDefined(); + expectTypeOf(client.updater.checkForUpdates).toBeFunction(); + expect(() => client.updater.checkForUpdates()).not.toThrow(); + + expect(client.updater.getLatestVersion).toBeDefined(); + expectTypeOf(client.updater.getLatestVersion).toBeFunction(); + expect(() => client.updater.getLatestVersion()).not.toThrow(); + + expect(client.updater.compareVersions).toBeDefined(); + expectTypeOf(client.updater.compareVersions).toBeFunction(); + expect(() => client.updater.compareVersions('1.0.0', '1.0.0')).not.toThrow(); + expect(client.updater.compareVersions('1.0.0', '1.0.0')).toBe(false); + expect(client.updater.compareVersions('1.0.0', '1.0.1')).toBe(true); + expect(client.updater.compareVersions('1.0.1', '1.0.0')).toBe(false); + expect(client.updater.compareVersions('meow', '1.0.0')).toBe(false); + + client.destroy(); +}); + +test('Updater (getLatestVersion)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + json: () => Promise.resolve({ 'dist-tags': { latest: '1.0.0' } }) + } as any); + const data = await client.updater.getLatestVersion(); + expect(data).toBe('1.0.0'); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('Updater (getLatestVersion error)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + status: 404, + json: () => Promise.resolve({ 'dist-tags': { latest: '1.0.0' } }) + } as any); + await expect(() => client.updater.getLatestVersion()).rejects.toThrowError(Errors.UPDATER_REQUEST_NOT_OK); + vi.restoreAllMocks(); + client.destroy(); +}); + +test('Updater (check version)', async () => { + const client = new Client(process.env.HYPIXEL_KEY ?? '', { cache: false, checkForUpdates: false, rateLimit: 'NONE' }); + client.requestHandler.setBaseURL(process.env.HYPIXEL_URL); + const consoleLogSpy = vi.spyOn(console, 'log'); + client.updater.currentVersion = '1.0.0'; + vi.spyOn(global, 'fetch').mockResolvedValue({ + ...defaultRequestData, + json: () => Promise.resolve({ 'dist-tags': { latest: packageJSON.version } }) + } as any); + await client.updater.checkForUpdates(); + expect(consoleLogSpy).toHaveBeenCalledWith( + `New version of hypixel-api-reborn is available! Current version: 1.0.0, Latest version: ${packageJSON.version}` + ); + vi.restoreAllMocks(); + client.destroy(); +}); diff --git a/src/Private/Updater.ts b/src/Private/Updater.ts new file mode 100644 index 000000000..1e4cb00b1 --- /dev/null +++ b/src/Private/Updater.ts @@ -0,0 +1,47 @@ +import Client from '../Client.js'; +import Errors from '../Errors.js'; +import packageJson from '../../package.json' with { type: 'json' }; + +class Updater { + readonly client: Client; + currentVersion: string; + latestVersion: string; + constructor(client: Client) { + this.client = client; + this.currentVersion = packageJson.version; + this.latestVersion = '0.0.0'; + } + + async checkForUpdates(): Promise { + this.latestVersion = await this.getLatestVersion(); + const compare = this.compareVersions(this.currentVersion, this.latestVersion); + if (compare) { + console.log( + `New version of hypixel-api-reborn is available! Current version: ${ + this.currentVersion + }, Latest version: ${this.latestVersion}` + ); + } + } + + async getLatestVersion(): Promise { + const request = await this.client.requestHandler.fetchExternalData('https://registry.npmjs.org/hypixel-api-reborn'); + if (request.statusCode !== 200) throw new Error(Errors.UPDATER_REQUEST_NOT_OK); + return request.data['dist-tags'].latest; + } + + compareVersions(a: string, b: string): boolean { + const pa = a.split('.'); + const pb = b.split('.'); + for (let i = 0; i < 3; i++) { + const na = Number(pa[i]); + const nb = Number(pb[i]); + if (isNaN(na) || isNaN(nb)) return false; + if (na > nb) return false; + if (nb > na) return true; + } + return false; + } +} + +export default Updater; diff --git a/src/Private/defaultCache.js b/src/Private/defaultCache.js deleted file mode 100644 index 6fc8606ba..000000000 --- a/src/Private/defaultCache.js +++ /dev/null @@ -1,77 +0,0 @@ -/** - * This is the default cache implementation, using a Map. - * All cache implementations must have these methods below, they can be async : - * set(key, value) : Sets key to value - * has(key) : Whether there is an entry to this key. (can be an alias to get) - * get(key) : Gets by key (nullish value if not found) - * delete(key) : Deletes by key - * keys() : Array of keys, ordered by time of creation. To help you, the key will be deleted and set in case of an update - * size(): Size of cache (number of keys) - * clear(): Deletes all cache entries - * See JSDoc for more info - */ -class Cache { - /** - * Constructor - */ - constructor() { - this.storage = new Map(); - } - /** - * Sets an entry - * @param {string} key String key - * @param {*} value Any value - * @return {boolean} - */ - set(key, value) { - return this.storage.set(key, value); - } - /** - * Check if there's an entry in the cache that has this key - * This doesn't have to return boolean, just a truthy/falsy value - * @param {string} key String key - * @return {boolean} Whether this key exists - */ - has(key) { - return this.storage.has(key); - } - /** - * Gets an entry, return a nullish value if not found - * @param {string} key String key - * @return {*} - */ - get(key) { - return this.storage.get(key); - } - /** - * Deletes an entry - * @param {string} key String key - * @return {boolean} Preferably, returns a boolean to check if the deletion is actually successful - */ - delete(key) { - return this.storage.delete(key); - } - /** - * Returns Array of string (not an iterator preferably, it can break) - * @return {string[]} - */ - keys() { - return Array.from(this.storage.keys()); - } - /** - * Returns size of cache - * @return {number} - */ - size() { - return this.storage.size; - } - /** - * Clears cache - * @return {void} - */ - clear() { - this.storage.clear(); - } -} - -module.exports = Cache; diff --git a/src/Private/rateLimit.js b/src/Private/rateLimit.js deleted file mode 100644 index 3f32fb87c..000000000 --- a/src/Private/rateLimit.js +++ /dev/null @@ -1,83 +0,0 @@ -const Errors = require('../Errors'); - -class RateLimit { - constructor() { - this.initialized = 0; - } - - async rateLimitManager() { - if (!this.initialized) return; - this.requests++; - this.requestQueue.unshift(Date.now()); - if ('NONE' === this.options.rateLimit || !this.requestQueue.length) return; - if ('AUTO' === this.options.rateLimit && this.requests <= this.options.keyLimit / 2) return; - const cooldown = this.computeCooldownTime(); - this.requestQueue[0] = Date.now() + cooldown; - return await new Promise((r) => setTimeout(r, cooldown), true); - } - - sync(data) { - this.options.keyLimit = parseInt(data.get('ratelimit-limit'), 10) || this.options.keyLimit; - this.requests = parseInt(data.get('ratelimit-remaining'), 10) || this.requests; - if ( - data.get('ratelimit-reset') && - Math.round(Date.now() / 1000) - (300 - parseInt(data.get('ratelimit-reset'), 10)) !== - Math.round(this.lastResetHappenedAt / 1000) - ) { - clearTimeout(this.resetTimer); - this.resetTimer = setTimeout(this.reset.bind(this), parseInt(data.get('ratelimit-reset'), 10) * 1000); - } - } - - computeCooldownTime() { - const overhead = this.requestQueue[1] <= Date.now() ? 0 : this.requestQueue[1] - Date.now(); - const multiplier = Math.floor(this.requests / this.options.keyLimit) + 1; - return ( - overhead + - (-overhead - Date.now() + 300000 * multiplier + this.lastResetHappenedAt) / - (this.options.keyLimit * multiplier - this.requests) - ); - } - - reset() { - this.requests = this.requests - this.options.keyLimit; - if (0 > this.requests) this.requests = 0; - this.lastResetHappenedAt = Date.now(); - this.resetTimer = setTimeout(this.reset.bind(this), 300000); - this.requestQueue = this.requestQueue.filter((x) => x >= Date.now()); - } - - rateLimitMonitor() { - this.resetTimer = setTimeout(this.reset.bind(this), 1000 * 300); - } - - init(keyInfo, options, client) { - this.options = options; - this.requests = 0; - this.cooldownTime = 300000 / this.options.keyLimit; - this.requestQueue = []; - this.client = client; - return keyInfo - .then((info) => { - this.requests = info.requestsInPastMin; - this.lastResetHappenedAt = Date.now() - (300 - info.resetsAfter) * 1000; - this.resetTimer = setTimeout(this.rateLimitMonitor.bind(this), 1000 * info.resetsAfter); - this.initialized = 1; - }) - .catch(() => { - client.emit('warn', Errors.RATE_LIMIT_INIT_ERROR); - this.requests = 0; - this.lastResetHappenedAt = Date.now(); - this.rateLimitMonitor(); - this.initialized = 1; - }); - // Still make the requests per min possible - } -} -module.exports = RateLimit; -/** - * @typedef {Object} RLOptions - * @property {number} keyLimit Max request of key per min - * @property {'NONE'|'AUTO'|'HARD'} rateLimit rate limit mode - * @property {boolean} syncWithHeaders Sync rate limits with headers - */ diff --git a/src/Private/requests.js b/src/Private/requests.js deleted file mode 100644 index 147fa1580..000000000 --- a/src/Private/requests.js +++ /dev/null @@ -1,82 +0,0 @@ -const requireFetch = !globalThis.fetch; -const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -const fetch = requireFetch ? externalFetch : globalThis.fetch; -const BASE_URL = 'https://api.hypixel.net/v2'; -const Cache = require('./defaultCache'); -const Errors = require('../Errors'); - -class Requests { - constructor(client, cache) { - if (cache && !this.validateCustomCache()) throw new Error(Errors.INVALID_CACHE_HANDLER); - this.cached = cache || new Cache(); - this.client = client; - } - async request(endpoint, options = {}) { - options.headers = { 'API-Key': this.client.key, ...options.headers }; - /** - * @type {externalFetch.Response|Response} - */ - const res = await fetch(BASE_URL + endpoint, options); - if (500 <= res.status && 528 > res.status) { - throw new Error( - Errors.ERROR_STATUSTEXT.replace(/{statustext}/, `Server Error : ${res.status} ${res.statusText}`) - ); - } - const parsedRes = await res.json().catch(() => { - throw new Error(Errors.INVALID_RESPONSE_BODY); - }); - if (400 === res.status) { - throw new Error( - Errors.ERROR_CODE_CAUSE.replace(/{code}/, '400 Bad Request').replace(/{cause}/, parsedRes.cause || '') - ); - } - if (403 === res.status) throw new Error(Errors.INVALID_API_KEY); - if (422 === res.status) throw new Error(Errors.UNEXPECTED_ERROR); - if ( - 429 === res.status && - 'You have already looked up this player too recently, please try again shortly' === parsedRes.cause - ) { - throw new Error(Errors.RECENT_REQUEST); - } - if (429 === res.status) throw new Error(Errors.RATE_LIMIT_EXCEEDED); - if (200 !== res.status) throw new Error(Errors.ERROR_STATUSTEXT.replace(/{statustext}/, res.statusText)); - if (!parsedRes.success && !endpoint.startsWith('/housing')) { - throw new Error(Errors.SOMETHING_WENT_WRONG.replace(/{cause}/, res.cause)); - } - // eslint-disable-next-line no-underscore-dangle - parsedRes._headers = res.headers; - parsedRes.raw = Boolean(options.raw); - if (options.noCaching) return parsedRes; - // split by question mark : first part is /path, remove / - if (this.client.options.cache && this.client.options.cacheFilter(endpoint.split('?')[0].slice(1))) { - if (this.client.options.cacheSize < (await this.cached.size())) { - await this.cached.delete(Array.from(await this.cached.keys())[0]); - } - await this.cached.delete(endpoint); - await this.cached.set(endpoint, parsedRes); - if (0 <= this.client.options.hypixelCacheTime) { - setTimeout(() => this.cached.delete(endpoint), 1000 * this.client.options.hypixelCacheTime); - } - } - return parsedRes; - } - - get cache() { - return this.cached; - } - - async sweepCache(amount) { - if (!amount || amount >= (await this.cached.size())) return await this.cached.clear(); - return await Promise.all( - Array.from(await this.cached.keys()) - .slice((await this.cached.size()) - amount) - .map((x) => this.cached.delete(x)) - ); - } - - validateCustomCache(cache) { - return Boolean(cache.set && cache.get && cache.delete && cache.keys); - } -} - -module.exports = Requests; diff --git a/src/Private/updater.js b/src/Private/updater.js deleted file mode 100644 index ff5768bd7..000000000 --- a/src/Private/updater.js +++ /dev/null @@ -1,34 +0,0 @@ -/* eslint-disable no-console */ -const requireFetch = !globalThis.fetch; -const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -const fetch = requireFetch ? externalFetch : globalThis.fetch; -const Errors = require('../Errors'); -class Updater { - async checkForUpdates() { - const version = require('../../package.json').version; - const request = await fetch('https://registry.npmjs.org/hypixel-api-reborn'); - if (!request.ok) return console.log(Errors.UPDATER_REQUEST_NOT_OK); - const metadata = await request.json(); - const latest = metadata['dist-tags'].latest; - const compare = this.compare(version, latest); - if (-1 === compare) { - console.log( - `New version of hypixel-api-reborn is available! Current version: ${version}, Latest version: ${latest}` - ); - } - } - compare(a, b) { - const pa = a.split('.'); - const pb = b.split('.'); - for (let i = 0; 3 > i; i++) { - const na = Number(pa[i]); - const nb = Number(pb[i]); - if (na > nb) return 1; - if (nb > na) return -1; - if (!isNaN(na) && isNaN(nb)) return 1; - if (isNaN(na) && !isNaN(nb)) return -1; - } - return 0; - } -} -module.exports = Updater; diff --git a/src/Private/uuidCache.js b/src/Private/uuidCache.js deleted file mode 100644 index 2a59bae9b..000000000 --- a/src/Private/uuidCache.js +++ /dev/null @@ -1,30 +0,0 @@ -const requireFetch = !globalThis.fetch; -const externalFetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)); -const fetch = requireFetch ? externalFetch : globalThis.fetch; -const NodeCache = require('node-cache'); -const cache = new NodeCache(); - -// TODO - use this for all cache models - -module.exports = async (url, query, cacheTime) => { - if (cache.has(query.toLowerCase())) return cache.get(query.toLowerCase()); - const res = await fetch(url); - const data = await res.json(); - // Don't cache 4xx - if (400 <= res.status) { - return { - status: res.status, - id: null, - name: null - }; - } - - cache.set(query.toLowerCase(), { status: res.status, id: data.id, name: data.name }, cacheTime); - cache.set(data.id.toLowerCase(), { status: res.status, id: data.id, name: data.name }, cacheTime); - - return { - status: res.status, - id: data.id, - name: data.name - }; -}; diff --git a/src/Private/validate.js b/src/Private/validate.js deleted file mode 100644 index 72b61b42a..000000000 --- a/src/Private/validate.js +++ /dev/null @@ -1,108 +0,0 @@ -const Errors = require('../Errors'); -const { isStrArray, strToArray } = require('../utils/arrayTools'); -/** - * Validation Class, used internally to validate provided arguments - */ -class Validation { - /** - * Check if cache options are valid - * @param {Object} options Global Cache Options to be validated - * @returns {void} Void - * @private - */ - validateOptions(options) { - if ('number' !== typeof options.hypixelCacheTime) throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER); - if ('number' !== typeof options.mojangCacheTime) throw new Error(Errors.CACHE_TIME_MUST_BE_A_NUMBER); - if ('number' !== typeof options.cacheSize) throw new Error(Errors.CACHE_LIMIT_MUST_BE_A_NUMBER); - if ('string' !== typeof options.rateLimit || !['AUTO', 'HARD', 'NONE'].includes(options.rateLimit)) { - throw new Error(Errors.INVALID_RATE_LIMIT_OPTION); - } - if ('number' !== typeof options.keyLimit) throw new Error(Errors.INVALID_KEY_LIMIT_OPTION); - if ('boolean' !== typeof options.syncWithHeaders) throw new Error(Errors.INVALID_HEADER_SYNC_OPTION); - if ('object' !== typeof options.headers) throw new Error(Errors.INVALID_HEADERS); - if ('boolean' !== typeof options.silent) throw new Error(Errors.INVALID_SILENT_OPTION); - if ('boolean' !== typeof options.checkForUpdates) throw new Error(Errors.INVALID_UPDATE_OPTION); - if (!['boolean', 'string'].includes(typeof options.useThirdPartyAPI)) { - throw new Error(Errors.INVALID_THIRD_PARTY_API_OPTION); - } - } - - /** - * Parses cache options - * @param {Object} options Options to be parsed - * @returns {Object} Parsed cache options - * @private - */ - parseOptions(options) { - if ('object' !== typeof options || null === options) throw new Error(Errors.OPTIONS_MUST_BE_AN_OBJECT); - return { - cache: options.cache ?? true, - hypixelCacheTime: options.hypixelCacheTime ?? 60, - mojangCacheTime: options.mojangCacheTime ?? 600, - cacheSize: (-1 === options.cacheSize ? Infinity : options.cacheSize) || Infinity, - cacheFilter: - // eslint-disable-next-line no-underscore-dangle - 'function' === typeof options.cacheFilter ? options.cacheFilter : this._handleFilter(options.cacheFilter), - rateLimit: options.rateLimit ?? 'AUTO', - keyLimit: options.keyLimit ?? 60, - syncWithHeaders: Boolean(options.syncWithHeaders), - headers: options.headers ?? {}, - silent: Boolean(options.silent), - checkForUpdates: options.checkForUpdates ?? true, - useThirdPartyAPI: options.useThirdPartyAPI ?? false - }; - } - - /** - * Checks if Key is provided in a correct format - * @param {string} key API Key - * @returns {string} Key - * @private - */ - validateKey(key) { - if (!key) throw new Error(Errors.NO_API_KEY); - if ('string' !== typeof key) throw new Error(Errors.KEY_MUST_BE_A_STRING); - return key; - } - - /** - * Check if suboptions are valid - * @param {Object} input Cache options - * @returns {boolean} Whether options are valid - * @private - */ - cacheSuboptions(input) { - if ('object' !== typeof input || null === input) return false; - if (!input.noCacheCheck && !input.noCaching && !input.raw) return false; - return true; - } - - /** - * Handles & parses the filter - * @param {*} filter FilterResolvable to be parsed - * @returns {Function} Filter function - * @private - */ - _handleFilter(filter) { - if (!filter) return () => true; - if ('object' === typeof filter && !Array.isArray(filter)) { - if (filter.whitelist && isStrArray(filter.whitelist)) return (x) => strToArray(filter.whitelist).includes(x); - if (filter.blacklist && isStrArray(filter.blacklist)) return (x) => !strToArray(filter.blacklist).includes(x); - throw new Error(Errors.CACHE_FILTER_INVALID); - } - if (!isStrArray(filter)) throw new Error(Errors.CACHE_FILTER_INVALID); - // blacklist by default - return (x) => !strToArray(filter).includes(x); - } - /** - * Checks user's node version - * -12 will return an error; -14 will result in a warning - * @returns {void} - * @private - */ - validateNodeVersion() { - const nodeVersion = parseInt(process.version.match(/v(\d{2})\.\d{1,}\.\d+/)[1], 10); - if (12 > nodeVersion) throw new Error(Errors.NODE_VERSION_ERR); - } -} -module.exports = Validation; diff --git a/src/Structures/Boosters/Booster.test.ts b/src/Structures/Boosters/Booster.test.ts new file mode 100644 index 000000000..508929548 --- /dev/null +++ b/src/Structures/Boosters/Booster.test.ts @@ -0,0 +1,65 @@ +import Booster from './Booster.js'; +import Game from '../Game.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BoosterType } from '../../Types/Booster.js'; + +test('Booster', () => { + const data = new Booster({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Booster); + expectTypeOf(data).toEqualTypeOf(); + expect(data.purchaser).toBeDefined(); + expectTypeOf(data.purchaser).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.originalLength).toBeDefined(); + expect(data.originalLength).toBeGreaterThanOrEqual(0); + expectTypeOf(data.originalLength).toEqualTypeOf(); + expect(data.remaining).toBeDefined(); + expect(data.remaining).toBeGreaterThanOrEqual(0); + expectTypeOf(data.remaining).toEqualTypeOf(); + expect(data.activatedTimestamp).toBeDefined(); + expect(data.activatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.activatedTimestamp).toEqualTypeOf(); + expect(data.activated).toBeDefined(); + expect(data.activated).toBeInstanceOf(Date); + expectTypeOf(data.activated).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expect(data.game).toBeInstanceOf(Game); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.isActive).toBeDefined(); + expectTypeOf(data.isActive).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.stackers).toBeDefined(); + expectTypeOf(data.stackers).toEqualTypeOf(); + expect(data.expired).toBeDefined(); + expectTypeOf(data.expired).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(`${data.purchaser}'s booster in ${data.game}`); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); + +test('Booster parseType (STACKED)', () => { + const type = Booster.parseType({ stacked: true }); + expect(type).toBeDefined(); + expectTypeOf(type).toEqualTypeOf(); + expect(type).toBe('STACKED'); +}); + +test('Booster parseType (QUEUED)', () => { + const type = Booster.parseType({ stacked: false }); + expect(type).toBeDefined(); + expectTypeOf(type).toEqualTypeOf(); + expect(type).toBe('QUEUED'); +}); + +test('Booster parseType (ACTIVE)', () => { + const type = Booster.parseType({}); + expect(type).toBeDefined(); + expectTypeOf(type).toEqualTypeOf(); + expect(type).toBe('ACTIVE'); +}); diff --git a/src/Structures/Boosters/Booster.ts b/src/Structures/Boosters/Booster.ts new file mode 100644 index 000000000..d5d5bbfb6 --- /dev/null +++ b/src/Structures/Boosters/Booster.ts @@ -0,0 +1,46 @@ +import Game from '../Game.js'; +import type RequestData from '../../Private/RequestData.js'; +import type { BoosterType } from '../../Types/Booster.js'; + +class Booster { + purchaser: string; + amount: number; + originalLength: number; + remaining: number; + activatedTimestamp: number; + activated: Date; + game: Game; + isActive: boolean; + type: BoosterType; + stackers: string[]; + expired: boolean; + constructor(data: Record) { + this.purchaser = data.purchaserUuid || 'UNKNOWN'; + this.amount = data.amount || 0; + this.originalLength = data.originalLength || 0; + this.remaining = data.length || 0; + this.activatedTimestamp = data.dateActivated || 0; + this.activated = new Date(data.dateActivated); + this.game = new Game(data.gameType); + this.isActive = Array.isArray(data.stacked); + this.type = Booster.parseType(data); + this.stackers = Array.isArray(data.stacked) ? Array.from(data.stacked) : []; + this.expired = data.length < 0; + } + + toString(): string { + return `${this.purchaser}'s booster in ${this.game}`; + } + + isRaw(): this is RequestData { + return false; + } + + static parseType(data: Record): BoosterType { + if (data.stacked === true) return 'STACKED'; + if (data.stacked === false) return 'QUEUED'; + return 'ACTIVE'; + } +} + +export default Booster; diff --git a/src/Structures/Color.test.ts b/src/Structures/Color.test.ts new file mode 100644 index 000000000..5718be5f0 --- /dev/null +++ b/src/Structures/Color.test.ts @@ -0,0 +1,29 @@ +import Color from './Color.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorCode, ColorHex, ColorString, InGameCode } from '../Types/Color.js'; + +test('Color', () => { + const data = new Color('BLACK'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Color); + expectTypeOf(data).toEqualTypeOf(); + expect(data.color).toBeDefined(); + expectTypeOf(data.color).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => ColorString>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe('Black'); + expectTypeOf(data.toString()).toEqualTypeOf(); + expect(data.toHex).toBeDefined(); + expectTypeOf(data.toHex).toEqualTypeOf<() => ColorHex>(); + expect(data.toHex()).toBeDefined(); + expectTypeOf(data.toHex()).toEqualTypeOf(); + expect(data.toCode).toBeDefined(); + expectTypeOf(data.toCode).toEqualTypeOf<() => ColorCode>(); + expect(data.toCode()).toBeDefined(); + expectTypeOf(data.toCode()).toEqualTypeOf(); + expect(data.toInGameCode).toBeDefined(); + expectTypeOf(data.toInGameCode).toEqualTypeOf<() => InGameCode>(); + expect(data.toInGameCode()).toBeDefined(); + expectTypeOf(data.toInGameCode()).toEqualTypeOf(); +}); diff --git a/src/Structures/Color.ts b/src/Structures/Color.ts new file mode 100644 index 000000000..b54b79cfc --- /dev/null +++ b/src/Structures/Color.ts @@ -0,0 +1,83 @@ +import type { ColorCode, ColorHex, ColorString, InGameCode } from '../Types/Color.js'; + +const ColorStrings: { [key: string]: ColorString } = { + BLACK: 'Black', + DARK_BLUE: 'Dark Blue', + DARK_GREEN: 'Dark Green', + DARK_AQUA: 'Dark Aqua', + DARK_RED: 'Dark Red', + DARK_PURPLE: 'Dark Purple', + GOLD: 'Gold', + GRAY: 'Gray', + DARK_GRAY: 'Dark Gray', + BLUE: 'Blue', + GREEN: 'Green', + AQUA: 'Aqua', + RED: 'Red', + LIGHT_PURPLE: 'Light Purple', + YELLOW: 'Yellow', + WHITE: 'White' +}; + +const ColorHexs: { [key: string]: ColorHex } = { + BLACK: '#000000', + DARK_BLUE: '#0000AA', + DARK_GREEN: '#008000', + DARK_AQUA: '#00AAAA', + DARK_RED: '#AA0000', + DARK_PURPLE: '#AA00AA', + GOLD: '#FFAA00', + GRAY: '#AAAAAA', + DARK_GRAY: '#555555', + BLUE: '#5555FF', + GREEN: '#3CE63C', + AQUA: '#3CE6E6', + RED: '#FF5555', + LIGHT_PURPLE: '#FF55FF', + YELLOW: '#FFFF55', + WHITE: '#FFFFFF' +}; + +const InGameCodes: { [key: string]: InGameCode } = { + BLACK: '§0', + DARK_BLUE: '§1', + DARK_GREEN: '§2', + DARK_AQUA: '§3', + DARK_RED: '§4', + DARK_PURPLE: '§5', + GOLD: '§6', + GRAY: '§7', + DARK_GRAY: '§8', + BLUE: '§9', + GREEN: '§a', + AQUA: '§b', + RED: '§c', + LIGHT_PURPLE: '§d', + YELLOW: '§e', + WHITE: '§f' +}; + +class Color { + color: ColorCode; + constructor(color: ColorCode) { + this.color = color; + } + + toString(): ColorString { + return ColorStrings[this.color] as ColorString; + } + + toHex(): ColorHex { + return ColorHexs[this.color] as ColorHex; + } + + toCode(): ColorCode { + return this.color; + } + + toInGameCode(): InGameCode { + return InGameCodes[this.color] as InGameCode; + } +} + +export default Color; diff --git a/src/Structures/Game.test.ts b/src/Structures/Game.test.ts new file mode 100644 index 000000000..61fad2590 --- /dev/null +++ b/src/Structures/Game.test.ts @@ -0,0 +1,25 @@ +import Game from './Game.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; + +test('Game', () => { + const data = new Game('ARCADE'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Game); + expectTypeOf(data).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.code).toBeDefined(); + expectTypeOf(data.code).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.found).toBeDefined(); + expectTypeOf(data.found).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => GameString | null>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Game.ts b/src/Structures/Game.ts new file mode 100644 index 000000000..f5938d0ac --- /dev/null +++ b/src/Structures/Game.ts @@ -0,0 +1,42 @@ +import { games } from '../Utils/Constants.js'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; + +class Game { + game: GameID | GameCode; + id: GameID | null; + code: GameCode | null; + name: GameString | null; + found: boolean; + constructor(game: GameID | GameCode) { + this.game = game; + const result = + games.find( + (Game) => + Game.code.toLowerCase() === this.game || + Game.id.toString() === this.game || + Game.name.toLowerCase() === this.game + ) || null; + this.id = result?.id || null; + this.code = result?.code || null; + this.name = result?.name || null; + this.found = result !== null; + } + + toString(): GameString | null { + return this.name; + } + + static get IDS(): GameID[] { + return games.map((x) => x.id as GameID); + } + + static get CODES(): GameCode[] { + return games.map((x) => x.code) as GameCode[]; + } + + static get NAMES(): GameString[] { + return games.map((x) => x.name) as GameString[]; + } +} + +export default Game; diff --git a/src/Structures/Guild/Guild.test.ts b/src/Structures/Guild/Guild.test.ts new file mode 100644 index 000000000..d1ec45665 --- /dev/null +++ b/src/Structures/Guild/Guild.test.ts @@ -0,0 +1,64 @@ +import Color from '../Color.js'; +import Game from '../Game.js'; +import Guild from './Guild.js'; +import GuildMember from './GuildMember.js'; +import GuildRank from './GuildRank.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ExpHistory } from '../../Types/Guild.js'; + +test('Guild', () => { + const data = new Guild({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Guild); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.ranks).toBeDefined(); + expectTypeOf(data.ranks).toEqualTypeOf(); + expect(data.totalWeeklyGEXP).toBeDefined(); + expect(data.totalWeeklyGEXP).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalWeeklyGEXP).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.joinable).toBeDefined(); + expectTypeOf(data.joinable).toEqualTypeOf(); + expect(data.publiclyListed).toBeDefined(); + expectTypeOf(data.publiclyListed).toEqualTypeOf(); + expect(data.chatMuteUntilTimestamp).toBeDefined(); + expectTypeOf(data.chatMuteUntilTimestamp).toEqualTypeOf(); + expect(data.chatMuteUntil).toBeDefined(); + expectTypeOf(data.chatMuteUntil).toEqualTypeOf(); + expect(data.banner).toBeDefined(); + expectTypeOf(data.banner).toEqualTypeOf<{ Pattern: string; Color: string }[]>(); + expect(data.tag).toBeDefined(); + expectTypeOf(data.tag).toEqualTypeOf(); + expect(data.tagColor).toBeDefined(); + expectTypeOf(data.tagColor).toEqualTypeOf(); + expect(data.expHistory).toBeDefined(); + expectTypeOf(data.expHistory).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expectTypeOf(data.achievements).toEqualTypeOf<{ winners: number; experienceKings: number; onlinePlayers: number }>(); + expect(data.preferredGames).toBeDefined(); + expectTypeOf(data.preferredGames).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Guild/Guild.ts b/src/Structures/Guild/Guild.ts new file mode 100644 index 000000000..100269f53 --- /dev/null +++ b/src/Structures/Guild/Guild.ts @@ -0,0 +1,69 @@ +import Color from '../Color.js'; +import Game from '../Game.js'; +import GuildMember from './GuildMember.js'; +import GuildRank from './GuildRank.js'; +import { calculateExpHistory, getGuildLevel, members, ranks, totalWeeklyGEXP } from '../../Utils/Guild.js'; +import type RequestData from '../../Private/RequestData.js'; +import type { ExpHistory } from '../../Types/Guild.js'; + +class Guild { + id: string; + name: string; + description: string; + experience: number; + level: number; + members: GuildMember[]; + me: GuildMember | null; + ranks: GuildRank[]; + totalWeeklyGEXP: number; + createdAtTimestamp: number | null; + createdAt: Date | null; + joinable: boolean; + publiclyListed: boolean; + chatMuteUntilTimestamp: number | null; + chatMuteUntil: Date | null; + banner: { Pattern: string; Color: string }[]; + tag: string; + tagColor: Color | null; + expHistory: ExpHistory[]; + achievements: { winners: number; experienceKings: number; onlinePlayers: number }; + preferredGames: Game[]; + constructor(data: Record, uuid?: string) { + // eslint-disable-next-line no-underscore-dangle + this.id = data._id || 'UNKNOWN'; + this.name = data.name || 'UNKNOWN'; + this.description = data.description ?? ''; + this.experience = data.exp || 0; + this.level = getGuildLevel(this.experience); + this.members = members(data?.members || []); + this.me = uuid ? (this.members.find((member) => member.uuid === uuid) as GuildMember) : null; + this.ranks = ranks(data); + this.totalWeeklyGEXP = totalWeeklyGEXP(this.members); + this.createdAtTimestamp = data.created || null; + this.createdAt = this.createdAtTimestamp ? new Date(this.createdAtTimestamp) : null; + this.joinable = data.joinable ?? false; + this.publiclyListed = Boolean(data.publiclyListed); + this.chatMuteUntilTimestamp = data.chatMute ?? null; + this.chatMuteUntil = this.chatMuteUntilTimestamp ? new Date(this.chatMuteUntilTimestamp) : null; + this.banner = data.banner ?? null; + this.tag = data.tag ?? null; + this.tagColor = data.tagColor ? new Color(data.tagColor) : null; + this.expHistory = calculateExpHistory(this.members); + this.achievements = { + winners: data?.achievements?.WINNERS || 0, + experienceKings: data?.achievements?.EXPERIENCE_KINGS || 0, + onlinePlayers: data?.achievements?.ONLINE_PLAYERS || 0 + }; + this.preferredGames = data.preferredGames ? data.preferredGames.map((g: any) => new Game(g)) : []; + } + + toString(): string { + return this.name; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Guild; diff --git a/src/Structures/Guild/GuildMember.test.ts b/src/Structures/Guild/GuildMember.test.ts new file mode 100644 index 000000000..ce9717194 --- /dev/null +++ b/src/Structures/Guild/GuildMember.test.ts @@ -0,0 +1,36 @@ +import GuildMember from './GuildMember.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ExpHistory } from '../../Types/Guild.js'; +import type { UUID } from '../../Types/Global.js'; + +test('GuildMember', () => { + const data = new GuildMember({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GuildMember); + expectTypeOf(data).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.joinedAtTimestamp).toBeDefined(); + expectTypeOf(data.joinedAtTimestamp).toEqualTypeOf(); + expect(data.joinedAt).toBeDefined(); + expectTypeOf(data.joinedAt).toEqualTypeOf(); + expect(data.questParticipation).toBeDefined(); + expect(data.questParticipation).toBeGreaterThanOrEqual(0); + expectTypeOf(data.questParticipation).toEqualTypeOf(); + expect(data.rank).toBeDefined(); + expectTypeOf(data.rank).toEqualTypeOf(); + expect(data.mutedUntilTimestamp).toBeDefined(); + expectTypeOf(data.mutedUntilTimestamp).toEqualTypeOf(); + expect(data.mutedUntil).toBeDefined(); + expectTypeOf(data.mutedUntil).toEqualTypeOf(); + expect(data.expHistory).toBeDefined(); + expectTypeOf(data.expHistory).toEqualTypeOf(); + expect(data.weeklyExperience).toBeDefined(); + expect(data.weeklyExperience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyExperience).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.uuid); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Guild/GuildMember.ts b/src/Structures/Guild/GuildMember.ts new file mode 100644 index 000000000..e0529b697 --- /dev/null +++ b/src/Structures/Guild/GuildMember.ts @@ -0,0 +1,35 @@ +import { parseHistory } from '../../Utils/Guild.js'; +import type { ExpHistory } from '../../Types/Guild.js'; +import type { UUID } from '../../Types/Global.js'; + +class GuildMember { + uuid: UUID; + joinedAtTimestamp: number | null; + joinedAt: Date | null; + questParticipation: number; + rank: string; + mutedUntilTimestamp: number | null; + mutedUntil: Date | null; + expHistory: ExpHistory[]; + weeklyExperience: number; + constructor(data: Record) { + this.uuid = data.uuid || ''; + this.joinedAtTimestamp = data?.joined || null; + this.joinedAt = this.joinedAtTimestamp ? new Date(this.joinedAtTimestamp) : null; + this.questParticipation = data?.questParticipation || 0; + this.rank = data?.rank || 'Member'; + this.mutedUntilTimestamp = data?.mutedTill || null; + this.mutedUntil = this.mutedUntilTimestamp ? new Date(this.mutedUntilTimestamp) : null; + const xpCheck = data.expHistory && typeof Object.values(data.expHistory)[0] === 'number'; + this.expHistory = parseHistory(data?.expHistory || {}); + this.weeklyExperience = xpCheck + ? Number(Object.values(data.expHistory).reduce((pV: any, cV: any) => pV + cV, 0)) + : 0; + } + + toString(): string { + return this.uuid; + } +} + +export default GuildMember; diff --git a/src/Structures/Guild/GuildRank.test.ts b/src/Structures/Guild/GuildRank.test.ts new file mode 100644 index 000000000..0237ed563 --- /dev/null +++ b/src/Structures/Guild/GuildRank.test.ts @@ -0,0 +1,27 @@ +import GuildRank from './GuildRank.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GuildRank', () => { + const data = new GuildRank({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GuildRank); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.tag).toBeDefined(); + expectTypeOf(data.tag).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.priority).toBeDefined(); + expect(data.priority).toBeGreaterThanOrEqual(0); + expectTypeOf(data.priority).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Guild/GuildRank.ts b/src/Structures/Guild/GuildRank.ts new file mode 100644 index 000000000..214ed9ae6 --- /dev/null +++ b/src/Structures/Guild/GuildRank.ts @@ -0,0 +1,22 @@ +class GuildRank { + name: string; + default: boolean; + tag: string | null; + createdAtTimestamp: number | null; + createdAt: Date | null; + priority: number; + constructor(data: Record) { + this.name = data.name || ''; + this.default = data.default || false; + this.tag = data.tag || null; + this.createdAtTimestamp = data.created || data.createdAtTimestamp || null; + this.createdAt = this.createdAtTimestamp ? new Date(this.createdAtTimestamp) : null; + this.priority = data?.priority || 0; + } + + toString(): string { + return this.name; + } +} + +export default GuildRank; diff --git a/src/Structures/House.test.ts b/src/Structures/House.test.ts new file mode 100644 index 000000000..1b7d2783e --- /dev/null +++ b/src/Structures/House.test.ts @@ -0,0 +1,31 @@ +import House from './House.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UUID } from '../Types/Global.js'; + +test('House', () => { + const data = new House({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(House); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.owner).toBeDefined(); + expectTypeOf(data.owner).toEqualTypeOf(); + expect(data.createdAtTimestamp).toBeDefined(); + expectTypeOf(data.createdAtTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.players).toBeDefined(); + expect(data.players).toBeGreaterThanOrEqual(0); + expectTypeOf(data.players).toEqualTypeOf(); + expect(data.cookies).toBeDefined(); + expect(data.cookies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cookies).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/House.ts b/src/Structures/House.ts new file mode 100644 index 000000000..f443afdb8 --- /dev/null +++ b/src/Structures/House.ts @@ -0,0 +1,31 @@ +import type RequestData from '../Private/RequestData.js'; +import type { UUID } from '../Types/Global.js'; + +class House { + name: string; + uuid: UUID; + owner: string; + createdAtTimestamp: number | null; + createdAt: Date | null; + players: number; + cookies: number; + constructor(data: Record) { + this.name = data.name || ''; + this.uuid = data.uuid || ''; + this.owner = data.owner || ''; + this.createdAtTimestamp = data.createdAt || null; + this.createdAt = this.createdAtTimestamp ? new Date(this.createdAtTimestamp) : null; + this.players = data.players || 0; + this.cookies = data.cookies?.current || 0; + } + + toString(): string { + return this.name; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default House; diff --git a/src/Structures/ItemBytes.test.ts b/src/Structures/ItemBytes.test.ts new file mode 100644 index 000000000..9fc484e78 --- /dev/null +++ b/src/Structures/ItemBytes.test.ts @@ -0,0 +1,12 @@ +import ItemBytes from './ItemBytes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ItemBytes', () => { + const data = new ItemBytes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ItemBytes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bytesBuffer).toBeDefined(); + expect(data.bytesBuffer).toBeInstanceOf(Buffer); + expectTypeOf(data.bytesBuffer).toEqualTypeOf(); +}); diff --git a/src/Structures/ItemBytes.ts b/src/Structures/ItemBytes.ts new file mode 100644 index 000000000..8076a3bad --- /dev/null +++ b/src/Structures/ItemBytes.ts @@ -0,0 +1,12 @@ +class ItemBytes { + bytesBuffer: Buffer; + constructor(data: Record) { + this.bytesBuffer = Buffer.from(JSON.stringify(data), 'base64'); + } + + base64(): string { + return this.bytesBuffer.toString('base64'); + } +} + +export default ItemBytes; diff --git a/src/Structures/Leaderboard.test.ts b/src/Structures/Leaderboard.test.ts new file mode 100644 index 000000000..4fbb2d42b --- /dev/null +++ b/src/Structures/Leaderboard.test.ts @@ -0,0 +1,22 @@ +import Leaderboard from './Leaderboard.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Leaderboard', () => { + const data = new Leaderboard({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Leaderboard); + expectTypeOf(data).toEqualTypeOf(); + expect(data.path).toBeDefined(); + expectTypeOf(data.path).toEqualTypeOf(); + expect(data.prefix).toBeDefined(); + expectTypeOf(data.prefix).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.location).toBeDefined(); + expectTypeOf(data.location).toEqualTypeOf(); + expect(data.count).toBeDefined(); + expect(data.count).toBeGreaterThanOrEqual(0); + expectTypeOf(data.count).toEqualTypeOf(); + expect(data.leaders).toBeDefined(); + expectTypeOf(data.leaders).toEqualTypeOf(); +}); diff --git a/src/Structures/Leaderboard.ts b/src/Structures/Leaderboard.ts new file mode 100644 index 000000000..5780035b6 --- /dev/null +++ b/src/Structures/Leaderboard.ts @@ -0,0 +1,18 @@ +class Leaderboard { + path: string; + prefix: string; + title: string; + location: string; + count: number; + leaders: string[]; + constructor(data: Record) { + this.path = data?.path || ''; + this.prefix = data?.prefix || ''; + this.title = data?.title || ''; + this.location = data?.location || '0,0,0'; + this.count = data?.count || 0; + this.leaders = data?.leaders || []; + } +} + +export default Leaderboard; diff --git a/src/Structures/MiniGames/Arcade/Arcade.test.ts b/src/Structures/MiniGames/Arcade/Arcade.test.ts new file mode 100644 index 000000000..22557f441 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Arcade.test.ts @@ -0,0 +1,210 @@ +import Arcade from './Arcade.js'; +import ArcadeOptions from './ArcadeOptions.js'; +import BlockingDead from './BlockingDead.js'; +import DragonWars from './DragonWars.js'; +import DrawTheirThing from './DrawTheirThing.js'; +import Dropper from './Dropper/Dropper.js'; +import Dtt from './Dtt.js'; +import EasterSimulator from './EasterSimulator.js'; +import EnderSpleef from './EnderSpleef.js'; +import FarmHunt from './FarmHunt.js'; +import FootBall from './FootBall.js'; +import GalaxyWars from './GalaxyWars.js'; +import GrinchSimulator from './GrinchSimulator.js'; +import HalloweenSimulator from './HalloweenSimulator.js'; +import HideAndSeek from './HideAndSeek.js'; +import HoleInTheWall from './HoleInTheWall.js'; +import HypixelSports from './HypixelSports.js'; +import MiniWalls from './MiniWalls.js'; +import OneInTheQuiver from './OneInTheQuiver.js'; +import PartyGames from './PartyGames/PartyGames.js'; +import SantaSays from './SantaSays.js'; +import SantaSimulator from './SantaSimulator.js'; +import ScubaSimulator from './ScubaSimulator.js'; +import SimonSays from './SimonSays.js'; +import Soccer from './Soccer.js'; +import ThrowOut from './ThrowOut.js'; +import WoolHunt from './WoolHunt.js'; +import Zombies from './Zombies/Zombies.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + ArcadeBountyHead, + ArcadeMeleeWeapon, + ArcadeMovementTrail, + ArcadePackage, + ArcadeProjectileTrail, + ArcadeVictoryDance, + Language, + PlayerGeneralSelectedCosmetic, + ShopSort +} from '../../../Types/Player.js'; + +test('Arcade', () => { + const data = new Arcade({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Arcade); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeMovementTrail).toBeDefined(); + expectTypeOf(data.activeMovementTrail).toEqualTypeOf< + ArcadeMovementTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.activeProjectileTrail).toBeDefined(); + expectTypeOf(data.activeProjectileTrail).toEqualTypeOf< + ArcadeProjectileTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.activeVictoryDance).toBeDefined(); + expectTypeOf(data.activeVictoryDance).toEqualTypeOf(); + expect(data.blood).toBeDefined(); + expectTypeOf(data.blood).toEqualTypeOf(); + expect(data.bountyHead).toBeDefined(); + expectTypeOf(data.bountyHead).toEqualTypeOf(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.dec2016Achievements).toBeDefined(); + expectTypeOf(data.dec2016Achievements).toEqualTypeOf(); + expect(data.dec2016Achievements2).toBeDefined(); + expectTypeOf(data.dec2016Achievements2).toEqualTypeOf(); + expect(data.flash).toBeDefined(); + expectTypeOf(data.flash).toEqualTypeOf(); + expect(data.hideAndSeekShowQueueBook).toBeDefined(); + expectTypeOf(data.hideAndSeekShowQueueBook).toEqualTypeOf(); + expect(data.hints).toBeDefined(); + expectTypeOf(data.hints).toEqualTypeOf(); + expect(data.language).toBeDefined(); + expectTypeOf(data.language).toEqualTypeOf(); + expect(data.maxWave).toBeDefined(); + expect(data.maxWave).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxWave).toEqualTypeOf(); + expect(data.meleeWeapon).toBeDefined(); + expectTypeOf(data.meleeWeapon).toEqualTypeOf(); + expect(data.monthlyTokens).toBeDefined(); + expect(data.monthlyTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokens).toEqualTypeOf(); + expect(data.monthlyTokensA).toBeDefined(); + expect(data.monthlyTokensA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokensA).toEqualTypeOf(); + expect(data.monthlyTokensB).toBeDefined(); + expect(data.monthlyTokensB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokensB).toEqualTypeOf(); + expect(data.music).toBeDefined(); + expectTypeOf(data.music).toEqualTypeOf(); + expect(data.mysteryGiftsObtained).toBeDefined(); + expect(data.mysteryGiftsObtained).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mysteryGiftsObtained).toEqualTypeOf(); + expect(data.options).toBeDefined(); + expect(data.options).toBeInstanceOf(ArcadeOptions); + expectTypeOf(data.options).toEqualTypeOf(); + expect(data.poopCollected).toBeDefined(); + expect(data.poopCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.poopCollected).toEqualTypeOf(); + expect(data.ppLanguage).toBeDefined(); + expectTypeOf(data.ppLanguage).toEqualTypeOf(); + expect(data.privategames).toBeDefined(); + expectTypeOf(data.privategames).toEqualTypeOf>(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.shopSortEnableOwnedFirst).toBeDefined(); + expectTypeOf(data.shopSortEnableOwnedFirst).toEqualTypeOf(); + expect(data.showInfoBook).toBeDefined(); + expectTypeOf(data.showInfoBook).toEqualTypeOf(); + expect(data.simonSong).toBeDefined(); + expectTypeOf(data.simonSong).toEqualTypeOf(); + expect(data.stampLevel).toBeDefined(); + expect(data.stampLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stampLevel).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expect(data.timestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.weeklyTokens).toBeDefined(); + expect(data.weeklyTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyTokens).toEqualTypeOf(); + expect(data.weeklyTokensA).toBeDefined(); + expect(data.weeklyTokensA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyTokensA).toEqualTypeOf(); + expect(data.weeklyTokensB).toBeDefined(); + expect(data.weeklyTokensB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyTokensB).toEqualTypeOf(); + expect(data.xmasMusic).toBeDefined(); + expectTypeOf(data.xmasMusic).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.blockingDead).toBeDefined(); + expect(data.blockingDead).toBeInstanceOf(BlockingDead); + expectTypeOf(data.blockingDead).toEqualTypeOf(); + expect(data.dragonWars).toBeDefined(); + expect(data.dragonWars).toBeInstanceOf(DragonWars); + expectTypeOf(data.dragonWars).toEqualTypeOf(); + expect(data.dropper).toBeDefined(); + expect(data.dropper).toBeInstanceOf(Dropper); + expectTypeOf(data.dropper).toEqualTypeOf(); + expect(data.drawTheirThing).toBeDefined(); + expect(data.drawTheirThing).toBeInstanceOf(DrawTheirThing); + expectTypeOf(data.drawTheirThing).toEqualTypeOf(); + expect(data.dtt).toBeDefined(); + expect(data.dtt).toBeInstanceOf(Dtt); + expectTypeOf(data.dtt).toEqualTypeOf(); + expect(data.easterSimulator).toBeDefined(); + expect(data.easterSimulator).toBeInstanceOf(EasterSimulator); + expectTypeOf(data.easterSimulator).toEqualTypeOf(); + expect(data.enderSpleef).toBeDefined(); + expect(data.enderSpleef).toBeInstanceOf(EnderSpleef); + expectTypeOf(data.enderSpleef).toEqualTypeOf(); + expect(data.farmHunt).toBeDefined(); + expect(data.farmHunt).toBeInstanceOf(FarmHunt); + expectTypeOf(data.farmHunt).toEqualTypeOf(); + expect(data.footBall).toBeDefined(); + expect(data.footBall).toBeInstanceOf(FootBall); + expectTypeOf(data.footBall).toEqualTypeOf(); + expect(data.galaxyWars).toBeDefined(); + expect(data.galaxyWars).toBeInstanceOf(GalaxyWars); + expectTypeOf(data.galaxyWars).toEqualTypeOf(); + expect(data.grinchSimulator).toBeDefined(); + expect(data.grinchSimulator).toBeInstanceOf(GrinchSimulator); + expectTypeOf(data.grinchSimulator).toEqualTypeOf(); + expect(data.halloweenSimulator).toBeDefined(); + expect(data.halloweenSimulator).toBeInstanceOf(HalloweenSimulator); + expectTypeOf(data.halloweenSimulator).toEqualTypeOf(); + expect(data.hideAndSeek).toBeDefined(); + expect(data.hideAndSeek).toBeInstanceOf(HideAndSeek); + expectTypeOf(data.hideAndSeek).toEqualTypeOf(); + expect(data.holeInTheWall).toBeDefined(); + expect(data.holeInTheWall).toBeInstanceOf(HoleInTheWall); + expectTypeOf(data.holeInTheWall).toEqualTypeOf(); + expect(data.hypixelSports).toBeDefined(); + expect(data.hypixelSports).toBeInstanceOf(HypixelSports); + expectTypeOf(data.hypixelSports).toEqualTypeOf(); + expect(data.MiniWalls).toBeDefined(); + expect(data.MiniWalls).toBeInstanceOf(MiniWalls); + expectTypeOf(data.MiniWalls).toEqualTypeOf(); + expect(data.oneInTheQuiver).toBeDefined(); + expect(data.oneInTheQuiver).toBeInstanceOf(OneInTheQuiver); + expectTypeOf(data.oneInTheQuiver).toEqualTypeOf(); + expect(data.partyGames).toBeDefined(); + expect(data.partyGames).toBeInstanceOf(PartyGames); + expectTypeOf(data.partyGames).toEqualTypeOf(); + expect(data.santaSays).toBeDefined(); + expect(data.santaSays).toBeInstanceOf(SantaSays); + expectTypeOf(data.santaSays).toEqualTypeOf(); + expect(data.santaSimulator).toBeDefined(); + expect(data.santaSimulator).toBeInstanceOf(SantaSimulator); + expectTypeOf(data.santaSimulator).toEqualTypeOf(); + expect(data.scubaSimulator).toBeDefined(); + expect(data.scubaSimulator).toBeInstanceOf(ScubaSimulator); + expectTypeOf(data.scubaSimulator).toEqualTypeOf(); + expect(data.simonSays).toBeDefined(); + expect(data.simonSays).toBeInstanceOf(SimonSays); + expectTypeOf(data.simonSays).toEqualTypeOf(); + expect(data.soccer).toBeDefined(); + expect(data.soccer).toBeInstanceOf(Soccer); + expectTypeOf(data.soccer).toEqualTypeOf(); + expect(data.throwOut).toBeDefined(); + expect(data.throwOut).toBeInstanceOf(ThrowOut); + expectTypeOf(data.throwOut).toEqualTypeOf(); + expect(data.woolHunt).toBeDefined(); + expect(data.woolHunt).toBeInstanceOf(WoolHunt); + expectTypeOf(data.woolHunt).toEqualTypeOf(); + expect(data.zombies).toBeDefined(); + expect(data.zombies).toBeInstanceOf(Zombies); + expectTypeOf(data.zombies).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Arcade.ts b/src/Structures/MiniGames/Arcade/Arcade.ts new file mode 100644 index 000000000..05a833339 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Arcade.ts @@ -0,0 +1,169 @@ +import ArcadeOptions from './ArcadeOptions.js'; +import BlockingDead from './BlockingDead.js'; +import DragonWars from './DragonWars.js'; +import DrawTheirThing from './DrawTheirThing.js'; +import Dropper from './Dropper/Dropper.js'; +import Dtt from './Dtt.js'; +import EasterSimulator from './EasterSimulator.js'; +import EnderSpleef from './EnderSpleef.js'; +import FarmHunt from './FarmHunt.js'; +import FootBall from './FootBall.js'; +import GalaxyWars from './GalaxyWars.js'; +import GrinchSimulator from './GrinchSimulator.js'; +import HalloweenSimulator from './HalloweenSimulator.js'; +import HideAndSeek from './HideAndSeek.js'; +import HoleInTheWall from './HoleInTheWall.js'; +import HypixelSports from './HypixelSports.js'; +import MiniWalls from './MiniWalls.js'; +import OneInTheQuiver from './OneInTheQuiver.js'; +import PartyGames from './PartyGames/PartyGames.js'; +import SantaSays from './SantaSays.js'; +import SantaSimulator from './SantaSimulator.js'; +import ScubaSimulator from './ScubaSimulator.js'; +import SimonSays from './SimonSays.js'; +import Soccer from './Soccer.js'; +import ThrowOut from './ThrowOut.js'; +import WoolHunt from './WoolHunt.js'; +import Zombies from './Zombies/Zombies.js'; +import { monthAB, weekAB } from '../../../Utils/Oscillation.js'; +import type { + ArcadeBountyHead, + ArcadeMeleeWeapon, + ArcadeMovementTrail, + ArcadePackage, + ArcadeProjectileTrail, + ArcadeVictoryDance, + Language, + PlayerGeneralSelectedCosmetic, + ShopSort +} from '../../../Types/Player.js'; + +class Arcade { + activeMovementTrail: ArcadeMovementTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeProjectileTrail: ArcadeProjectileTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeVictoryDance: ArcadeVictoryDance | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + blood: boolean; + bountyHead: ArcadeBountyHead; + tokens: number; + dec2016Achievements: boolean; + dec2016Achievements2: boolean; + flash: boolean; + hideAndSeekShowQueueBook: boolean; + hints: boolean; + language: Language | 'UNKNOWN'; + maxWave: number; + meleeWeapon: ArcadeMeleeWeapon | 'UNKNOWN'; + monthlyTokens: number; + monthlyTokensA: number; + monthlyTokensB: number; + music: boolean; + mysteryGiftsObtained: number; + options: ArcadeOptions; + poopCollected: number; + ppLanguage: Language | 'UNKNOWN'; + privategames: Record; + shopSort: ShopSort | 'UNKNOWN'; + shopSortEnableOwnedFirst: boolean; + showInfoBook: boolean; + simonSong: boolean; + stampLevel: number; + timestamp: number; + weeklyTokens: number; + weeklyTokensA: number; + weeklyTokensB: number; + xmasMusic: boolean; + packages: ArcadePackage[]; + blockingDead: BlockingDead; + dragonWars: DragonWars; + dropper: Dropper; + drawTheirThing: DrawTheirThing; + dtt: Dtt; + easterSimulator: EasterSimulator; + enderSpleef: EnderSpleef; + farmHunt: FarmHunt; + footBall: FootBall; + galaxyWars: GalaxyWars; + grinchSimulator: GrinchSimulator; + halloweenSimulator: HalloweenSimulator; + hideAndSeek: HideAndSeek; + holeInTheWall: HoleInTheWall; + hypixelSports: HypixelSports; + MiniWalls: MiniWalls; + oneInTheQuiver: OneInTheQuiver; + partyGames: PartyGames; + santaSays: SantaSays; + santaSimulator: SantaSimulator; + scubaSimulator: ScubaSimulator; + simonSays: SimonSays; + soccer: Soccer; + throwOut: ThrowOut; + woolHunt: WoolHunt; + zombies: Zombies; + constructor(data: Record) { + this.activeMovementTrail = data?.active_movement_trail || 'UNKNOWN'; + this.activeProjectileTrail = data?.active_projectile_trail || 'UNKNOWN'; + this.activeVictoryDance = data?.active_victory_dance || 'UNKNOWN'; + this.blood = data?.blood || false; + this.bountyHead = data?.bounty_head || 'DEFAULT'; + this.tokens = data?.tokens || data?.coins || 0; + this.dec2016Achievements = data?.dec2016_achievements || false; + this.dec2016Achievements2 = data?.dec2016_achievements2 || false; + this.flash = data?.flash || false; + this.hideAndSeekShowQueueBook = data?.hideandseek_showqueuebook || false; + this.hints = data?.hints || false; + this.language = data?.language || 'UNKNOWN'; + this.maxWave = data?.max_wave || 0; + this.meleeWeapon = data?.melee_weapon || 'UNKNOWN'; + this.monthlyTokens = parseInt( + data?.[`monthly_tokens_${monthAB()}`] || data?.[`monthly_coins_${monthAB()}`] || 0, + 10 + ); + this.monthlyTokensA = data?.monthly_coins_a || 0; + this.monthlyTokensB = data?.monthly_coins_b || 0; + this.music = data?.music || false; + this.mysteryGiftsObtained = data?.mystery_gifts_obtained || 0; + this.options = new ArcadeOptions(data); + this.poopCollected = data?.poop_collected || 0; + this.ppLanguage = data?.pp_language || 'UNKNOWN'; + this.privategames = data?.privategames || {}; + this.shopSort = data?.shop_sort || 'UNKNOWN'; + this.shopSortEnableOwnedFirst = data?.shop_sort_enable_owned_first || false; + this.showInfoBook = data?.showinfobook || false; + this.simonSong = data?.simon_song || false; + this.stampLevel = data?.stamp_level || 0; + this.timestamp = data?.time_stamp || 0; + this.weeklyTokens = parseInt(data?.[`weekly_tokens_${weekAB()}`] || data?.[`weekly_coins_${weekAB()}`] || 0, 10); + this.weeklyTokensA = data?.weekly_tokens_a || data?.weekly_coins_a || 0; + this.weeklyTokensB = data?.weekly_tokens_b || data?.weekly_coins_b || 0; + this.xmasMusic = data?.xmas_music || false; + this.packages = data?.packages || []; + this.blockingDead = new BlockingDead(data); + this.dragonWars = new DragonWars(data); + this.dropper = new Dropper(data?.dropper || {}); + this.drawTheirThing = new DrawTheirThing(data); + this.dtt = new Dtt(data); + this.easterSimulator = new EasterSimulator(data); + this.enderSpleef = new EnderSpleef(data); + this.farmHunt = new FarmHunt(data); + this.footBall = new FootBall(data); + this.galaxyWars = new GalaxyWars(data); + this.grinchSimulator = new GrinchSimulator(data); + this.halloweenSimulator = new HalloweenSimulator(data); + this.hideAndSeek = new HideAndSeek(data); + this.holeInTheWall = new HoleInTheWall(data); + this.hypixelSports = new HypixelSports(data); + this.MiniWalls = new MiniWalls(data); + this.oneInTheQuiver = new OneInTheQuiver(data); + this.partyGames = new PartyGames(data); + this.santaSays = new SantaSays(data); + this.santaSimulator = new SantaSimulator(data); + this.scubaSimulator = new ScubaSimulator(data); + this.simonSays = new SimonSays(data); + this.soccer = new Soccer(data); + this.throwOut = new ThrowOut(data); + this.woolHunt = new WoolHunt(data); + this.zombies = new Zombies(data); + } +} + +export default Arcade; diff --git a/src/Structures/MiniGames/Arcade/ArcadeOptions.test.ts b/src/Structures/MiniGames/Arcade/ArcadeOptions.test.ts new file mode 100644 index 000000000..4a29acd93 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ArcadeOptions.test.ts @@ -0,0 +1,25 @@ +import ArcadeOptions from './ArcadeOptions.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ArcadeOptions', () => { + const data = new ArcadeOptions({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ArcadeOptions); + expectTypeOf(data).toEqualTypeOf(); + expect(data.showAllKillFeed).toBeDefined(); + expectTypeOf(data.showAllKillFeed).toEqualTypeOf(); + expect(data.showEnemyWoolDropped).toBeDefined(); + expectTypeOf(data.showEnemyWoolDropped).toEqualTypeOf(); + expect(data.showEnemyWoolPickedUp).toBeDefined(); + expectTypeOf(data.showEnemyWoolPickedUp).toEqualTypeOf(); + expect(data.showOwnWoolDropped).toBeDefined(); + expectTypeOf(data.showOwnWoolDropped).toEqualTypeOf(); + expect(data.showOwnWoolPickedUp).toBeDefined(); + expectTypeOf(data.showOwnWoolPickedUp).toEqualTypeOf(); + expect(data.showTipHologram).toBeDefined(); + expectTypeOf(data.showTipHologram).toEqualTypeOf(); + expect(data.showTips).toBeDefined(); + expectTypeOf(data.showTips).toEqualTypeOf(); + expect(data.showTutorialBook).toBeDefined(); + expectTypeOf(data.showTutorialBook).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/ArcadeOptions.ts b/src/Structures/MiniGames/Arcade/ArcadeOptions.ts new file mode 100644 index 000000000..34dd50d76 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ArcadeOptions.ts @@ -0,0 +1,22 @@ +class ArcadeOptions { + showAllKillFeed: boolean; + showEnemyWoolDropped: boolean; + showEnemyWoolPickedUp: boolean; + showOwnWoolDropped: boolean; + showOwnWoolPickedUp: boolean; + showTipHologram: boolean; + showTips: boolean; + showTutorialBook: boolean; + constructor(data: Record) { + this.showAllKillFeed = (data?.option_show_all_killfeed || 'off') === 'on'; + this.showEnemyWoolDropped = (data?.option_show_enemy_wool_dropped || 'off') === 'on'; + this.showEnemyWoolPickedUp = (data?.option_show_enemy_wool_picked_up || 'off') === 'on'; + this.showOwnWoolDropped = (data?.option_show_own_wool_dropped || 'off') === 'on'; + this.showOwnWoolPickedUp = (data?.option_show_own_wool_picked_up || 'off') === 'on'; + this.showTipHologram = (data?.option_show_tip_hologram || 'off') === 'on'; + this.showTips = (data?.option_show_tips || 'off') === 'on'; + this.showTutorialBook = (data?.option_show_tutorial_book || 'off') === 'on'; + } +} + +export default ArcadeOptions; diff --git a/src/Structures/MiniGames/Arcade/BlockingDead.test.ts b/src/Structures/MiniGames/Arcade/BlockingDead.test.ts new file mode 100644 index 000000000..23a10680a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/BlockingDead.test.ts @@ -0,0 +1,18 @@ +import BlockingDead from './BlockingDead.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BlockingDead', () => { + const data = new BlockingDead({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BlockingDead); + expectTypeOf(data).toEqualTypeOf(); + expect(data.headShots).toBeDefined(); + expect(data.headShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headShots).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/BlockingDead.ts b/src/Structures/MiniGames/Arcade/BlockingDead.ts new file mode 100644 index 000000000..07a390a95 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/BlockingDead.ts @@ -0,0 +1,12 @@ +class BlockingDead { + headShots: number; + kills: number; + wins: number; + constructor(data: Record) { + this.headShots = data?.headshots_dayone || 0; + this.kills = data?.kills_dayone || 0; + this.wins = data?.wins_dayone || 0; + } +} + +export default BlockingDead; diff --git a/src/Structures/MiniGames/Arcade/DragonWars.test.ts b/src/Structures/MiniGames/Arcade/DragonWars.test.ts new file mode 100644 index 000000000..a01eeea8e --- /dev/null +++ b/src/Structures/MiniGames/Arcade/DragonWars.test.ts @@ -0,0 +1,15 @@ +import DragonWars from './DragonWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DragonWars', () => { + const data = new DragonWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DragonWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/DragonWars.ts b/src/Structures/MiniGames/Arcade/DragonWars.ts new file mode 100644 index 000000000..cf142b64f --- /dev/null +++ b/src/Structures/MiniGames/Arcade/DragonWars.ts @@ -0,0 +1,10 @@ +class DragonWars { + kills: number; + wins: number; + constructor(data: Record) { + this.kills = data?.kills_dragonwars2 || 0; + this.wins = data?.wins_dragonwars2 || 0; + } +} + +export default DragonWars; diff --git a/src/Structures/MiniGames/Arcade/DrawTheirThing.test.ts b/src/Structures/MiniGames/Arcade/DrawTheirThing.test.ts new file mode 100644 index 000000000..a5c650fee --- /dev/null +++ b/src/Structures/MiniGames/Arcade/DrawTheirThing.test.ts @@ -0,0 +1,12 @@ +import DrawTheirThing from './DrawTheirThing.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DrawTheirThing', () => { + const data = new DrawTheirThing({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DrawTheirThing); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/DrawTheirThing.ts b/src/Structures/MiniGames/Arcade/DrawTheirThing.ts new file mode 100644 index 000000000..c9d89e8f1 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/DrawTheirThing.ts @@ -0,0 +1,8 @@ +class DrawTheirThing { + wins: number; + constructor(data: Record) { + this.wins = data?.wins_draw_their_thing || 0; + } +} + +export default DrawTheirThing; diff --git a/src/Structures/MiniGames/Arcade/Dropper/Dropper.test.ts b/src/Structures/MiniGames/Arcade/Dropper/Dropper.test.ts new file mode 100644 index 000000000..9d5e1f38f --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dropper/Dropper.test.ts @@ -0,0 +1,217 @@ +import Dropper from './Dropper.js'; +import DropperMap from './DropperMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Dropper', () => { + const data = new Dropper({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Dropper); + expectTypeOf(data).toEqualTypeOf(); + expect(data.fails).toBeDefined(); + expect(data.fails).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fails).toEqualTypeOf(); + expect(data.fastestGame).toBeDefined(); + expect(data.fastestGame).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestGame).toEqualTypeOf(); + expect(data.flawlessGames).toBeDefined(); + expect(data.flawlessGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flawlessGames).toEqualTypeOf(); + expect(data.gamesFinished).toBeDefined(); + expect(data.gamesFinished).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesFinished).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.mapsCompleted).toBeDefined(); + expect(data.mapsCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mapsCompleted).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.atlantis).toBeDefined(); + expect(data.atlantis).toBeInstanceOf(DropperMap); + expectTypeOf(data.atlantis).toEqualTypeOf(); + expect(data.balloons).toBeDefined(); + expect(data.balloons).toBeInstanceOf(DropperMap); + expectTypeOf(data.balloons).toEqualTypeOf(); + expect(data.bbq).toBeDefined(); + expect(data.bbq).toBeInstanceOf(DropperMap); + expectTypeOf(data.bbq).toEqualTypeOf(); + expect(data.beanstalk).toBeDefined(); + expect(data.beanstalk).toBeInstanceOf(DropperMap); + expectTypeOf(data.beanstalk).toEqualTypeOf(); + expect(data.birdcage).toBeDefined(); + expect(data.birdcage).toBeInstanceOf(DropperMap); + expectTypeOf(data.birdcage).toEqualTypeOf(); + expect(data.boardgames).toBeDefined(); + expect(data.boardgames).toBeInstanceOf(DropperMap); + expectTypeOf(data.boardgames).toEqualTypeOf(); + expect(data.bridges).toBeDefined(); + expect(data.bridges).toBeInstanceOf(DropperMap); + expectTypeOf(data.bridges).toEqualTypeOf(); + expect(data.butterflies).toBeDefined(); + expect(data.butterflies).toBeInstanceOf(DropperMap); + expectTypeOf(data.butterflies).toEqualTypeOf(); + expect(data.cabin).toBeDefined(); + expect(data.cabin).toBeInstanceOf(DropperMap); + expectTypeOf(data.cabin).toEqualTypeOf(); + expect(data.castle).toBeDefined(); + expect(data.castle).toBeInstanceOf(DropperMap); + expectTypeOf(data.castle).toEqualTypeOf(); + expect(data.city).toBeDefined(); + expect(data.city).toBeInstanceOf(DropperMap); + expectTypeOf(data.city).toEqualTypeOf(); + expect(data.distance).toBeDefined(); + expect(data.distance).toBeInstanceOf(DropperMap); + expectTypeOf(data.distance).toEqualTypeOf(); + expect(data.distortion).toBeDefined(); + expect(data.distortion).toBeInstanceOf(DropperMap); + expectTypeOf(data.distortion).toEqualTypeOf(); + expect(data.drainage).toBeDefined(); + expect(data.drainage).toBeInstanceOf(DropperMap); + expectTypeOf(data.drainage).toEqualTypeOf(); + expect(data.emoji).toBeDefined(); + expect(data.emoji).toBeInstanceOf(DropperMap); + expectTypeOf(data.emoji).toEqualTypeOf(); + expect(data.factory).toBeDefined(); + expect(data.factory).toBeInstanceOf(DropperMap); + expectTypeOf(data.factory).toEqualTypeOf(); + expect(data.floatingIslands).toBeDefined(); + expect(data.floatingIslands).toBeInstanceOf(DropperMap); + expectTypeOf(data.floatingIslands).toEqualTypeOf(); + expect(data.flytrap).toBeDefined(); + expect(data.flytrap).toBeInstanceOf(DropperMap); + expectTypeOf(data.flytrap).toEqualTypeOf(); + expect(data.frogspawn).toBeDefined(); + expect(data.frogspawn).toBeInstanceOf(DropperMap); + expectTypeOf(data.frogspawn).toEqualTypeOf(); + expect(data.gears).toBeDefined(); + expect(data.gears).toBeInstanceOf(DropperMap); + expectTypeOf(data.gears).toEqualTypeOf(); + expect(data.geometry).toBeDefined(); + expect(data.geometry).toBeInstanceOf(DropperMap); + expectTypeOf(data.geometry).toEqualTypeOf(); + expect(data.glacier).toBeDefined(); + expect(data.glacier).toBeInstanceOf(DropperMap); + expectTypeOf(data.glacier).toEqualTypeOf(); + expect(data.hellgate).toBeDefined(); + expect(data.hellgate).toBeInstanceOf(DropperMap); + expectTypeOf(data.hellgate).toEqualTypeOf(); + expect(data.illusion).toBeDefined(); + expect(data.illusion).toBeInstanceOf(DropperMap); + expectTypeOf(data.illusion).toEqualTypeOf(); + expect(data.iris).toBeDefined(); + expect(data.iris).toBeInstanceOf(DropperMap); + expectTypeOf(data.iris).toEqualTypeOf(); + expect(data.kingDommines).toBeDefined(); + expect(data.kingDommines).toBeInstanceOf(DropperMap); + expectTypeOf(data.kingDommines).toEqualTypeOf(); + expect(data.kingsPass).toBeDefined(); + expect(data.kingsPass).toBeInstanceOf(DropperMap); + expectTypeOf(data.kingsPass).toEqualTypeOf(); + expect(data.kraken).toBeDefined(); + expect(data.kraken).toBeInstanceOf(DropperMap); + expectTypeOf(data.kraken).toEqualTypeOf(); + expect(data.launchZone).toBeDefined(); + expect(data.launchZone).toBeInstanceOf(DropperMap); + expectTypeOf(data.launchZone).toEqualTypeOf(); + expect(data.lavaFall).toBeDefined(); + expect(data.lavaFall).toBeInstanceOf(DropperMap); + expectTypeOf(data.lavaFall).toEqualTypeOf(); + expect(data.lily).toBeDefined(); + expect(data.lily).toBeInstanceOf(DropperMap); + expectTypeOf(data.lily).toEqualTypeOf(); + expect(data.maelstrom).toBeDefined(); + expect(data.maelstrom).toBeInstanceOf(DropperMap); + expectTypeOf(data.maelstrom).toEqualTypeOf(); + expect(data.mainframe).toBeDefined(); + expect(data.mainframe).toBeInstanceOf(DropperMap); + expectTypeOf(data.mainframe).toEqualTypeOf(); + expect(data.microscope).toBeDefined(); + expect(data.microscope).toBeInstanceOf(DropperMap); + expectTypeOf(data.microscope).toEqualTypeOf(); + expect(data.mineshaft).toBeDefined(); + expect(data.mineshaft).toBeInstanceOf(DropperMap); + expectTypeOf(data.mineshaft).toEqualTypeOf(); + expect(data.mushroom).toBeDefined(); + expect(data.mushroom).toBeInstanceOf(DropperMap); + expectTypeOf(data.mushroom).toEqualTypeOf(); + expect(data.nightlife).toBeDefined(); + expect(data.nightlife).toBeInstanceOf(DropperMap); + expectTypeOf(data.nightlife).toEqualTypeOf(); + expect(data.ocean).toBeDefined(); + expect(data.ocean).toBeInstanceOf(DropperMap); + expectTypeOf(data.ocean).toEqualTypeOf(); + expect(data.overgrown).toBeDefined(); + expect(data.overgrown).toBeInstanceOf(DropperMap); + expectTypeOf(data.overgrown).toEqualTypeOf(); + expect(data.painted).toBeDefined(); + expect(data.painted).toBeInstanceOf(DropperMap); + expectTypeOf(data.painted).toEqualTypeOf(); + expect(data.paradigm).toBeDefined(); + expect(data.paradigm).toBeInstanceOf(DropperMap); + expectTypeOf(data.paradigm).toEqualTypeOf(); + expect(data.plughole).toBeDefined(); + expect(data.plughole).toBeInstanceOf(DropperMap); + expectTypeOf(data.plughole).toEqualTypeOf(); + expect(data.raindrops).toBeDefined(); + expect(data.raindrops).toBeInstanceOf(DropperMap); + expectTypeOf(data.raindrops).toEqualTypeOf(); + expect(data.ravine).toBeDefined(); + expect(data.ravine).toBeInstanceOf(DropperMap); + expectTypeOf(data.ravine).toEqualTypeOf(); + expect(data.retro).toBeDefined(); + expect(data.retro).toBeInstanceOf(DropperMap); + expectTypeOf(data.retro).toEqualTypeOf(); + expect(data.revolve).toBeDefined(); + expect(data.revolve).toBeInstanceOf(DropperMap); + expectTypeOf(data.revolve).toEqualTypeOf(); + expect(data.sandWorm).toBeDefined(); + expect(data.sandWorm).toBeInstanceOf(DropperMap); + expectTypeOf(data.sandWorm).toEqualTypeOf(); + expect(data.sewer).toBeDefined(); + expect(data.sewer).toBeInstanceOf(DropperMap); + expectTypeOf(data.sewer).toEqualTypeOf(); + expect(data.space).toBeDefined(); + expect(data.space).toBeInstanceOf(DropperMap); + expectTypeOf(data.space).toEqualTypeOf(); + expect(data.stratocumulus).toBeDefined(); + expect(data.stratocumulus).toBeInstanceOf(DropperMap); + expectTypeOf(data.stratocumulus).toEqualTypeOf(); + expect(data.sweets).toBeDefined(); + expect(data.sweets).toBeInstanceOf(DropperMap); + expectTypeOf(data.sweets).toEqualTypeOf(); + expect(data.tangle).toBeDefined(); + expect(data.tangle).toBeInstanceOf(DropperMap); + expectTypeOf(data.tangle).toEqualTypeOf(); + expect(data.time).toBeDefined(); + expect(data.time).toBeInstanceOf(DropperMap); + expectTypeOf(data.time).toEqualTypeOf(); + expect(data.toilet).toBeDefined(); + expect(data.toilet).toBeInstanceOf(DropperMap); + expectTypeOf(data.toilet).toEqualTypeOf(); + expect(data.ufo).toBeDefined(); + expect(data.ufo).toBeInstanceOf(DropperMap); + expectTypeOf(data.ufo).toEqualTypeOf(); + expect(data.upsideDown).toBeDefined(); + expect(data.upsideDown).toBeInstanceOf(DropperMap); + expectTypeOf(data.upsideDown).toEqualTypeOf(); + expect(data.vintage).toBeDefined(); + expect(data.vintage).toBeInstanceOf(DropperMap); + expectTypeOf(data.vintage).toEqualTypeOf(); + expect(data.vortex).toBeDefined(); + expect(data.vortex).toBeInstanceOf(DropperMap); + expectTypeOf(data.vortex).toEqualTypeOf(); + expect(data.warp).toBeDefined(); + expect(data.warp).toBeInstanceOf(DropperMap); + expectTypeOf(data.warp).toEqualTypeOf(); + expect(data.warPortal).toBeDefined(); + expect(data.warPortal).toBeInstanceOf(DropperMap); + expectTypeOf(data.warPortal).toEqualTypeOf(); + expect(data.well).toBeDefined(); + expect(data.well).toBeInstanceOf(DropperMap); + expectTypeOf(data.well).toEqualTypeOf(); + expect(data.western).toBeDefined(); + expect(data.western).toBeInstanceOf(DropperMap); + expectTypeOf(data.western).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Dropper/Dropper.ts b/src/Structures/MiniGames/Arcade/Dropper/Dropper.ts new file mode 100644 index 000000000..9204e319a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dropper/Dropper.ts @@ -0,0 +1,146 @@ +import DropperMap from './DropperMap.js'; + +class Dropper { + fails: number; + fastestGame: number; + flawlessGames: number; + gamesFinished: number; + gamesPlayed: number; + mapsCompleted: number; + wins: number; + atlantis: DropperMap; + balloons: DropperMap; + bbq: DropperMap; + beanstalk: DropperMap; + birdcage: DropperMap; + boardgames: DropperMap; + bridges: DropperMap; + butterflies: DropperMap; + cabin: DropperMap; + castle: DropperMap; + city: DropperMap; + distance: DropperMap; + distortion: DropperMap; + drainage: DropperMap; + emoji: DropperMap; + factory: DropperMap; + floatingIslands: DropperMap; + flytrap: DropperMap; + frogspawn: DropperMap; + gears: DropperMap; + geometry: DropperMap; + glacier: DropperMap; + hellgate: DropperMap; + illusion: DropperMap; + iris: DropperMap; + kingDommines: DropperMap; + kingsPass: DropperMap; + kraken: DropperMap; + launchZone: DropperMap; + lavaFall: DropperMap; + lily: DropperMap; + maelstrom: DropperMap; + mainframe: DropperMap; + microscope: DropperMap; + mineshaft: DropperMap; + mushroom: DropperMap; + nightlife: DropperMap; + ocean: DropperMap; + overgrown: DropperMap; + painted: DropperMap; + paradigm: DropperMap; + plughole: DropperMap; + raindrops: DropperMap; + ravine: DropperMap; + retro: DropperMap; + revolve: DropperMap; + sandWorm: DropperMap; + sewer: DropperMap; + space: DropperMap; + stratocumulus: DropperMap; + sweets: DropperMap; + tangle: DropperMap; + time: DropperMap; + toilet: DropperMap; + ufo: DropperMap; + upsideDown: DropperMap; + vintage: DropperMap; + vortex: DropperMap; + warp: DropperMap; + warPortal: DropperMap; + well: DropperMap; + western: DropperMap; + constructor(data: Record) { + this.fails = data?.fails || 0; + this.fastestGame = data?.fastest_game || 0; + this.flawlessGames = data?.flawless_games || 0; + this.gamesFinished = data?.games_finished || 0; + this.gamesPlayed = data?.games_played || 0; + this.mapsCompleted = data?.maps_completed || 0; + this.wins = data?.wins || 0; + this.atlantis = new DropperMap(data?.atlantis || {}); + this.balloons = new DropperMap(data?.balloons || {}); + this.bbq = new DropperMap(data?.bbq || {}); + this.beanstalk = new DropperMap(data?.beanstalk || {}); + this.birdcage = new DropperMap(data?.birdcage || {}); + this.boardgames = new DropperMap(data?.boardgames || {}); + this.bridges = new DropperMap(data?.bridges || {}); + this.butterflies = new DropperMap(data?.butterflies || {}); + this.cabin = new DropperMap(data?.cabin || {}); + this.castle = new DropperMap(data?.castle || {}); + this.city = new DropperMap(data?.city || {}); + this.distance = new DropperMap(data?.distance || {}); + this.distortion = new DropperMap(data?.distortion || {}); + this.drainage = new DropperMap(data?.drainage || {}); + this.emoji = new DropperMap(data?.emoji || {}); + this.factory = new DropperMap(data?.factory || {}); + this.floatingIslands = new DropperMap(data?.floatingislands || {}); + this.flytrap = new DropperMap(data?.flytrap || {}); + this.frogspawn = new DropperMap(data?.frogspawn || {}); + this.gears = new DropperMap(data?.gears || {}); + this.geometry = new DropperMap(data?.geometry || {}); + this.glacier = new DropperMap(data?.glacier || {}); + this.hellgate = new DropperMap(data?.hellgate || {}); + this.illusion = new DropperMap(data?.illusion || {}); + this.iris = new DropperMap(data?.iris || {}); + this.kingDommines = new DropperMap(data?.kingdommines || {}); + this.kingsPass = new DropperMap(data?.kingspass || {}); + this.kraken = new DropperMap(data?.kraken || {}); + this.launchZone = new DropperMap(data?.launchzone || {}); + this.lavaFall = new DropperMap(data?.lavafall || {}); + this.lily = new DropperMap(data?.lily || {}); + this.maelstrom = new DropperMap(data?.maelstrom || {}); + this.mainframe = new DropperMap(data?.mainframe || {}); + this.microscope = new DropperMap(data?.microscope || {}); + this.mineshaft = new DropperMap(data?.mineshaft || {}); + this.mushroom = new DropperMap(data?.mushroom || {}); + this.nightlife = new DropperMap(data?.nightlife || {}); + this.ocean = new DropperMap(data?.ocean || {}); + this.overgrown = new DropperMap(data?.overgrown || {}); + this.painted = new DropperMap(data?.painted || {}); + this.paradigm = new DropperMap(data?.paradigm || {}); + this.plughole = new DropperMap(data?.plughole || {}); + this.raindrops = new DropperMap(data?.raindrops || {}); + this.ravine = new DropperMap(data?.ravine || {}); + this.retro = new DropperMap(data?.retro || {}); + this.revolve = new DropperMap(data?.revolve || {}); + this.sandWorm = new DropperMap(data?.sandworm || {}); + this.sewer = new DropperMap(data?.sewer || {}); + this.space = new DropperMap(data?.space || {}); + this.stratocumulus = new DropperMap(data?.stratocumulus || {}); + this.sweets = new DropperMap(data?.sweets || {}); + this.tangle = new DropperMap(data?.tangle || {}); + this.time = new DropperMap(data?.time || {}); + this.toilet = new DropperMap(data?.toilet || {}); + this.ufo = new DropperMap(data?.ufo || {}); + this.upsideDown = new DropperMap(data?.upsidedown || {}); + this.vintage = new DropperMap(data?.vintage || {}); + this.vortex = new DropperMap(data?.vortex || {}); + this.warp = new DropperMap(data?.warp || {}); + this.warPortal = new DropperMap(data?.warportal || {}); + this.well = new DropperMap(data?.well || {}); + this.western = new DropperMap(data?.western || {}); + } +} + +export default Dropper; diff --git a/src/Structures/MiniGames/Arcade/Dropper/DropperMap.test.ts b/src/Structures/MiniGames/Arcade/Dropper/DropperMap.test.ts new file mode 100644 index 000000000..c924e43e2 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dropper/DropperMap.test.ts @@ -0,0 +1,15 @@ +import DropperMap from './DropperMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DropperMap', () => { + const data = new DropperMap({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DropperMap); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestTime).toBeDefined(); + expect(data.bestTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestTime).toEqualTypeOf(); + expect(data.completions).toBeDefined(); + expect(data.completions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completions).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Dropper/DropperMap.ts b/src/Structures/MiniGames/Arcade/Dropper/DropperMap.ts new file mode 100644 index 000000000..a5355c08c --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dropper/DropperMap.ts @@ -0,0 +1,10 @@ +class DropperMap { + bestTime: number; + completions: number; + constructor(data: Record) { + this.bestTime = data?.best_time || 0; + this.completions = data?.completions || 0; + } +} + +export default DropperMap; diff --git a/src/Structures/MiniGames/Arcade/Dtt.test.ts b/src/Structures/MiniGames/Arcade/Dtt.test.ts new file mode 100644 index 000000000..1e84a2995 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dtt.test.ts @@ -0,0 +1,15 @@ +import Dtt from './Dtt.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Dtt', () => { + const data = new Dtt({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Dtt); + expectTypeOf(data).toEqualTypeOf(); + expect(data.dropdown).toBeDefined(); + expectTypeOf(data.dropdown).toEqualTypeOf(); + expect(data.filter).toBeDefined(); + expectTypeOf(data.filter).toEqualTypeOf(); + expect(data.music).toBeDefined(); + expectTypeOf(data.music).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Dtt.ts b/src/Structures/MiniGames/Arcade/Dtt.ts new file mode 100644 index 000000000..0aec08be7 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Dtt.ts @@ -0,0 +1,13 @@ +// TODO: Work out WHAT THE FUCK Dtt means. I cannot find any mentions of it +class Dtt { + dropdown: boolean; + filter: boolean; + music: boolean; + constructor(data: Record) { + this.dropdown = data?.dtt_dropdown || false; + this.filter = data?.dtt_filter || false; + this.music = data?.dtt_music || false; + } +} + +export default Dtt; diff --git a/src/Structures/MiniGames/Arcade/EasterSimulator.test.ts b/src/Structures/MiniGames/Arcade/EasterSimulator.test.ts new file mode 100644 index 000000000..7ef58ce73 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/EasterSimulator.test.ts @@ -0,0 +1,15 @@ +import EasterSimulator from './EasterSimulator.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('EasterSimulator', () => { + const data = new EasterSimulator({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(EasterSimulator); + expectTypeOf(data).toEqualTypeOf(); + expect(data.eggsFound).toBeDefined(); + expect(data.eggsFound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggsFound).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/EasterSimulator.ts b/src/Structures/MiniGames/Arcade/EasterSimulator.ts new file mode 100644 index 000000000..4ab0c9f24 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/EasterSimulator.ts @@ -0,0 +1,10 @@ +class EasterSimulator { + eggsFound: number; + wins: number; + constructor(data: Record) { + this.eggsFound = data?.eggs_found_easter_simulator || 0; + this.wins = data?.wins_easter_simulator || 0; + } +} + +export default EasterSimulator; diff --git a/src/Structures/MiniGames/Arcade/EnderSpleef.test.ts b/src/Structures/MiniGames/Arcade/EnderSpleef.test.ts new file mode 100644 index 000000000..6683305ff --- /dev/null +++ b/src/Structures/MiniGames/Arcade/EnderSpleef.test.ts @@ -0,0 +1,27 @@ +import EnderSpleef from './EnderSpleef.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ArcadeEnderSpleefTrail } from '../../../Types/Player.js'; + +test('EnderSpleef', () => { + const data = new EnderSpleef({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(EnderSpleef); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bigshotPowerupActivations).toBeDefined(); + expect(data.bigshotPowerupActivations).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bigshotPowerupActivations).toEqualTypeOf(); + expect(data.blocksDestroyed).toBeDefined(); + expect(data.blocksDestroyed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksDestroyed).toEqualTypeOf(); + expect(data.spleefTrail).toBeDefined(); + expectTypeOf(data.spleefTrail).toEqualTypeOf(); + expect(data.powerupActivations).toBeDefined(); + expect(data.powerupActivations).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powerupActivations).toEqualTypeOf(); + expect(data.tripleshotPowerupActivations).toBeDefined(); + expect(data.tripleshotPowerupActivations).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tripleshotPowerupActivations).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/EnderSpleef.ts b/src/Structures/MiniGames/Arcade/EnderSpleef.ts new file mode 100644 index 000000000..bea74ada4 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/EnderSpleef.ts @@ -0,0 +1,20 @@ +import type { ArcadeEnderSpleefTrail } from '../../../Types/Player.js'; + +class EnderSpleef { + bigshotPowerupActivations: number; + blocksDestroyed: number; + spleefTrail: ArcadeEnderSpleefTrail | 'UNKNOWN'; + powerupActivations: number; + tripleshotPowerupActivations: number; + wins: number; + constructor(data: Record) { + this.bigshotPowerupActivations = data?.bigshot_powerup_activations_ender || 0; + this.blocksDestroyed = data?.blocks_destroyed_ender || 0; + this.spleefTrail = data?.enderspleef_trail || 'UNKNOWN'; + this.powerupActivations = data?.powerup_activations_ender || 0; + this.tripleshotPowerupActivations = data?.tripleshot_powerup_activations_ender || 0; + this.wins = data?.wins_ender || 0; + } +} + +export default EnderSpleef; diff --git a/src/Structures/MiniGames/Arcade/FarmHunt.test.ts b/src/Structures/MiniGames/Arcade/FarmHunt.test.ts new file mode 100644 index 000000000..8317d6c7d --- /dev/null +++ b/src/Structures/MiniGames/Arcade/FarmHunt.test.ts @@ -0,0 +1,60 @@ +import FarmHunt from './FarmHunt.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('FarmHunt', () => { + const data = new FarmHunt({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(FarmHunt); + expectTypeOf(data).toEqualTypeOf(); + expect(data.animalBowKills).toBeDefined(); + expect(data.animalBowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.animalBowKills).toEqualTypeOf(); + expect(data.animalKills).toBeDefined(); + expect(data.animalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.animalKills).toEqualTypeOf(); + expect(data.animalWins).toBeDefined(); + expect(data.animalWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.animalWins).toEqualTypeOf(); + expect(data.animalsBowKills).toBeDefined(); + expect(data.animalsBowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.animalsBowKills).toEqualTypeOf(); + expect(data.bowKills).toBeDefined(); + expect(data.bowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowKills).toEqualTypeOf(); + expect(data.dangerousTauntsUsed).toBeDefined(); + expect(data.dangerousTauntsUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dangerousTauntsUsed).toEqualTypeOf(); + expect(data.fireworkTauntsUsed).toBeDefined(); + expect(data.fireworkTauntsUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fireworkTauntsUsed).toEqualTypeOf(); + expect(data.hunterBowKills).toBeDefined(); + expect(data.hunterBowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hunterBowKills).toEqualTypeOf(); + expect(data.hunterKills).toBeDefined(); + expect(data.hunterKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hunterKills).toEqualTypeOf(); + expect(data.hunterWins).toBeDefined(); + expect(data.hunterWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hunterWins).toEqualTypeOf(); + expect(data.huntersBowKills).toBeDefined(); + expect(data.huntersBowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.huntersBowKills).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.poopCollected).toBeDefined(); + expect(data.poopCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.poopCollected).toEqualTypeOf(); + expect(data.riskyTauntsUsed).toBeDefined(); + expect(data.riskyTauntsUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.riskyTauntsUsed).toEqualTypeOf(); + expect(data.safeTauntsUsed).toBeDefined(); + expect(data.safeTauntsUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.safeTauntsUsed).toEqualTypeOf(); + expect(data.tauntsUsed).toBeDefined(); + expect(data.tauntsUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tauntsUsed).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/FarmHunt.ts b/src/Structures/MiniGames/Arcade/FarmHunt.ts new file mode 100644 index 000000000..909dac5b2 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/FarmHunt.ts @@ -0,0 +1,40 @@ +class FarmHunt { + animalBowKills: number; + animalKills: number; + animalWins: number; + animalsBowKills: number; + bowKills: number; + dangerousTauntsUsed: number; + fireworkTauntsUsed: number; + hunterBowKills: number; + hunterKills: number; + hunterWins: number; + huntersBowKills: number; + kills: number; + poopCollected: number; + riskyTauntsUsed: number; + safeTauntsUsed: number; + tauntsUsed: number; + wins: number; + constructor(data: Record) { + this.animalBowKills = data?.animal_bow_kills_farm_hunt || 0; + this.animalKills = data?.animal_kills_farm_hunt || 0; + this.animalWins = data?.animal_wins_farm_hunt || 0; + this.animalsBowKills = data?.animals_bow_kills_farm_hunt || 0; + this.bowKills = data?.bow_kills_farm_hunt || 0; + this.dangerousTauntsUsed = data?.dangerous_taunts_used_farm_hunt || 0; + this.fireworkTauntsUsed = data?.firework_taunts_used_farm_hunt || 0; + this.hunterBowKills = data?.hunter_bow_kills_farm_hunt || 0; + this.hunterKills = data?.hunter_kills_farm_hunt || 0; + this.hunterWins = data?.hunter_wins_farm_hunt || 0; + this.huntersBowKills = data?.hunters_bow_kills_farm_hunt || 0; + this.kills = data?.kills_farm_hunt || 0; + this.poopCollected = data?.poop_collected_farm_hunt || 0; + this.riskyTauntsUsed = data?.risky_taunts_used_farm_hunt || 0; + this.safeTauntsUsed = data?.safe_taunts_used_farm_hunt || 0; + this.tauntsUsed = data?.taunts_used_farm_hunt || 0; + this.wins = data?.wins_farm_hunt || 0; + } +} + +export default FarmHunt; diff --git a/src/Structures/MiniGames/Arcade/FootBall.test.ts b/src/Structures/MiniGames/Arcade/FootBall.test.ts new file mode 100644 index 000000000..81275f5a3 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/FootBall.test.ts @@ -0,0 +1,21 @@ +import FootBall from './FootBall.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('FootBall', () => { + const data = new FootBall({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(FootBall); + expectTypeOf(data).toEqualTypeOf(); + expect(data.goals).toBeDefined(); + expect(data.goals).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goals).toEqualTypeOf(); + expect(data.kicks).toBeDefined(); + expect(data.kicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kicks).toEqualTypeOf(); + expect(data.powerkicks).toBeDefined(); + expect(data.powerkicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powerkicks).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/FootBall.ts b/src/Structures/MiniGames/Arcade/FootBall.ts new file mode 100644 index 000000000..72015c030 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/FootBall.ts @@ -0,0 +1,14 @@ +class FootBall { + goals: number; + kicks: number; + powerkicks: number; + wins: number; + constructor(data: Record) { + this.goals = data?.fb_goals || 0; + this.kicks = data?.fb_kicks || 0; + this.powerkicks = data?.fb_powerkicks || 0; + this.wins = data?.fb_wins || 0; + } +} + +export default FootBall; diff --git a/src/Structures/MiniGames/Arcade/GalaxyWars.test.ts b/src/Structures/MiniGames/Arcade/GalaxyWars.test.ts new file mode 100644 index 000000000..389df472d --- /dev/null +++ b/src/Structures/MiniGames/Arcade/GalaxyWars.test.ts @@ -0,0 +1,45 @@ +import GalaxyWars from './GalaxyWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GalaxyWars', () => { + const data = new GalaxyWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GalaxyWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.empireKills).toBeDefined(); + expect(data.empireKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.empireKills).toEqualTypeOf(); + expect(data.gameWins).toBeDefined(); + expect(data.gameWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gameWins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.monthlyKills).toBeDefined(); + expect(data.monthlyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKills).toEqualTypeOf(); + expect(data.monthlyKillsA).toBeDefined(); + expect(data.monthlyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsA).toEqualTypeOf(); + expect(data.monthlyKillsB).toBeDefined(); + expect(data.monthlyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsB).toEqualTypeOf(); + expect(data.rebelKills).toBeDefined(); + expect(data.rebelKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rebelKills).toEqualTypeOf(); + expect(data.shotsFired).toBeDefined(); + expect(data.shotsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shotsFired).toEqualTypeOf(); + expect(data.weeklyKills).toBeDefined(); + expect(data.weeklyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKills).toEqualTypeOf(); + expect(data.weeklyKillsA).toBeDefined(); + expect(data.weeklyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsA).toEqualTypeOf(); + expect(data.weeklyKillsB).toBeDefined(); + expect(data.weeklyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsB).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/GalaxyWars.ts b/src/Structures/MiniGames/Arcade/GalaxyWars.ts new file mode 100644 index 000000000..5264b1c02 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/GalaxyWars.ts @@ -0,0 +1,32 @@ +import { monthAB, weekAB } from '../../../Utils/Oscillation.js'; + +class GalaxyWars { + deaths: number; + empireKills: number; + gameWins: number; + kills: number; + monthlyKills: number; + monthlyKillsA: number; + monthlyKillsB: number; + rebelKills: number; + shotsFired: number; + weeklyKills: number; + weeklyKillsA: number; + weeklyKillsB: number; + constructor(data: Record) { + this.deaths = data?.sw_deaths || 0; + this.empireKills = data?.sw_empire_kills || 0; + this.gameWins = data?.sw_game_wins || 0; + this.kills = data?.sw_kills || 0; + this.monthlyKills = parseInt(data?.[`sw_monthly_kills_${monthAB()}`] || 0, 10); + this.monthlyKillsA = data?.sw_monthly_kills_a || 0; + this.monthlyKillsB = data?.sw_monthly_kills_b || 0; + this.rebelKills = data?.sw_rebel_kills || 0; + this.shotsFired = data?.sw_shots_fired || 0; + this.weeklyKills = parseInt(data?.[`sw_weekly_kills_${weekAB()}`] || 0, 10); + this.weeklyKillsA = data?.sw_weekly_kills_a || 0; + this.weeklyKillsB = data?.sw_weekly_kills_b || 0; + } +} + +export default GalaxyWars; diff --git a/src/Structures/MiniGames/Arcade/GrinchSimulator.test.ts b/src/Structures/MiniGames/Arcade/GrinchSimulator.test.ts new file mode 100644 index 000000000..5aaad3f3b --- /dev/null +++ b/src/Structures/MiniGames/Arcade/GrinchSimulator.test.ts @@ -0,0 +1,33 @@ +import GrinchSimulator from './GrinchSimulator.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GrinchSimulator', () => { + const data = new GrinchSimulator({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GrinchSimulator); + expectTypeOf(data).toEqualTypeOf(); + expect(data.gifts).toBeDefined(); + expect(data.gifts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gifts).toEqualTypeOf(); + expect(data.giftsTourney).toBeDefined(); + expect(data.giftsTourney).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giftsTourney).toEqualTypeOf(); + expect(data.giftsTourneyGrinchSimulator1).toBeDefined(); + expect(data.giftsTourneyGrinchSimulator1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giftsTourneyGrinchSimulator1).toEqualTypeOf(); + expect(data.lossesTourney).toBeDefined(); + expect(data.lossesTourney).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lossesTourney).toEqualTypeOf(); + expect(data.lossesTourneyGrinchSimulator1).toBeDefined(); + expect(data.lossesTourneyGrinchSimulator1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lossesTourneyGrinchSimulator1).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.winsTourney).toBeDefined(); + expect(data.winsTourney).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsTourney).toEqualTypeOf(); + expect(data.winsTourneyGrinchSimulator1).toBeDefined(); + expect(data.winsTourneyGrinchSimulator1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsTourneyGrinchSimulator1).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/GrinchSimulator.ts b/src/Structures/MiniGames/Arcade/GrinchSimulator.ts new file mode 100644 index 000000000..7fa2f8ccb --- /dev/null +++ b/src/Structures/MiniGames/Arcade/GrinchSimulator.ts @@ -0,0 +1,22 @@ +class GrinchSimulator { + gifts: number; + giftsTourney: number; + giftsTourneyGrinchSimulator1: number; + lossesTourney: number; + lossesTourneyGrinchSimulator1: number; + wins: number; + winsTourney: number; + winsTourneyGrinchSimulator1: number; + constructor(data: Record) { + this.gifts = data?.gifts_grinch_simulator_v2 || 0; + this.giftsTourney = data?.gifts_grinch_simulator_v2_tourney || 0; + this.giftsTourneyGrinchSimulator1 = data?.gifts_grinch_simulator_v2_tourney_grinch_simulator_1 || 0; + this.lossesTourney = data?.losses_grinch_simulator_v2_tourney || 0; + this.lossesTourneyGrinchSimulator1 = data?.losses_grinch_simulator_v2_tourney_grinch_simulator_1 || 0; + this.wins = data?.wins_grinch_simulator_v2 || 0; + this.winsTourney = data?.wins_grinch_simulator_v2_tourney || 0; + this.winsTourneyGrinchSimulator1 = data?.wins_grinch_simulator_v2_tourney_grinch_simulator_1 || 0; + } +} + +export default GrinchSimulator; diff --git a/src/Structures/MiniGames/Arcade/HalloweenSimulator.test.ts b/src/Structures/MiniGames/Arcade/HalloweenSimulator.test.ts new file mode 100644 index 000000000..4da551cff --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HalloweenSimulator.test.ts @@ -0,0 +1,15 @@ +import HalloweenSimulator from './HalloweenSimulator.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('HalloweenSimulator', () => { + const data = new HalloweenSimulator({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(HalloweenSimulator); + expectTypeOf(data).toEqualTypeOf(); + expect(data.candyFound).toBeDefined(); + expect(data.candyFound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candyFound).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/HalloweenSimulator.ts b/src/Structures/MiniGames/Arcade/HalloweenSimulator.ts new file mode 100644 index 000000000..831c25a4f --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HalloweenSimulator.ts @@ -0,0 +1,10 @@ +class HalloweenSimulator { + candyFound: number; + wins: number; + constructor(data: Record) { + this.candyFound = data?.candy_found_halloween_simulator || 0; + this.wins = data?.wins_halloween_simulator || 0; + } +} + +export default HalloweenSimulator; diff --git a/src/Structures/MiniGames/Arcade/HideAndSeek.test.ts b/src/Structures/MiniGames/Arcade/HideAndSeek.test.ts new file mode 100644 index 000000000..c6d57fdc1 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HideAndSeek.test.ts @@ -0,0 +1,27 @@ +import HideAndSeek from './HideAndSeek.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('HideAndSeek', () => { + const data = new HideAndSeek({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(HideAndSeek); + expectTypeOf(data).toEqualTypeOf(); + expect(data.hiderWins).toBeDefined(); + expect(data.hiderWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hiderWins).toEqualTypeOf(); + expect(data.partyPooperHiderWins).toBeDefined(); + expect(data.partyPooperHiderWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.partyPooperHiderWins).toEqualTypeOf(); + expect(data.partyPooperSeekerWins).toBeDefined(); + expect(data.partyPooperSeekerWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.partyPooperSeekerWins).toEqualTypeOf(); + expect(data.propHuntHiderWins).toBeDefined(); + expect(data.propHuntHiderWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.propHuntHiderWins).toEqualTypeOf(); + expect(data.propHuntSeekerWins).toBeDefined(); + expect(data.propHuntSeekerWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.propHuntSeekerWins).toEqualTypeOf(); + expect(data.seekerWins).toBeDefined(); + expect(data.seekerWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.seekerWins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/HideAndSeek.ts b/src/Structures/MiniGames/Arcade/HideAndSeek.ts new file mode 100644 index 000000000..303d7daf1 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HideAndSeek.ts @@ -0,0 +1,18 @@ +class HideAndSeek { + hiderWins: number; + partyPooperHiderWins: number; + partyPooperSeekerWins: number; + propHuntHiderWins: number; + propHuntSeekerWins: number; + seekerWins: number; + constructor(data: Record) { + this.hiderWins = data?.hider_wins_hide_and_seek || 0; + this.partyPooperHiderWins = data?.party_pooper_hider_wins_hide_and_seek || 0; + this.partyPooperSeekerWins = data?.party_pooper_seeker_wins_hide_and_seek || 0; + this.propHuntHiderWins = data?.prop_hunt_hider_wins_hide_and_seek || 0; + this.propHuntSeekerWins = data?.prop_hunt_seeker_wins_hide_and_seek || 0; + this.seekerWins = data?.seeker_wins_hide_and_seek || 0; + } +} + +export default HideAndSeek; diff --git a/src/Structures/MiniGames/Arcade/HoleInTheWall.test.ts b/src/Structures/MiniGames/Arcade/HoleInTheWall.test.ts new file mode 100644 index 000000000..f0228654c --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HoleInTheWall.test.ts @@ -0,0 +1,24 @@ +import HoleInTheWall from './HoleInTheWall.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ArcadeHoleInTheWallColor } from '../../../Types/Player.js'; + +test('HoleInTheWall', () => { + const data = new HoleInTheWall({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(HoleInTheWall); + expectTypeOf(data).toEqualTypeOf(); + expect(data.rounds).toBeDefined(); + expect(data.rounds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rounds).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.color).toBeDefined(); + expectTypeOf(data.color).toEqualTypeOf(); + expect(data.recordF).toBeDefined(); + expect(data.recordF).toBeGreaterThanOrEqual(0); + expectTypeOf(data.recordF).toEqualTypeOf(); + expect(data.recordQ).toBeDefined(); + expect(data.recordQ).toBeGreaterThanOrEqual(0); + expectTypeOf(data.recordQ).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/HoleInTheWall.ts b/src/Structures/MiniGames/Arcade/HoleInTheWall.ts new file mode 100644 index 000000000..64759d124 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HoleInTheWall.ts @@ -0,0 +1,18 @@ +import type { ArcadeHoleInTheWallColor } from '../../../Types/Player.js'; + +class HoleInTheWall { + rounds: number; + wins: number; + color: ArcadeHoleInTheWallColor; + recordF: number; + recordQ: number; + constructor(data: Record) { + this.rounds = data?.rounds_hole_in_the_wall || 0; + this.wins = data?.wins_hole_in_the_wall || 0; + this.color = data?.hitw_color || 'DEFAULT'; + this.recordF = data?.hitw_record_f || 0; + this.recordQ = data?.hitw_record_q || 0; + } +} + +export default HoleInTheWall; diff --git a/src/Structures/MiniGames/Arcade/HypixelSports.test.ts b/src/Structures/MiniGames/Arcade/HypixelSports.test.ts new file mode 100644 index 000000000..c00488298 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HypixelSports.test.ts @@ -0,0 +1,12 @@ +import HypixelSports from './HypixelSports.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('HypixelSports', () => { + const data = new HypixelSports({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(HypixelSports); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/HypixelSports.ts b/src/Structures/MiniGames/Arcade/HypixelSports.ts new file mode 100644 index 000000000..a78020b54 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/HypixelSports.ts @@ -0,0 +1,8 @@ +class HypixelSports { + wins: number; + constructor(data: Record) { + this.wins = data?.wins_hypixel_sports || 0; + } +} + +export default HypixelSports; diff --git a/src/Structures/MiniGames/Arcade/MiniWalls.test.ts b/src/Structures/MiniGames/Arcade/MiniWalls.test.ts new file mode 100644 index 000000000..a58bfc1c2 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/MiniWalls.test.ts @@ -0,0 +1,59 @@ +import MiniWalls from './MiniWalls.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MiniWalls', () => { + const data = new MiniWalls({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MiniWalls); + expectTypeOf(data).toEqualTypeOf(); + expect(data.arrowsHit).toBeDefined(); + expect(data.arrowsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsHit).toEqualTypeOf(); + expect(data.arrowsHitTourney0).toBeDefined(); + expect(data.arrowsHitTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsHitTourney0).toEqualTypeOf(); + expect(data.arrowsShot).toBeDefined(); + expect(data.arrowsShot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsShot).toEqualTypeOf(); + expect(data.arrowsShotTourney0).toBeDefined(); + expect(data.arrowsShotTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsShotTourney0).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.deathsTourney0).toBeDefined(); + expect(data.deathsTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsTourney0).toEqualTypeOf(); + expect(data.finalKills).toBeDefined(); + expect(data.finalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalKills).toEqualTypeOf(); + expect(data.finalKillsTourney0).toBeDefined(); + expect(data.finalKillsTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalKillsTourney0).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.killsTourney0).toBeDefined(); + expect(data.killsTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsTourney0).toEqualTypeOf(); + expect(data.inventoryLayout).toBeDefined(); + expectTypeOf(data.inventoryLayout).toEqualTypeOf>(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.winsTourney0).toBeDefined(); + expect(data.winsTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsTourney0).toEqualTypeOf(); + expect(data.witherDamage).toBeDefined(); + expect(data.witherDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherDamage).toEqualTypeOf(); + expect(data.witherDamageTourney0).toBeDefined(); + expect(data.witherDamageTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherDamageTourney0).toEqualTypeOf(); + expect(data.witherKills).toBeDefined(); + expect(data.witherKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherKills).toEqualTypeOf(); + expect(data.witherKillsTourney0).toBeDefined(); + expect(data.witherKillsTourney0).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherKillsTourney0).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/MiniWalls.ts b/src/Structures/MiniGames/Arcade/MiniWalls.ts new file mode 100644 index 000000000..66b87802b --- /dev/null +++ b/src/Structures/MiniGames/Arcade/MiniWalls.ts @@ -0,0 +1,40 @@ +class MiniWalls { + arrowsHit: number; + arrowsHitTourney0: number; + arrowsShot: number; + arrowsShotTourney0: number; + deaths: number; + deathsTourney0: number; + finalKills: number; + finalKillsTourney0: number; + kills: number; + killsTourney0: number; + inventoryLayout: Record; + wins: number; + winsTourney0: number; + witherDamage: number; + witherDamageTourney0: number; + witherKills: number; + witherKillsTourney0: number; + constructor(data: Record) { + this.arrowsHit = data?.arrows_hit_mini_walls || 0; + this.arrowsHitTourney0 = data?.arrows_hit_tourney_mini_walls_0 || 0; + this.arrowsShot = data?.arrows_shot_mini_walls || 0; + this.arrowsShotTourney0 = data?.arrows_shot_tourney_mini_walls_0 || 0; + this.deaths = data?.deaths_mini_walls || 0; + this.deathsTourney0 = data?.deaths_tourney_mini_walls_0 || 0; + this.finalKills = data?.final_kills_mini_walls || 0; + this.finalKillsTourney0 = data?.final_kills_tourney_mini_walls_0 || 0; + this.kills = data?.kills_mini_walls || 0; + this.killsTourney0 = data?.kills_tourney_mini_walls_0 || 0; + this.inventoryLayout = data?.mini_walls_inventory_layout || {}; + this.wins = data?.wins_mini_walls || 0; + this.winsTourney0 = data?.wins_tourney_mini_walls_0 || 0; + this.witherDamage = data?.wither_damage_mini_walls || 0; + this.witherDamageTourney0 = data?.wither_damage_tourney_mini_walls_0 || 0; + this.witherKills = data?.wither_kills_mini_walls || 0; + this.witherKillsTourney0 = data?.wither_kills_tourney_mini_walls_0 || 0; + } +} + +export default MiniWalls; diff --git a/src/Structures/MiniGames/Arcade/OneInTheQuiver.test.ts b/src/Structures/MiniGames/Arcade/OneInTheQuiver.test.ts new file mode 100644 index 000000000..7266b9d2a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/OneInTheQuiver.test.ts @@ -0,0 +1,27 @@ +import OneInTheQuiver from './OneInTheQuiver.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('OneInTheQuiver', () => { + const data = new OneInTheQuiver({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(OneInTheQuiver); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bountyKills).toBeDefined(); + expect(data.bountyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bountyKills).toEqualTypeOf(); + expect(data.bowKills).toBeDefined(); + expect(data.bowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowKills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.swordKills).toBeDefined(); + expect(data.swordKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swordKills).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/OneInTheQuiver.ts b/src/Structures/MiniGames/Arcade/OneInTheQuiver.ts new file mode 100644 index 000000000..4715c0890 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/OneInTheQuiver.ts @@ -0,0 +1,18 @@ +class OneInTheQuiver { + bountyKills: number; + bowKills: number; + deaths: number; + kills: number; + swordKills: number; + wins: number; + constructor(data: Record) { + this.bountyKills = data?.bounty_kills_oneinthequiver || 0; + this.bowKills = data?.bow_kills_oneinthequiver || 0; + this.deaths = data?.deaths_oneinthequiver || 0; + this.kills = data?.kills_oneinthequiver || 0; + this.swordKills = data?.sword_kills_oneinthequiver || 0; + this.wins = data?.wins_oneinthequiver || 0; + } +} + +export default OneInTheQuiver; diff --git a/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.test.ts b/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.test.ts new file mode 100644 index 000000000..6010da68a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.test.ts @@ -0,0 +1,9 @@ +import LawnMoower from './LawnMoower.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('LawnMoower', () => { + const data = new LawnMoower({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(LawnMoower); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.ts b/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.ts new file mode 100644 index 000000000..cd56af347 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/LawnMoower.ts @@ -0,0 +1,11 @@ +import PartyGamesGame from './PartyGamesGame.js'; + +class LawnMoower extends PartyGamesGame { + constructor(data: Record) { + super(data, 'lawn_moower'); + this.bestScore = data?.lawn_moower_mowed_best_score_party || 0; + this.totalScore = data?.lawn_moower_mowed_total_score_party || 0; + } +} + +export default LawnMoower; diff --git a/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.test.ts b/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.test.ts new file mode 100644 index 000000000..d23aca4ef --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.test.ts @@ -0,0 +1,90 @@ +import LawnMoower from './LawnMoower.js'; +import PartyGames from './PartyGames.js'; +import PartyGamesGame from './PartyGamesGame.js'; +import RPG16 from './RPG16.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PartyGames', () => { + const data = new PartyGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PartyGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.animalSlaughter).toBeDefined(); + expect(data.animalSlaughter).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.animalSlaughter).toEqualTypeOf(); + expect(data.anvilSpleef).toBeDefined(); + expect(data.anvilSpleef).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.anvilSpleef).toEqualTypeOf(); + expect(data.avalanche).toBeDefined(); + expect(data.avalanche).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.avalanche).toEqualTypeOf(); + expect(data.bombardment).toBeDefined(); + expect(data.bombardment).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.bombardment).toEqualTypeOf(); + expect(data.cannonPainting).toBeDefined(); + expect(data.cannonPainting).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.cannonPainting).toEqualTypeOf(); + expect(data.chickenRings).toBeDefined(); + expect(data.chickenRings).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.chickenRings).toEqualTypeOf(); + expect(data.dive).toBeDefined(); + expect(data.dive).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.dive).toEqualTypeOf(); + expect(data.fireLeapers).toBeDefined(); + expect(data.fireLeapers).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.fireLeapers).toEqualTypeOf(); + expect(data.frozenFloor).toBeDefined(); + expect(data.frozenFloor).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.frozenFloor).toEqualTypeOf(); + expect(data.highGround).toBeDefined(); + expect(data.highGround).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.highGround).toEqualTypeOf(); + expect(data.hoeHoeHoe).toBeDefined(); + expect(data.hoeHoeHoe).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.hoeHoeHoe).toEqualTypeOf(); + expect(data.jigsawRush).toBeDefined(); + expect(data.jigsawRush).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.jigsawRush).toEqualTypeOf(); + expect(data.jungleJump).toBeDefined(); + expect(data.jungleJump).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.jungleJump).toEqualTypeOf(); + expect(data.labEscape).toBeDefined(); + expect(data.labEscape).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.labEscape).toEqualTypeOf(); + expect(data.lawnMoower).toBeDefined(); + expect(data.lawnMoower).toBeInstanceOf(LawnMoower); + expectTypeOf(data.lawnMoower).toEqualTypeOf(); + expect(data.minecartRacing).toBeDefined(); + expect(data.minecartRacing).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.minecartRacing).toEqualTypeOf(); + expect(data.pigFishing).toBeDefined(); + expect(data.pigFishing).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.pigFishing).toEqualTypeOf(); + expect(data.pigJousting).toBeDefined(); + expect(data.pigJousting).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.pigJousting).toEqualTypeOf(); + expect(data.rpg16).toBeDefined(); + expect(data.rpg16).toBeInstanceOf(RPG16); + expectTypeOf(data.rpg16).toEqualTypeOf(); + expect(data.shootingRange).toBeDefined(); + expect(data.shootingRange).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.shootingRange).toEqualTypeOf(); + expect(data.spiderMaze).toBeDefined(); + expect(data.spiderMaze).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.spiderMaze).toEqualTypeOf(); + expect(data.superSheep).toBeDefined(); + expect(data.superSheep).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.superSheep).toEqualTypeOf(); + expect(data.theFloorIsLava).toBeDefined(); + expect(data.theFloorIsLava).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.theFloorIsLava).toEqualTypeOf(); + expect(data.trampolinio).toBeDefined(); + expect(data.trampolinio).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.trampolinio).toEqualTypeOf(); + expect(data.volcano).toBeDefined(); + expect(data.volcano).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.volcano).toEqualTypeOf(); + expect(data.workshop).toBeDefined(); + expect(data.workshop).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data.workshop).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.ts b/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.ts new file mode 100644 index 000000000..abd3d0824 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/PartyGames.ts @@ -0,0 +1,62 @@ +import LawnMoower from './LawnMoower.js'; +import PartyGamesGame from './PartyGamesGame.js'; +import RPG16 from './RPG16.js'; + +class PartyGames { + animalSlaughter: PartyGamesGame; + anvilSpleef: PartyGamesGame; + avalanche: PartyGamesGame; + bombardment: PartyGamesGame; + cannonPainting: PartyGamesGame; + chickenRings: PartyGamesGame; + dive: PartyGamesGame; + fireLeapers: PartyGamesGame; + frozenFloor: PartyGamesGame; + highGround: PartyGamesGame; + hoeHoeHoe: PartyGamesGame; + jigsawRush: PartyGamesGame; + jungleJump: PartyGamesGame; + labEscape: PartyGamesGame; + lawnMoower: LawnMoower; + minecartRacing: PartyGamesGame; + pigFishing: PartyGamesGame; + pigJousting: PartyGamesGame; + rpg16: RPG16; + shootingRange: PartyGamesGame; + spiderMaze: PartyGamesGame; + superSheep: PartyGamesGame; + theFloorIsLava: PartyGamesGame; + trampolinio: PartyGamesGame; + volcano: PartyGamesGame; + workshop: PartyGamesGame; + constructor(data: Record) { + this.animalSlaughter = new PartyGamesGame(data, 'animal_slaughter'); + this.anvilSpleef = new PartyGamesGame(data, 'anvil_spleef'); + this.avalanche = new PartyGamesGame(data, 'avalanche'); + this.bombardment = new PartyGamesGame(data, 'bombardment'); + this.cannonPainting = new PartyGamesGame(data, 'cannon_painting'); + this.chickenRings = new PartyGamesGame(data, 'chicken_rings'); + this.dive = new PartyGamesGame(data, 'dive'); + this.fireLeapers = new PartyGamesGame(data, 'fire_leapers'); + this.frozenFloor = new PartyGamesGame(data, 'frozen_floor'); + this.highGround = new PartyGamesGame(data, 'high_ground'); + this.hoeHoeHoe = new PartyGamesGame(data, 'hoe_hoe_hoe'); + this.jigsawRush = new PartyGamesGame(data, 'jigsaw_rush'); + this.jungleJump = new PartyGamesGame(data, 'jungle_jump'); + this.labEscape = new PartyGamesGame(data, 'lab_escape'); + this.lawnMoower = new LawnMoower(data); + this.minecartRacing = new PartyGamesGame(data, 'minecart_racing'); + this.pigFishing = new PartyGamesGame(data, 'pig_fishing'); + this.pigJousting = new PartyGamesGame(data, 'pig_jousting'); + this.rpg16 = new RPG16(data); + this.shootingRange = new PartyGamesGame(data, 'shooting_range'); + this.spiderMaze = new PartyGamesGame(data, 'spider_maze'); + this.superSheep = new PartyGamesGame(data, 'super_sheep'); + this.theFloorIsLava = new PartyGamesGame(data, 'the_floor_is_lava'); + this.trampolinio = new PartyGamesGame(data, 'trampolinio'); + this.volcano = new PartyGamesGame(data, 'volcano'); + this.workshop = new PartyGamesGame(data, 'workshop'); + } +} + +export default PartyGames; diff --git a/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.test.ts b/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.test.ts new file mode 100644 index 000000000..36a9c3d22 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.test.ts @@ -0,0 +1,24 @@ +import PartyGamesGame from './PartyGamesGame.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PartyGamesGame', () => { + const data = new PartyGamesGame({ stats: 'meow' }, 'animal_slaughter'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PartyGamesGame); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestScore).toBeDefined(); + expect(data.bestScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestScore).toEqualTypeOf(); + expect(data.bestTime).toBeDefined(); + expect(data.bestTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestTime).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.roundWins).toBeDefined(); + expect(data.roundWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.roundWins).toEqualTypeOf(); + expect(data.totalScore).toBeDefined(); + expect(data.totalScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalScore).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.ts b/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.ts new file mode 100644 index 000000000..5e012a655 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.ts @@ -0,0 +1,18 @@ +import type { ArcadePartyGamesGame } from '../../../../Types/Player.js'; + +class PartyGamesGame { + bestScore: number; + bestTime: number; + kills: number; + roundWins: number; + totalScore: number; + constructor(data: Record, game: ArcadePartyGamesGame) { + this.bestScore = data?.[`${game}_best_score_party`] || 0; + this.bestTime = data?.[`${game}_best_time_party`] || 0; + this.kills = data?.[`${game}_kills_party`] || 0; + this.roundWins = data?.[`${game}_round_wins_party`] || 0; + this.totalScore = data?.[`${game}_total_score_party`] || 0; + } +} + +export default PartyGamesGame; diff --git a/src/Structures/MiniGames/Arcade/PartyGames/RPG16.test.ts b/src/Structures/MiniGames/Arcade/PartyGames/RPG16.test.ts new file mode 100644 index 000000000..15b5a3d35 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/RPG16.test.ts @@ -0,0 +1,9 @@ +import RPG16 from './RPG16.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('RPG16', () => { + const data = new RPG16({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RPG16); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/PartyGames/RPG16.ts b/src/Structures/MiniGames/Arcade/PartyGames/RPG16.ts new file mode 100644 index 000000000..c1bc2978a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/PartyGames/RPG16.ts @@ -0,0 +1,10 @@ +import PartyGamesGame from './PartyGamesGame.js'; + +class RPG16 extends PartyGamesGame { + constructor(data: Record) { + super(data, 'rpg_16'); + this.bestScore = data?.rpg_16_kills_best_score_party || 0; + } +} + +export default RPG16; diff --git a/src/Structures/MiniGames/Arcade/SantaSays.test.ts b/src/Structures/MiniGames/Arcade/SantaSays.test.ts new file mode 100644 index 000000000..9bee95aaf --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SantaSays.test.ts @@ -0,0 +1,21 @@ +import SantaSays from './SantaSays.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SantaSays', () => { + const data = new SantaSays({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SantaSays); + expectTypeOf(data).toEqualTypeOf(); + expect(data.roundWins).toBeDefined(); + expect(data.roundWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.roundWins).toEqualTypeOf(); + expect(data.rounds).toBeDefined(); + expect(data.rounds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rounds).toEqualTypeOf(); + expect(data.topScore).toBeDefined(); + expect(data.topScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.topScore).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/SantaSays.ts b/src/Structures/MiniGames/Arcade/SantaSays.ts new file mode 100644 index 000000000..1639baf28 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SantaSays.ts @@ -0,0 +1,14 @@ +class SantaSays { + roundWins: number; + rounds: number; + topScore: number; + wins: number; + constructor(data: Record) { + this.roundWins = data?.round_wins_santa_says || 0; + this.rounds = data?.rounds_santa_says || 0; + this.topScore = data?.top_score_santa_says || 0; + this.wins = data?.wins_santa_says || 0; + } +} + +export default SantaSays; diff --git a/src/Structures/MiniGames/Arcade/SantaSimulator.test.ts b/src/Structures/MiniGames/Arcade/SantaSimulator.test.ts new file mode 100644 index 000000000..94a4d4c98 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SantaSimulator.test.ts @@ -0,0 +1,18 @@ +import SantaSimulator from './SantaSimulator.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SantaSimulator', () => { + const data = new SantaSimulator({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SantaSimulator); + expectTypeOf(data).toEqualTypeOf(); + expect(data.delivered).toBeDefined(); + expect(data.delivered).toBeGreaterThanOrEqual(0); + expectTypeOf(data.delivered).toEqualTypeOf(); + expect(data.spotted).toBeDefined(); + expect(data.spotted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spotted).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/SantaSimulator.ts b/src/Structures/MiniGames/Arcade/SantaSimulator.ts new file mode 100644 index 000000000..d4d93abac --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SantaSimulator.ts @@ -0,0 +1,12 @@ +class SantaSimulator { + delivered: number; + spotted: number; + wins: number; + constructor(data: Record) { + this.delivered = data?.delivered_santa_simulator || 0; + this.spotted = data?.spotted_santa_simulator || 0; + this.wins = data?.wins_santa_simulator || 0; + } +} + +export default SantaSimulator; diff --git a/src/Structures/MiniGames/Arcade/ScubaSimulator.test.ts b/src/Structures/MiniGames/Arcade/ScubaSimulator.test.ts new file mode 100644 index 000000000..9a05cc4c8 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ScubaSimulator.test.ts @@ -0,0 +1,18 @@ +import ScubaSimulator from './ScubaSimulator.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ScubaSimulator', () => { + const data = new ScubaSimulator({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ScubaSimulator); + expectTypeOf(data).toEqualTypeOf(); + expect(data.itemsFound).toBeDefined(); + expect(data.itemsFound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemsFound).toEqualTypeOf(); + expect(data.totalPoints).toBeDefined(); + expect(data.totalPoints).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalPoints).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/ScubaSimulator.ts b/src/Structures/MiniGames/Arcade/ScubaSimulator.ts new file mode 100644 index 000000000..28a23944e --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ScubaSimulator.ts @@ -0,0 +1,12 @@ +class ScubaSimulator { + itemsFound: number; + totalPoints: number; + wins: number; + constructor(data: Record) { + this.itemsFound = data?.items_found_scuba_simulator || 0; + this.totalPoints = data?.total_points_scuba_simulator || 0; + this.wins = data?.wins_scuba_simulator || 0; + } +} + +export default ScubaSimulator; diff --git a/src/Structures/MiniGames/Arcade/SimonSays.test.ts b/src/Structures/MiniGames/Arcade/SimonSays.test.ts new file mode 100644 index 000000000..9149b5f5f --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SimonSays.test.ts @@ -0,0 +1,21 @@ +import SimonSays from './SimonSays.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SimonSays', () => { + const data = new SimonSays({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SimonSays); + expectTypeOf(data).toEqualTypeOf(); + expect(data.roundWins).toBeDefined(); + expect(data.roundWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.roundWins).toEqualTypeOf(); + expect(data.rounds).toBeDefined(); + expect(data.rounds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rounds).toEqualTypeOf(); + expect(data.topScore).toBeDefined(); + expect(data.topScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.topScore).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/SimonSays.ts b/src/Structures/MiniGames/Arcade/SimonSays.ts new file mode 100644 index 000000000..ef2216e18 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/SimonSays.ts @@ -0,0 +1,14 @@ +class SimonSays { + roundWins: number; + rounds: number; + topScore: number; + wins: number; + constructor(data: Record) { + this.roundWins = data?.round_wins_simon_says || 0; + this.rounds = data?.rounds_simon_says || 0; + this.topScore = data?.top_score_simon_says || 0; + this.wins = data?.wins_simon_says || 0; + } +} + +export default SimonSays; diff --git a/src/Structures/MiniGames/Arcade/Soccer.test.ts b/src/Structures/MiniGames/Arcade/Soccer.test.ts new file mode 100644 index 000000000..e8791af16 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Soccer.test.ts @@ -0,0 +1,21 @@ +import Soccer from './Soccer.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Soccer', () => { + const data = new Soccer({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Soccer); + expectTypeOf(data).toEqualTypeOf(); + expect(data.goals).toBeDefined(); + expect(data.goals).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goals).toEqualTypeOf(); + expect(data.kicks).toBeDefined(); + expect(data.kicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kicks).toEqualTypeOf(); + expect(data.powerkicks).toBeDefined(); + expect(data.powerkicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powerkicks).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Soccer.ts b/src/Structures/MiniGames/Arcade/Soccer.ts new file mode 100644 index 000000000..8051a91f5 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Soccer.ts @@ -0,0 +1,14 @@ +class Soccer { + goals: number; + kicks: number; + powerkicks: number; + wins: number; + constructor(data: Record) { + this.goals = data?.goals_soccer || 0; + this.kicks = data?.kicks_soccer || 0; + this.powerkicks = data?.powerkicks_soccer || 0; + this.wins = data?.wins_soccer || 0; + } +} + +export default Soccer; diff --git a/src/Structures/MiniGames/Arcade/ThrowOut.test.ts b/src/Structures/MiniGames/Arcade/ThrowOut.test.ts new file mode 100644 index 000000000..ba9305486 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ThrowOut.test.ts @@ -0,0 +1,21 @@ +import ThrowOut from './ThrowOut.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ArcadeThrowOutDisguise } from '../../../Types/Player.js'; + +test('ThrowOut', () => { + const data = new ThrowOut({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ThrowOut); + expectTypeOf(data).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.disguise).toBeDefined(); + expectTypeOf(data.disguise).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/ThrowOut.ts b/src/Structures/MiniGames/Arcade/ThrowOut.ts new file mode 100644 index 000000000..a3d68a523 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/ThrowOut.ts @@ -0,0 +1,16 @@ +import type { ArcadeThrowOutDisguise } from '../../../Types/Player.js'; + +class ThrowOut { + deaths: number; + kills: number; + wins: number; + disguise: ArcadeThrowOutDisguise | 'UNKNOWN'; + constructor(data: Record) { + this.deaths = data?.deaths_throw_out || 0; + this.kills = data?.kills_throw_out || 0; + this.wins = data?.wins_throw_out || 0; + this.disguise = data?.throwout_disguise || 'UNKNOWN'; + } +} + +export default ThrowOut; diff --git a/src/Structures/MiniGames/Arcade/WoolHunt.test.ts b/src/Structures/MiniGames/Arcade/WoolHunt.test.ts new file mode 100644 index 000000000..0d6ee7a92 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/WoolHunt.test.ts @@ -0,0 +1,77 @@ +import WoolHunt from './WoolHunt.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('WoolHunt', () => { + const data = new WoolHunt({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WoolHunt); + expectTypeOf(data).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.deathsToWoolholder).toBeDefined(); + expect(data.deathsToWoolholder).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsToWoolholder).toEqualTypeOf(); + expect(data.deathsWithWool).toBeDefined(); + expect(data.deathsWithWool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsWithWool).toEqualTypeOf(); + expect(data.experiencedDraws).toBeDefined(); + expect(data.experiencedDraws).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experiencedDraws).toEqualTypeOf(); + expect(data.experiencedLosses).toBeDefined(); + expect(data.experiencedLosses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experiencedLosses).toEqualTypeOf(); + expect(data.experiencedWins).toBeDefined(); + expect(data.experiencedWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experiencedWins).toEqualTypeOf(); + expect(data.fastestWin).toBeDefined(); + expect(data.fastestWin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestWin).toEqualTypeOf(); + expect(data.fastestWoolCapture).toBeDefined(); + expect(data.fastestWoolCapture).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestWoolCapture).toEqualTypeOf(); + expect(data.goldEarned).toBeDefined(); + expect(data.goldEarned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldEarned).toEqualTypeOf(); + expect(data.goldSpent).toBeDefined(); + expect(data.goldSpent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldSpent).toEqualTypeOf(); + expect(data.inventorylayout).toBeDefined(); + expectTypeOf(data.inventorylayout).toEqualTypeOf>(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.killsOnWoolholder).toBeDefined(); + expect(data.killsOnWoolholder).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsOnWoolholder).toEqualTypeOf(); + expect(data.killsWithWool).toBeDefined(); + expect(data.killsWithWool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsWithWool).toEqualTypeOf(); + expect(data.longestGame).toBeDefined(); + expect(data.longestGame).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestGame).toEqualTypeOf(); + expect(data.mostGoldEarned).toBeDefined(); + expect(data.mostGoldEarned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostGoldEarned).toEqualTypeOf(); + expect(data.mostKillsAndAssists).toBeDefined(); + expect(data.mostKillsAndAssists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostKillsAndAssists).toEqualTypeOf(); + expect(data.participatedDraws).toBeDefined(); + expect(data.participatedDraws).toBeGreaterThanOrEqual(0); + expectTypeOf(data.participatedDraws).toEqualTypeOf(); + expect(data.participatedLosses).toBeDefined(); + expect(data.participatedLosses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.participatedLosses).toEqualTypeOf(); + expect(data.participatedWins).toBeDefined(); + expect(data.participatedWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.participatedWins).toEqualTypeOf(); + expect(data.woolsCaptured).toBeDefined(); + expect(data.woolsCaptured).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolsCaptured).toEqualTypeOf(); + expect(data.woolsStolen).toBeDefined(); + expect(data.woolsStolen).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolsStolen).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/WoolHunt.ts b/src/Structures/MiniGames/Arcade/WoolHunt.ts new file mode 100644 index 000000000..bcc2943b3 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/WoolHunt.ts @@ -0,0 +1,52 @@ +class WoolHunt { + assists: number; + deaths: number; + deathsToWoolholder: number; + deathsWithWool: number; + experiencedDraws: number; + experiencedLosses: number; + experiencedWins: number; + fastestWin: number; + fastestWoolCapture: number; + goldEarned: number; + goldSpent: number; + inventorylayout: Record; + kills: number; + killsOnWoolholder: number; + killsWithWool: number; + longestGame: number; + mostGoldEarned: number; + mostKillsAndAssists: number; + participatedDraws: number; + participatedLosses: number; + participatedWins: number; + woolsCaptured: number; + woolsStolen: number; + constructor(data: Record) { + this.assists = data?.woolhunt_assists || 0; + this.deaths = data?.woolhunt_deaths || 0; + this.deathsToWoolholder = data?.woolhunt_deaths_to_woolholder || 0; + this.deathsWithWool = data?.woolhunt_deaths_with_wool || 0; + this.experiencedDraws = data?.woolhunt_experienced_draws || 0; + this.experiencedLosses = data?.woolhunt_experienced_losses || 0; + this.experiencedWins = data?.woolhunt_experienced_wins || 0; + this.fastestWin = data?.woolhunt_fastest_win || 0; + this.fastestWoolCapture = data?.woolhunt_fastest_wool_capture || 0; + this.goldEarned = data?.woolhunt_gold_earned || 0; + this.goldSpent = data?.woolhunt_gold_spent || 0; + this.inventorylayout = data?.woolhunt_inventorylayout || {}; + this.kills = data?.woolhunt_kills || 0; + this.killsOnWoolholder = data?.woolhunt_kills_on_woolholder || 0; + this.killsWithWool = data?.woolhunt_kills_with_wool || 0; + this.longestGame = data?.woolhunt_longest_game || 0; + this.mostGoldEarned = data?.woolhunt_most_gold_earned || 0; + this.mostKillsAndAssists = data?.woolhunt_most_kills_and_assists || 0; + this.participatedDraws = data?.woolhunt_participated_draws || 0; + this.participatedLosses = data?.woolhunt_participated_losses || 0; + this.participatedWins = data?.woolhunt_participated_wins || 0; + this.woolsCaptured = data?.woolhunt_wools_captured || 0; + this.woolsStolen = data?.woolhunt_wools_stolen || 0; + } +} + +export default WoolHunt; diff --git a/src/Structures/MiniGames/Arcade/Zombies/Zombies.test.ts b/src/Structures/MiniGames/Arcade/Zombies/Zombies.test.ts new file mode 100644 index 000000000..960e08c0a --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/Zombies.test.ts @@ -0,0 +1,351 @@ +import Zombies from './Zombies.js'; +import ZombiesMap from './ZombiesMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Zombies', () => { + const data = new Zombies({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Zombies); + expectTypeOf(data).toEqualTypeOf(); + expect(data.basicZombieKills).toBeDefined(); + expect(data.basicZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.basicZombieKills).toEqualTypeOf(); + expect(data.basketballZombieKills).toBeDefined(); + expect(data.basketballZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.basketballZombieKills).toEqualTypeOf(); + expect(data.bestRound).toBeDefined(); + expect(data.bestRound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestRound).toEqualTypeOf(); + expect(data.blazeZombieKills).toBeDefined(); + expect(data.blazeZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blazeZombieKills).toEqualTypeOf(); + expect(data.blobZombieKills).toBeDefined(); + expect(data.blobZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blobZombieKills).toEqualTypeOf(); + expect(data.bombZombieKills).toBeDefined(); + expect(data.bombZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bombZombieKills).toEqualTypeOf(); + expect(data.broodmotherZombieKills).toBeDefined(); + expect(data.broodmotherZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.broodmotherZombieKills).toEqualTypeOf(); + expect(data.bulletsHit).toBeDefined(); + expect(data.bulletsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bulletsHit).toEqualTypeOf(); + expect(data.bulletsShot).toBeDefined(); + expect(data.bulletsShot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bulletsShot).toEqualTypeOf(); + expect(data.caveSpiderZombieKills).toBeDefined(); + expect(data.caveSpiderZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.caveSpiderZombieKills).toEqualTypeOf(); + expect(data.chargedCreeperZombieKills).toBeDefined(); + expect(data.chargedCreeperZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chargedCreeperZombieKills).toEqualTypeOf(); + expect(data.chglugluZombieKills).toBeDefined(); + expect(data.chglugluZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chglugluZombieKills).toEqualTypeOf(); + expect(data.clownZombieKills).toBeDefined(); + expect(data.clownZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.clownZombieKills).toEqualTypeOf(); + expect(data.corruptedPigmanZombieKills).toBeDefined(); + expect(data.corruptedPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.corruptedPigmanZombieKills).toEqualTypeOf(); + expect(data.creeperZombieKills).toBeDefined(); + expect(data.creeperZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.creeperZombieKills).toEqualTypeOf(); + expect(data.daBombZombieKills).toBeDefined(); + expect(data.daBombZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.daBombZombieKills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.doorsOpened).toBeDefined(); + expect(data.doorsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doorsOpened).toEqualTypeOf(); + expect(data.drownedZombieKills).toBeDefined(); + expect(data.drownedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.drownedZombieKills).toEqualTypeOf(); + expect(data.empoweredZombieKills).toBeDefined(); + expect(data.empoweredZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.empoweredZombieKills).toEqualTypeOf(); + expect(data.enderZombieKills).toBeDefined(); + expect(data.enderZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderZombieKills).toEqualTypeOf(); + expect(data.endermiteZombieKills).toBeDefined(); + expect(data.endermiteZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.endermiteZombieKills).toEqualTypeOf(); + expect(data.familyDaughterZombieKills).toBeDefined(); + expect(data.familyDaughterZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyDaughterZombieKills).toEqualTypeOf(); + expect(data.familyFatherZombieKills).toBeDefined(); + expect(data.familyFatherZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyFatherZombieKills).toEqualTypeOf(); + expect(data.familyMotherZombieKills).toBeDefined(); + expect(data.familyMotherZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyMotherZombieKills).toEqualTypeOf(); + expect(data.familyTwinBlueZombieKills).toBeDefined(); + expect(data.familyTwinBlueZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyTwinBlueZombieKills).toEqualTypeOf(); + expect(data.familyTwinRedZombieKills).toBeDefined(); + expect(data.familyTwinRedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyTwinRedZombieKills).toEqualTypeOf(); + expect(data.fastestTime10).toBeDefined(); + expect(data.fastestTime10).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime10).toEqualTypeOf(); + expect(data.fastestTime20).toBeDefined(); + expect(data.fastestTime20).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime20).toEqualTypeOf(); + expect(data.fastestTime30).toBeDefined(); + expect(data.fastestTime30).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime30).toEqualTypeOf(); + expect(data.fireLordZombieKills).toBeDefined(); + expect(data.fireLordZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fireLordZombieKills).toEqualTypeOf(); + expect(data.fireZombieKills).toBeDefined(); + expect(data.fireZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fireZombieKills).toEqualTypeOf(); + expect(data.frostZombieZombieKills).toBeDefined(); + expect(data.frostZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.frostZombieZombieKills).toEqualTypeOf(); + expect(data.ghastZombieKills).toBeDefined(); + expect(data.ghastZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ghastZombieKills).toEqualTypeOf(); + expect(data.giantRainbowZombieKills).toBeDefined(); + expect(data.giantRainbowZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giantRainbowZombieKills).toEqualTypeOf(); + expect(data.giantZombieKills).toBeDefined(); + expect(data.giantZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giantZombieKills).toEqualTypeOf(); + expect(data.guardZombieZombieKills).toBeDefined(); + expect(data.guardZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.guardZombieZombieKills).toEqualTypeOf(); + expect(data.guardianZombieKills).toBeDefined(); + expect(data.guardianZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.guardianZombieKills).toEqualTypeOf(); + expect(data.headlessPigmanZombieKills).toBeDefined(); + expect(data.headlessPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headlessPigmanZombieKills).toEqualTypeOf(); + expect(data.headshots).toBeDefined(); + expect(data.headshots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headshots).toEqualTypeOf(); + expect(data.herobrineMinionZombieKills).toBeDefined(); + expect(data.herobrineMinionZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.herobrineMinionZombieKills).toEqualTypeOf(); + expect(data.herobrineZombieKills).toBeDefined(); + expect(data.herobrineZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.herobrineZombieKills).toEqualTypeOf(); + expect(data.humanZombieKills).toBeDefined(); + expect(data.humanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.humanZombieKills).toEqualTypeOf(); + expect(data.infernoPigmanZombieKills).toBeDefined(); + expect(data.infernoPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.infernoPigmanZombieKills).toEqualTypeOf(); + expect(data.infernoZombieKills).toBeDefined(); + expect(data.infernoZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.infernoZombieKills).toEqualTypeOf(); + expect(data.invisibleZombieKills).toBeDefined(); + expect(data.invisibleZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.invisibleZombieKills).toEqualTypeOf(); + expect(data.ironGolemZombieKills).toBeDefined(); + expect(data.ironGolemZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ironGolemZombieKills).toEqualTypeOf(); + expect(data.kingDrownedZombieKills).toBeDefined(); + expect(data.kingDrownedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kingDrownedZombieKills).toEqualTypeOf(); + expect(data.kingSlimeZombieKills).toBeDefined(); + expect(data.kingSlimeZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kingSlimeZombieKills).toEqualTypeOf(); + expect(data.knightDrownedZombieKills).toBeDefined(); + expect(data.knightDrownedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.knightDrownedZombieKills).toEqualTypeOf(); + expect(data.magmaCubeZombieKills).toBeDefined(); + expect(data.magmaCubeZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magmaCubeZombieKills).toEqualTypeOf(); + expect(data.magmaZombieKills).toBeDefined(); + expect(data.magmaZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magmaZombieKills).toEqualTypeOf(); + expect(data.mcdonaldsPigmanZombieKills).toBeDefined(); + expect(data.mcdonaldsPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mcdonaldsPigmanZombieKills).toEqualTypeOf(); + expect(data.mcdonaldsZombieZombieKills).toBeDefined(); + expect(data.mcdonaldsZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mcdonaldsZombieZombieKills).toEqualTypeOf(); + expect(data.megaBlobZombieKills).toBeDefined(); + expect(data.megaBlobZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.megaBlobZombieKills).toEqualTypeOf(); + expect(data.megaMagmaZombieKills).toBeDefined(); + expect(data.megaMagmaZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.megaMagmaZombieKills).toEqualTypeOf(); + expect(data.moltenZombieKills).toBeDefined(); + expect(data.moltenZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.moltenZombieKills).toEqualTypeOf(); + expect(data.murderPigmanZombieKills).toBeDefined(); + expect(data.murderPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murderPigmanZombieKills).toEqualTypeOf(); + expect(data.murderZombieZombieKills).toBeDefined(); + expect(data.murderZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murderZombieZombieKills).toEqualTypeOf(); + expect(data.nurseZombieZombieKills).toBeDefined(); + expect(data.nurseZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nurseZombieZombieKills).toEqualTypeOf(); + expect(data.pigZombieZombieKills).toBeDefined(); + expect(data.pigZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pigZombieZombieKills).toEqualTypeOf(); + expect(data.playersRevived).toBeDefined(); + expect(data.playersRevived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playersRevived).toEqualTypeOf(); + expect(data.prisonerPigman2CellZombieKills).toBeDefined(); + expect(data.prisonerPigman2CellZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerPigman2CellZombieKills).toEqualTypeOf(); + expect(data.prisonerPigman2ZombieKills).toBeDefined(); + expect(data.prisonerPigman2ZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerPigman2ZombieKills).toEqualTypeOf(); + expect(data.prisonerPigmanCellZombieKills).toBeDefined(); + expect(data.prisonerPigmanCellZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerPigmanCellZombieKills).toEqualTypeOf(); + expect(data.prisonerPigmanZombieKills).toBeDefined(); + expect(data.prisonerPigmanZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerPigmanZombieKills).toEqualTypeOf(); + expect(data.prisonerSkeletonZombieKills).toBeDefined(); + expect(data.prisonerSkeletonZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerSkeletonZombieKills).toEqualTypeOf(); + expect(data.prisonerZombieAngry2ZombieKills).toBeDefined(); + expect(data.prisonerZombieAngry2ZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerZombieAngry2ZombieKills).toEqualTypeOf(); + expect(data.prisonerZombieAngry3ZombieKills).toBeDefined(); + expect(data.prisonerZombieAngry3ZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerZombieAngry3ZombieKills).toEqualTypeOf(); + expect(data.prisonerZombieAngryZombieKills).toBeDefined(); + expect(data.prisonerZombieAngryZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerZombieAngryZombieKills).toEqualTypeOf(); + expect(data.prisonerZombieCellZombieKills).toBeDefined(); + expect(data.prisonerZombieCellZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerZombieCellZombieKills).toEqualTypeOf(); + expect(data.prisonerZombieKills).toBeDefined(); + expect(data.prisonerZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prisonerZombieKills).toEqualTypeOf(); + expect(data.rainbowZombieKills).toBeDefined(); + expect(data.rainbowZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rainbowZombieKills).toEqualTypeOf(); + expect(data.scubaZombieKills).toBeDefined(); + expect(data.scubaZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scubaZombieKills).toEqualTypeOf(); + expect(data.sentinelZombieKills).toBeDefined(); + expect(data.sentinelZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sentinelZombieKills).toEqualTypeOf(); + expect(data.shadySkeletonZombieKills).toBeDefined(); + expect(data.shadySkeletonZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shadySkeletonZombieKills).toEqualTypeOf(); + expect(data.silverfishZombieKills).toBeDefined(); + expect(data.silverfishZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silverfishZombieKills).toEqualTypeOf(); + expect(data.skelefishZombieKills).toBeDefined(); + expect(data.skelefishZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skelefishZombieKills).toEqualTypeOf(); + expect(data.skeletonZombieKills).toBeDefined(); + expect(data.skeletonZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skeletonZombieKills).toEqualTypeOf(); + expect(data.slimeZombieKills).toBeDefined(); + expect(data.slimeZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slimeZombieKills).toEqualTypeOf(); + expect(data.slimeZombieZombieKills).toBeDefined(); + expect(data.slimeZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slimeZombieZombieKills).toEqualTypeOf(); + expect(data.spaceBlasterZombieKills).toBeDefined(); + expect(data.spaceBlasterZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spaceBlasterZombieKills).toEqualTypeOf(); + expect(data.spaceGruntZombieKills).toBeDefined(); + expect(data.spaceGruntZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spaceGruntZombieKills).toEqualTypeOf(); + expect(data.tankDrownedZombieKills).toBeDefined(); + expect(data.tankDrownedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tankDrownedZombieKills).toEqualTypeOf(); + expect(data.tankZombieZombieKills).toBeDefined(); + expect(data.tankZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tankZombieZombieKills).toEqualTypeOf(); + expect(data.theOldOneZombieKills).toBeDefined(); + expect(data.theOldOneZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theOldOneZombieKills).toEqualTypeOf(); + expect(data.theWardenZombieKills).toBeDefined(); + expect(data.theWardenZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theWardenZombieKills).toEqualTypeOf(); + expect(data.timesKnockedDown).toBeDefined(); + expect(data.timesKnockedDown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesKnockedDown).toEqualTypeOf(); + expect(data.tntBabyZombieKills).toBeDefined(); + expect(data.tntBabyZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tntBabyZombieKills).toEqualTypeOf(); + expect(data.tntZombieKills).toBeDefined(); + expect(data.tntZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tntZombieKills).toEqualTypeOf(); + expect(data.totalRoundsSurvived).toBeDefined(); + expect(data.totalRoundsSurvived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalRoundsSurvived).toEqualTypeOf(); + expect(data.werewolfZombieKills).toBeDefined(); + expect(data.werewolfZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.werewolfZombieKills).toEqualTypeOf(); + expect(data.windowsRepaired).toBeDefined(); + expect(data.windowsRepaired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.windowsRepaired).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.witchZombieKills).toBeDefined(); + expect(data.witchZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witchZombieKills).toEqualTypeOf(); + expect(data.witherSkeletonZombieKills).toBeDefined(); + expect(data.witherSkeletonZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherSkeletonZombieKills).toEqualTypeOf(); + expect(data.witherZombieKills).toBeDefined(); + expect(data.witherZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherZombieKills).toEqualTypeOf(); + expect(data.witherZombieZombieKills).toBeDefined(); + expect(data.witherZombieZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherZombieZombieKills).toEqualTypeOf(); + expect(data.wolfDrownedZombieKills).toBeDefined(); + expect(data.wolfDrownedZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wolfDrownedZombieKills).toEqualTypeOf(); + expect(data.wolfPetZombieKills).toBeDefined(); + expect(data.wolfPetZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wolfPetZombieKills).toEqualTypeOf(); + expect(data.wolfZombieKills).toBeDefined(); + expect(data.wolfZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wolfZombieKills).toEqualTypeOf(); + expect(data.worldEnderZombieKills).toBeDefined(); + expect(data.worldEnderZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.worldEnderZombieKills).toEqualTypeOf(); + expect(data.wormSmallZombieKills).toBeDefined(); + expect(data.wormSmallZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wormSmallZombieKills).toEqualTypeOf(); + expect(data.wormZombieKills).toBeDefined(); + expect(data.wormZombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wormZombieKills).toEqualTypeOf(); + expect(data.zombieKills).toBeDefined(); + expect(data.zombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieKills).toEqualTypeOf(); + expect(data.hideTutorials).toBeDefined(); + expectTypeOf(data.hideTutorials).toEqualTypeOf(); + expect(data.alienArcadium).toBeDefined(); + expect(data.alienArcadium).toBeInstanceOf(ZombiesMap); + expectTypeOf(data.alienArcadium).toEqualTypeOf(); + expect(data.alienArcadium.normal).toBeUndefined(); + expect(data.alienArcadium.hard).toBeUndefined(); + expect(data.alienArcadium.rip).toBeUndefined(); + expect(data.badBlood).toBeDefined(); + expect(data.badBlood).toBeInstanceOf(ZombiesMap); + expect(data.badBlood.normal).toBeDefined(); + expect(data.badBlood.hard).toBeDefined(); + expect(data.badBlood.rip).toBeDefined(); + expectTypeOf(data.badBlood).toEqualTypeOf(); + expect(data.deadEnd).toBeDefined(); + expect(data.deadEnd).toBeInstanceOf(ZombiesMap); + expectTypeOf(data.deadEnd).toEqualTypeOf(); + expect(data.deadEnd.normal).toBeDefined(); + expect(data.deadEnd.hard).toBeDefined(); + expect(data.deadEnd.rip).toBeDefined(); + expect(data.prison).toBeDefined(); + expect(data.prison).toBeInstanceOf(ZombiesMap); + expectTypeOf(data.prison).toEqualTypeOf(); + expect(data.prison.normal).toBeDefined(); + expect(data.prison.hard).toBeDefined(); + expect(data.prison.rip).toBeDefined(); +}); diff --git a/src/Structures/MiniGames/Arcade/Zombies/Zombies.ts b/src/Structures/MiniGames/Arcade/Zombies/Zombies.ts new file mode 100644 index 000000000..f96fe3c4f --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/Zombies.ts @@ -0,0 +1,228 @@ +import ZombiesMap from './ZombiesMap.js'; + +class Zombies { + basicZombieKills: number; + basketballZombieKills: number; + bestRound: number; + blazeZombieKills: number; + blobZombieKills: number; + bombZombieKills: number; + broodmotherZombieKills: number; + bulletsHit: number; + bulletsShot: number; + caveSpiderZombieKills: number; + chargedCreeperZombieKills: number; + chglugluZombieKills: number; + clownZombieKills: number; + corruptedPigmanZombieKills: number; + creeperZombieKills: number; + daBombZombieKills: number; + deaths: number; + doorsOpened: number; + drownedZombieKills: number; + empoweredZombieKills: number; + enderZombieKills: number; + endermiteZombieKills: number; + familyDaughterZombieKills: number; + familyFatherZombieKills: number; + familyMotherZombieKills: number; + familyTwinBlueZombieKills: number; + familyTwinRedZombieKills: number; + fastestTime10: number; + fastestTime20: number; + fastestTime30: number; + fireLordZombieKills: number; + fireZombieKills: number; + frostZombieZombieKills: number; + ghastZombieKills: number; + giantRainbowZombieKills: number; + giantZombieKills: number; + guardZombieZombieKills: number; + guardianZombieKills: number; + headlessPigmanZombieKills: number; + headshots: number; + herobrineMinionZombieKills: number; + herobrineZombieKills: number; + humanZombieKills: number; + infernoPigmanZombieKills: number; + infernoZombieKills: number; + invisibleZombieKills: number; + ironGolemZombieKills: number; + kingDrownedZombieKills: number; + kingSlimeZombieKills: number; + knightDrownedZombieKills: number; + magmaCubeZombieKills: number; + magmaZombieKills: number; + mcdonaldsPigmanZombieKills: number; + mcdonaldsZombieZombieKills: number; + megaBlobZombieKills: number; + megaMagmaZombieKills: number; + moltenZombieKills: number; + murderPigmanZombieKills: number; + murderZombieZombieKills: number; + nurseZombieZombieKills: number; + pigZombieZombieKills: number; + playersRevived: number; + prisonerPigman2CellZombieKills: number; + prisonerPigman2ZombieKills: number; + prisonerPigmanCellZombieKills: number; + prisonerPigmanZombieKills: number; + prisonerSkeletonZombieKills: number; + prisonerZombieAngry2ZombieKills: number; + prisonerZombieAngry3ZombieKills: number; + prisonerZombieAngryZombieKills: number; + prisonerZombieCellZombieKills: number; + prisonerZombieKills: number; + rainbowZombieKills: number; + scubaZombieKills: number; + sentinelZombieKills: number; + shadySkeletonZombieKills: number; + silverfishZombieKills: number; + skelefishZombieKills: number; + skeletonZombieKills: number; + slimeZombieKills: number; + slimeZombieZombieKills: number; + spaceBlasterZombieKills: number; + spaceGruntZombieKills: number; + tankDrownedZombieKills: number; + tankZombieZombieKills: number; + theOldOneZombieKills: number; + theWardenZombieKills: number; + timesKnockedDown: number; + tntBabyZombieKills: number; + tntZombieKills: number; + totalRoundsSurvived: number; + werewolfZombieKills: number; + windowsRepaired: number; + wins: number; + witchZombieKills: number; + witherSkeletonZombieKills: number; + witherZombieKills: number; + witherZombieZombieKills: number; + wolfDrownedZombieKills: number; + wolfPetZombieKills: number; + wolfZombieKills: number; + worldEnderZombieKills: number; + wormSmallZombieKills: number; + wormZombieKills: number; + zombieKills: number; + hideTutorials: boolean; + alienArcadium: ZombiesMap; + badBlood: ZombiesMap; + deadEnd: ZombiesMap; + prison: ZombiesMap; + constructor(data: Record) { + this.basicZombieKills = data?.basic_zombie_kills_zombies || 0; + this.basketballZombieKills = data?.basketball_zombie_zombie_kills_zombies || 0; + this.bestRound = data?.best_round_zombies || 0; + this.blazeZombieKills = data?.blaze_zombie_kills_zombies || 0; + this.blobZombieKills = data?.blob_zombie_kills_zombies || 0; + this.bombZombieKills = data?.bomb_zombie_kills_zombies || 0; + this.broodmotherZombieKills = data?.broodmother_zombie_kills_zombies || 0; + this.bulletsHit = data?.bullets_hit_zombies || 0; + this.bulletsShot = data?.bullets_shot_zombies || 0; + this.caveSpiderZombieKills = data?.cave_spider_zombie_kills_zombies || 0; + this.chargedCreeperZombieKills = data?.charged_creeper_zombie_kills_zombies || 0; + this.chglugluZombieKills = data?.chgluglu_zombie_kills_zombies || 0; + this.clownZombieKills = data?.clown_zombie_kills_zombies || 0; + this.corruptedPigmanZombieKills = data?.corrupted_pigman_zombie_kills_zombies || 0; + this.creeperZombieKills = data?.creeper_zombie_kills_zombies || 0; + this.daBombZombieKills = data?.da_bomb_zombie_kills_zombies || 0; + this.deaths = data?.deaths_zombies || 0; + this.doorsOpened = data?.doors_opened_zombies || 0; + this.drownedZombieKills = data?.drowned_zombie_kills_zombies || 0; + this.empoweredZombieKills = data?.empowered_zombie_kills_zombies || 0; + this.enderZombieKills = data?.ender_zombie_kills_zombies || 0; + this.endermiteZombieKills = data?.endermite_zombie_kills_zombies || 0; + this.familyDaughterZombieKills = data?.family_daughter_zombie_kills_zombies || 0; + this.familyFatherZombieKills = data?.family_father_zombie_kills_zombies || 0; + this.familyMotherZombieKills = data?.family_mother_zombie_kills_zombies || 0; + this.familyTwinBlueZombieKills = data?.family_twin_blue_zombie_kills_zombies || 0; + this.familyTwinRedZombieKills = data?.family_twin_red_zombie_kills_zombies || 0; + this.fastestTime10 = data?.fastest_time_10_zombies || 0; + this.fastestTime20 = data?.fastest_time_20_zombies || 0; + this.fastestTime30 = data?.fastest_time_30_zombies || 0; + this.fireLordZombieKills = data?.fire_lord_zombie_kills_zombies || 0; + this.fireZombieKills = data?.fire_zombie_kills_zombies || 0; + this.frostZombieZombieKills = data?.frost_zombie_zombie_kills_zombies || 0; + this.ghastZombieKills = data?.ghast_zombie_kills_zombies || 0; + this.giantRainbowZombieKills = data?.giant_rainbow_zombie_kills_zombies || 0; + this.giantZombieKills = data?.giant_zombie_kills_zombies || 0; + this.guardZombieZombieKills = data?.guard_zombie_zombie_kills_zombies || 0; + this.guardianZombieKills = data?.guardian_zombie_kills_zombies || 0; + this.headlessPigmanZombieKills = data?.headless_pigman_zombie_kills_zombies || 0; + this.headshots = data?.headshots_zombies || 0; + this.herobrineMinionZombieKills = data?.herobrine_minion_zombie_kills_zombies || 0; + this.herobrineZombieKills = data?.herobrine_zombie_kills_zombies || 0; + this.humanZombieKills = data?.human_zombie_zombie_kills_zombies || 0; + this.infernoPigmanZombieKills = data?.inferno_pigman_zombie_kills_zombies || 0; + this.infernoZombieKills = data?.inferno_zombie_kills_zombies || 0; + this.invisibleZombieKills = data?.invisible_zombie_kills_zombies || 0; + this.ironGolemZombieKills = data?.iron_golem_zombie_kills_zombies || 0; + this.kingDrownedZombieKills = data?.king_drowned_zombie_kills_zombies || 0; + this.kingSlimeZombieKills = data?.king_slime_zombie_kills_zombies || 0; + this.knightDrownedZombieKills = data?.knight_drowned_zombie_kills_zombies || 0; + this.magmaCubeZombieKills = data?.magma_cube_zombie_kills_zombies || 0; + this.magmaZombieKills = data?.magma_zombie_kills_zombies || 0; + this.mcdonaldsPigmanZombieKills = data?.mcdonalds_pigman_zombie_kills_zombies || 0; + this.mcdonaldsZombieZombieKills = data?.mcdonalds_zombie_zombie_kills_zombies || 0; + this.megaBlobZombieKills = data?.mega_blob_zombie_kills_zombies || 0; + this.megaMagmaZombieKills = data?.mega_magma_zombie_kills_zombies || 0; + this.moltenZombieKills = data?.molten_zombie_kills_zombies || 0; + this.murderPigmanZombieKills = data?.murder_pigman_zombie_kills_zombies || 0; + this.murderZombieZombieKills = data?.murder_zombie_zombie_kills_zombies || 0; + this.nurseZombieZombieKills = data?.nurse_zombie_zombie_kills_zombies || 0; + this.pigZombieZombieKills = data?.pig_zombie_zombie_kills_zombies || 0; + this.playersRevived = data?.players_revived_zombies || 0; + this.prisonerPigman2CellZombieKills = data?.prisoner_pigman_2_cell_zombie_kills_zombies || 0; + this.prisonerPigman2ZombieKills = data?.prisoner_pigman_2_zombie_kills_zombies || 0; + this.prisonerPigmanCellZombieKills = data?.prisoner_pigman_cell_zombie_kills_zombies || 0; + this.prisonerPigmanZombieKills = data?.prisoner_pigman_zombie_kills_zombies || 0; + this.prisonerSkeletonZombieKills = data?.prisoner_skeleton_zombie_kills_zombies || 0; + this.prisonerZombieAngry2ZombieKills = data?.prisoner_zombie_angry_2_zombie_kills_zombies || 0; + this.prisonerZombieAngry3ZombieKills = data?.prisoner_zombie_angry_3_zombie_kills_zombies || 0; + this.prisonerZombieAngryZombieKills = data?.prisoner_zombie_angry_zombie_kills_zombies || 0; + this.prisonerZombieCellZombieKills = data?.prisoner_zombie_cell_zombie_kills_zombies || 0; + this.prisonerZombieKills = data?.prisoner_zombie_zombie_kills_zombies || 0; + this.rainbowZombieKills = data?.rainbow_zombie_kills_zombies || 0; + this.scubaZombieKills = data?.scuba_zombie_zombie_kills_zombies || 0; + this.sentinelZombieKills = data?.sentinel_zombie_kills_zombies || 0; + this.shadySkeletonZombieKills = data?.shady_skeleton_zombie_kills_zombies || 0; + this.silverfishZombieKills = data?.silverfish_zombie_kills_zombies || 0; + this.skelefishZombieKills = data?.skelefish_zombie_kills_zombies || 0; + this.skeletonZombieKills = data?.skeleton_zombie_kills_zombies || 0; + this.slimeZombieKills = data?.slime_zombie_kills_zombies || 0; + this.slimeZombieZombieKills = data?.slime_zombie_zombie_kills_zombies || 0; + this.spaceBlasterZombieKills = data?.space_blaster_zombie_kills_zombies || 0; + this.spaceGruntZombieKills = data?.space_grunt_zombie_kills_zombies || 0; + this.tankDrownedZombieKills = data?.tank_drowned_zombie_kills_zombies || 0; + this.tankZombieZombieKills = data?.tank_zombie_zombie_kills_zombies || 0; + this.theOldOneZombieKills = data?.the_old_one_zombie_kills_zombies || 0; + this.theWardenZombieKills = data?.the_warden_zombie_kills_zombies || 0; + this.timesKnockedDown = data?.times_knocked_down_zombies || 0; + this.tntBabyZombieKills = data?.tnt_baby_zombie_kills_zombies || 0; + this.tntZombieKills = data?.tnt_zombie_kills_zombies || 0; + this.totalRoundsSurvived = data?.total_rounds_survived_zombies || 0; + this.werewolfZombieKills = data?.werewolf_zombie_kills_zombies || 0; + this.windowsRepaired = data?.windows_repaired_zombies || 0; + this.wins = data?.wins_zombies || 0; + this.witchZombieKills = data?.witch_zombie_kills_zombies || 0; + this.witherSkeletonZombieKills = data?.wither_skeleton_zombie_kills_zombies || 0; + this.witherZombieKills = data?.wither_zombie_kills_zombies || 0; + this.witherZombieZombieKills = data?.wither_zombie_zombie_kills_zombies || 0; + this.wolfDrownedZombieKills = data?.wolf_drowned_zombie_kills_zombies || 0; + this.wolfPetZombieKills = data?.wolf_pet_zombie_kills_zombies || 0; + this.wolfZombieKills = data?.wolf_zombie_kills_zombies || 0; + this.worldEnderZombieKills = data?.world_ender_zombie_kills_zombies || 0; + this.wormSmallZombieKills = data?.worm_small_zombie_kills_zombies || 0; + this.wormZombieKills = data?.worm_zombie_kills_zombies || 0; + this.zombieKills = data?.zombie_kills_zombies || 0; + this.hideTutorials = data?.zombies_hideTutorials || false; + this.alienArcadium = new ZombiesMap(data, 'alienarcadium', false); + this.badBlood = new ZombiesMap(data, 'badblood', true); + this.deadEnd = new ZombiesMap(data, 'deadend', true); + this.prison = new ZombiesMap(data, 'prison', true); + } +} + +export default Zombies; diff --git a/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.test.ts b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.test.ts new file mode 100644 index 000000000..5167aa5b3 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.test.ts @@ -0,0 +1,101 @@ +import ZombiesMap from './ZombiesMap.js'; +import ZombiesMapMode from './ZombiesMapMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ZombiesMap (alienarcadium)', () => { + const data = new ZombiesMap({ stats: 'meow' }, 'alienarcadium', false); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ZombiesMap); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestRound).toBeDefined(); + expect(data.bestRound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestRound).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.doorsOpened).toBeDefined(); + expect(data.doorsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doorsOpened).toEqualTypeOf(); + expect(data.fastestTime10).toBeDefined(); + expect(data.fastestTime10).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime10).toEqualTypeOf(); + expect(data.fastestTime20).toBeDefined(); + expect(data.fastestTime20).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime20).toEqualTypeOf(); + expect(data.fastestTime30).toBeDefined(); + expect(data.fastestTime30).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime30).toEqualTypeOf(); + expect(data.playersRevived).toBeDefined(); + expect(data.playersRevived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playersRevived).toEqualTypeOf(); + expect(data.timesKnockedDown).toBeDefined(); + expect(data.timesKnockedDown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesKnockedDown).toEqualTypeOf(); + expect(data.totalRoundsSurvived).toBeDefined(); + expect(data.totalRoundsSurvived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalRoundsSurvived).toEqualTypeOf(); + expect(data.windowsRepaired).toBeDefined(); + expect(data.windowsRepaired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.windowsRepaired).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.zombieKills).toBeDefined(); + expect(data.zombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieKills).toEqualTypeOf(); + expect(data.normal).toBeUndefined(); + expect(data.hard).toBeUndefined(); + expect(data.rip).toBeUndefined(); +}); + +test('ZombiesMap (deadend)', () => { + const data = new ZombiesMap({ stats: 'meow' }, 'deadend', true); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ZombiesMap); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestRound).toBeDefined(); + expect(data.bestRound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestRound).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.doorsOpened).toBeDefined(); + expect(data.doorsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doorsOpened).toEqualTypeOf(); + expect(data.fastestTime10).toBeDefined(); + expect(data.fastestTime10).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime10).toEqualTypeOf(); + expect(data.fastestTime20).toBeDefined(); + expect(data.fastestTime20).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime20).toEqualTypeOf(); + expect(data.fastestTime30).toBeDefined(); + expect(data.fastestTime30).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime30).toEqualTypeOf(); + expect(data.playersRevived).toBeDefined(); + expect(data.playersRevived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playersRevived).toEqualTypeOf(); + expect(data.timesKnockedDown).toBeDefined(); + expect(data.timesKnockedDown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesKnockedDown).toEqualTypeOf(); + expect(data.totalRoundsSurvived).toBeDefined(); + expect(data.totalRoundsSurvived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalRoundsSurvived).toEqualTypeOf(); + expect(data.windowsRepaired).toBeDefined(); + expect(data.windowsRepaired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.windowsRepaired).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.zombieKills).toBeDefined(); + expect(data.zombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieKills).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(ZombiesMapMode); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.hard).toBeDefined(); + expect(data.hard).toBeInstanceOf(ZombiesMapMode); + expectTypeOf(data.hard).toEqualTypeOf(); + expect(data.rip).toBeDefined(); + expect(data.rip).toBeInstanceOf(ZombiesMapMode); + expectTypeOf(data.rip).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.ts b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.ts new file mode 100644 index 000000000..092421ccb --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMap.ts @@ -0,0 +1,51 @@ +import ZombiesMapMode from './ZombiesMapMode.js'; +import type { ArcadeZombiesMaps } from '../../../../Types/Player.js'; + +function minPositive(...values: number[]): number { + const positives = values.filter((v) => v > 0); + return positives.length > 0 ? Math.min(...positives) : 0; +} + +class ZombiesMap { + bestRound: number; + deaths: number; + doorsOpened: number; + fastestTime10: number; + fastestTime20: number; + fastestTime30: number; + playersRevived: number; + timesKnockedDown: number; + totalRoundsSurvived: number; + windowsRepaired: number; + wins: number; + zombieKills: number; + normal?: ZombiesMapMode; + hard?: ZombiesMapMode; + rip?: ZombiesMapMode; + constructor(data: Record, map: ArcadeZombiesMaps, hasModes: boolean = false) { + this.bestRound = data?.[`best_round_zombies_${map}`] || 0; + this.deaths = data?.[`deaths_zombies_${map}`] || 0; + this.doorsOpened = data?.[`doors_opened_zombies_${map}`] || 0; + this.playersRevived = data?.[`players_revived_zombies_${map}`] || 0; + this.timesKnockedDown = data?.[`times_knocked_down_zombies_${map}`] || 0; + this.totalRoundsSurvived = data?.[`total_rounds_survived_zombies_${map}`] || 0; + this.windowsRepaired = data?.[`windows_repaired_zombies_${map}`] || 0; + this.wins = data?.[`wins_zombies_${map}`] || 0; + this.zombieKills = data?.[`zombie_kills_zombies_${map}`] || 0; + + if (hasModes) { + this.normal = new ZombiesMapMode(data, map, 'normal'); + this.hard = new ZombiesMapMode(data, map, 'hard'); + this.rip = new ZombiesMapMode(data, map, 'rip'); + this.fastestTime10 = minPositive(this.normal.fastestTime10, this.hard.fastestTime10, this.rip.fastestTime10); + this.fastestTime20 = minPositive(this.normal.fastestTime20, this.hard.fastestTime20, this.rip.fastestTime20); + this.fastestTime30 = minPositive(this.normal.fastestTime30, this.hard.fastestTime30, this.rip.fastestTime30); + } else { + this.fastestTime10 = data?.[`fastest_time_10_zombies_${map}_normal`] || 0; + this.fastestTime20 = data?.[`fastest_time_20_zombies_${map}_normal`] || 0; + this.fastestTime30 = data?.[`fastest_time_30_zombies_${map}_normal`] || 0; + } + } +} + +export default ZombiesMap; diff --git a/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.test.ts b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.test.ts new file mode 100644 index 000000000..26bdb40b5 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.test.ts @@ -0,0 +1,45 @@ +import ZombiesMapMode from './ZombiesMapMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ZombiesMapMode', () => { + const data = new ZombiesMapMode({ stats: 'meow' }, 'deadend', 'normal'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ZombiesMapMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestRound).toBeDefined(); + expect(data.bestRound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestRound).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.doorsOpened).toBeDefined(); + expect(data.doorsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doorsOpened).toEqualTypeOf(); + expect(data.fastestTime10).toBeDefined(); + expect(data.fastestTime10).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime10).toEqualTypeOf(); + expect(data.fastestTime20).toBeDefined(); + expect(data.fastestTime20).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime20).toEqualTypeOf(); + expect(data.fastestTime30).toBeDefined(); + expect(data.fastestTime30).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTime30).toEqualTypeOf(); + expect(data.playersRevived).toBeDefined(); + expect(data.playersRevived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playersRevived).toEqualTypeOf(); + expect(data.timesKnockedDown).toBeDefined(); + expect(data.timesKnockedDown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesKnockedDown).toEqualTypeOf(); + expect(data.totalRoundsSurvived).toBeDefined(); + expect(data.totalRoundsSurvived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalRoundsSurvived).toEqualTypeOf(); + expect(data.windowsRepaired).toBeDefined(); + expect(data.windowsRepaired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.windowsRepaired).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.zombieKills).toBeDefined(); + expect(data.zombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieKills).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.ts b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.ts new file mode 100644 index 000000000..065fd9f23 --- /dev/null +++ b/src/Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.ts @@ -0,0 +1,32 @@ +import type { ArcadeZombiesDifficulty, ArcadeZombiesMaps } from '../../../../Types/Player.js'; + +class ZombiesMapMode { + bestRound: number; + deaths: number; + doorsOpened: number; + fastestTime10: number; + fastestTime20: number; + fastestTime30: number; + playersRevived: number; + timesKnockedDown: number; + totalRoundsSurvived: number; + windowsRepaired: number; + wins: number; + zombieKills: number; + constructor(data: Record, map: ArcadeZombiesMaps, mode: ArcadeZombiesDifficulty) { + this.bestRound = data?.[`best_round_zombies_${map}_${mode}`] || 0; + this.deaths = data?.[`deaths_zombies_${map}_${mode}`] || 0; + this.doorsOpened = data?.[`doors_opened_zombies_${map}_${mode}`] || 0; + this.fastestTime10 = data?.[`fastest_time_10_zombies_${map}_${mode}`] || 0; + this.fastestTime20 = data?.[`fastest_time_20_zombies_${map}_${mode}`] || 0; + this.fastestTime30 = data?.[`fastest_time_30_zombies_${map}_${mode}`] || 0; + this.playersRevived = data?.[`players_revived_zombies_${map}_${mode}`] || 0; + this.timesKnockedDown = data?.[`times_knocked_down_zombies_${map}_${mode}`] || 0; + this.totalRoundsSurvived = data?.[`total_rounds_survived_zombies_${map}_${mode}`] || 0; + this.windowsRepaired = data?.[`windows_repaired_zombies_${map}_${mode}`] || 0; + this.wins = data?.[`wins_zombies_${map}_${mode}`] || 0; + this.zombieKills = data?.[`zombie_kills_zombies_${map}_${mode}`] || 0; + } +} + +export default ZombiesMapMode; diff --git a/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.test.ts b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.test.ts new file mode 100644 index 000000000..41550fba6 --- /dev/null +++ b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.test.ts @@ -0,0 +1,37 @@ +import ArenaBrawl from './ArenaBrawl.js'; +import ArenaBrawlMode from './ArenaBrawlMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ArenaBrawlRunes } from '../../../Types/Player.js'; + +test('ArenaBrawl', () => { + const data = new ArenaBrawl({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ArenaBrawl); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.coinsSpent).toBeDefined(); + expect(data.coinsSpent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coinsSpent).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.keys).toBeDefined(); + expect(data.keys).toBeGreaterThanOrEqual(0); + expectTypeOf(data.keys).toEqualTypeOf(); + expect(data.chests).toBeDefined(); + expect(data.chests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chests).toEqualTypeOf(); + expect(data.rune).toBeDefined(); + expectTypeOf(data.rune).toEqualTypeOf(); + expect(data['1v1']).toBeDefined(); + expect(data['1v1']).toBeInstanceOf(ArenaBrawlMode); + expectTypeOf(data['1v1']).toEqualTypeOf(); + expect(data['2v2']).toBeDefined(); + expect(data['2v2']).toBeInstanceOf(ArenaBrawlMode); + expectTypeOf(data['2v2']).toEqualTypeOf(); + expect(data['4v4']).toBeDefined(); + expect(data['4v4']).toBeInstanceOf(ArenaBrawlMode); + expectTypeOf(data['4v4']).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.ts b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.ts new file mode 100644 index 000000000..92ea31b97 --- /dev/null +++ b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawl.ts @@ -0,0 +1,27 @@ +import ArenaBrawlMode from './ArenaBrawlMode.js'; +import type { ArenaBrawlRunes } from '../../../Types/Player.js'; + +class ArenaBrawl { + coins: number; + coinsSpent: number; + wins: number; + keys: number; + chests: number; + rune: ArenaBrawlRunes | 'None'; + '1v1': ArenaBrawlMode; + '2v2': ArenaBrawlMode; + '4v4': ArenaBrawlMode; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.coinsSpent = data?.coins_spent || 0; + this.wins = data?.wins || 0; + this.keys = data?.keys || 0; + this.chests = data?.magical_chest || 0; + this.rune = data?.active_rune || 'None'; + this['1v1'] = new ArenaBrawlMode(data, '1v1'); + this['2v2'] = new ArenaBrawlMode(data, '2v2'); + this['4v4'] = new ArenaBrawlMode(data, '4v4'); + } +} + +export default ArenaBrawl; diff --git a/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.test.ts b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.test.ts new file mode 100644 index 000000000..8bb3415a9 --- /dev/null +++ b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.test.ts @@ -0,0 +1,39 @@ +import ArenaBrawlMode from './ArenaBrawlMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('ArenaBrawlMode', () => { + const data = new ArenaBrawlMode({ stats: 'meow' }, '1v1'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(ArenaBrawlMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.damage).toBeDefined(); + expect(data.damage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damage).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.healed).toBeDefined(); + expect(data.healed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healed).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeGreaterThanOrEqual(0); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.ts b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.ts new file mode 100644 index 000000000..f2caad015 --- /dev/null +++ b/src/Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.ts @@ -0,0 +1,29 @@ +import Divide from '../../../Utils/Divide.js'; +import type { ArenaBrawlModes } from '../../../Types/Player.js'; + +class ArenaBrawlMode { + damage: number; + kills: number; + deaths: number; + KDR: number; + healed: number; + wins: number; + losses: number; + WLR: number; + games: number; + winStreak: number; + constructor(data: Record, mode: ArenaBrawlModes) { + this.damage = data?.[`damage_${mode}`] || 0; + this.kills = data?.[`kills_${mode}`] || 0; + this.deaths = data?.[`deaths_${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.healed = data?.[`healed_${mode}`] || 0; + this.wins = data?.[`wins_${mode}`] || 0; + this.losses = data?.[`losses_${mode}`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.games = data?.[`games_${mode}`] || 0; + this.winStreak = data?.[`win_streaks_${mode}`] || 0; + } +} + +export default ArenaBrawlMode; diff --git a/src/Structures/MiniGames/BedWars/BedWars.test.ts b/src/Structures/MiniGames/BedWars/BedWars.test.ts new file mode 100644 index 000000000..b5063be3f --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWars.test.ts @@ -0,0 +1,120 @@ +import BedWars from './BedWars.js'; +import BedWarsBoxes from './BedWarsBoxes.js'; +import BedWarsFavorites from './BedWarsFavorites.js'; +import BedWarsFigurines from './BedWarsFigurines.js'; +import BedWarsPrivateGameSettings from './BedWarsPrivateGameSettings.js'; +import BedWarsSettings from './BedWarsSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + BedWarsBedDestroy, + BedWarsDeathCry, + BedWarsGlyph, + BedWarsIslandTopper, + BedWarsKillEffect, + BedWarsKillMessage, + BedWarsNPCSkin, + BedWarsPrestige, + BedWarsProjectileTrail, + BedWarsQuickbuyPrivacy, + BedWarsSpray, + BedWarsStartingWeapon, + BedWarsUltimate, + BedWarsVictoryDance, + BedWarsWoodSkin, + PlayerGeneralSelectedCosmetic, + ShopSort +} from '../../../Types/Player.js'; + +test('BedWars', () => { + const data = new BedWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expectTypeOf(data.prestige).toEqualTypeOf(); + expect(data.activeBedDestroy).toBeDefined(); + expectTypeOf(data.activeBedDestroy).toEqualTypeOf(); + expect(data.activeDeathCry).toBeDefined(); + expectTypeOf(data.activeDeathCry).toEqualTypeOf(); + expect(data.activeGlyph).toBeDefined(); + expectTypeOf(data.activeGlyph).toEqualTypeOf(); + expect(data.activeIslandTopper).toBeDefined(); + expectTypeOf(data.activeIslandTopper).toEqualTypeOf< + BedWarsIslandTopper | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.activeKillEffect).toBeDefined(); + expectTypeOf(data.activeKillEffect).toEqualTypeOf(); + expect(data.activeKillMessages).toBeDefined(); + expectTypeOf(data.activeKillMessages).toEqualTypeOf(); + expect(data.activeNPCSkin).toBeDefined(); + expectTypeOf(data.activeNPCSkin).toEqualTypeOf(); + expect(data.activeProjectileTrail).toBeDefined(); + expectTypeOf(data.activeProjectileTrail).toEqualTypeOf< + BedWarsProjectileTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.activeSprays).toBeDefined(); + expectTypeOf(data.activeSprays).toEqualTypeOf(); + expect(data.activeVictoryDance).toBeDefined(); + expectTypeOf(data.activeVictoryDance).toEqualTypeOf< + BedWarsVictoryDance | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.activeWoodType).toBeDefined(); + expectTypeOf(data.activeWoodType).toEqualTypeOf(); + expect(data.activeStartingWeapon).toBeDefined(); + expectTypeOf(data.activeStartingWeapon).toEqualTypeOf< + BedWarsStartingWeapon | PlayerGeneralSelectedCosmetic | 'UNKNOWN' + >(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.firstJoin7).toBeDefined(); + expectTypeOf(data.firstJoin7).toEqualTypeOf(); + expect(data.glyphStorage).toBeDefined(); + expectTypeOf(data.glyphStorage).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.quickbuyPrivacy).toBeDefined(); + expectTypeOf(data.quickbuyPrivacy).toEqualTypeOf(); + expect(data.seenBetaMenu).toBeDefined(); + expectTypeOf(data.seenBetaMenu).toEqualTypeOf(); + expect(data.selectedUltimate).toBeDefined(); + expectTypeOf(data.selectedUltimate).toEqualTypeOf(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.shopSortEnableOwnedFirst).toBeDefined(); + expectTypeOf(data.shopSortEnableOwnedFirst).toEqualTypeOf(); + expect(data.spookyOpenAch).toBeDefined(); + expect(data.spookyOpenAch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spookyOpenAch).toEqualTypeOf(); + expect(data.sprayGlyphField).toBeDefined(); + expectTypeOf(data.sprayGlyphField).toEqualTypeOf(); + expect(data.sprayStorage).toBeDefined(); + expectTypeOf(data.sprayStorage).toEqualTypeOf(); + expect(data.understandsResourceBank).toBeDefined(); + expectTypeOf(data.understandsResourceBank).toEqualTypeOf(); + expect(data.understandsStreaks).toBeDefined(); + expectTypeOf(data.understandsStreaks).toEqualTypeOf(); + expect(data.updateBook).toBeDefined(); + expectTypeOf(data.updateBook).toEqualTypeOf(); + expect(data.boxes).toBeDefined(); + expect(data.boxes).toBeInstanceOf(BedWarsBoxes); + expectTypeOf(data.boxes).toEqualTypeOf(); + expect(data.favorites).toBeDefined(); + expect(data.favorites).toBeInstanceOf(BedWarsFavorites); + expectTypeOf(data.favorites).toEqualTypeOf(); + expect(data.figurines).toBeDefined(); + expect(data.figurines).toBeInstanceOf(BedWarsFigurines); + expectTypeOf(data.figurines).toEqualTypeOf(); + expect(data.privateGameSettings).toBeDefined(); + expect(data.privateGameSettings).toBeInstanceOf(BedWarsPrivateGameSettings); + expectTypeOf(data.privateGameSettings).toEqualTypeOf(); + expect(data.settings).toBeDefined(); + expect(data.settings).toBeInstanceOf(BedWarsSettings); + expectTypeOf(data.settings).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWars.ts b/src/Structures/MiniGames/BedWars/BedWars.ts new file mode 100644 index 000000000..8f31dbd5b --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWars.ts @@ -0,0 +1,149 @@ +import BedWarsBoxes from './BedWarsBoxes.js'; +import BedWarsEightOne from './BedWarsEightOne.ts'; +import BedWarsEightTwo from './BedWarsEightTwo.ts'; +import BedWarsFavorites from './BedWarsFavorites.js'; +import BedWarsFigurines from './BedWarsFigurines.js'; +import BedWarsFourFour from './BedWarsFourFour.ts'; +import BedWarsFourThree from './BedWarsFourThree.ts'; +import BedWarsMode from './BedWarsMode.js'; +import BedWarsPrivateGameSettings from './BedWarsPrivateGameSettings.js'; +import BedWarsSettings from './BedWarsSettings.js'; +import BedWarsSlumber from './BedWarsSlumber/BedWarsSlumber.ts'; +import BedWarsTwoFour from './BedWarsTwoFour.ts'; +import { BedWarsPrestiges } from '../../../Utils/Constants.js'; +import type { + BedWarsBedDestroy, + BedWarsDeathCry, + BedWarsGlyph, + BedWarsIslandTopper, + BedWarsKillEffect, + BedWarsKillMessage, + BedWarsNPCSkin, + BedWarsPrestige, + BedWarsProjectileTrail, + BedWarsQuickbuyPrivacy, + BedWarsSpray, + BedWarsStartingWeapon, + BedWarsUltimate, + BedWarsVictoryDance, + BedWarsWoodSkin, + PlayerGeneralSelectedCosmetic, + ShopSort +} from '../../../Types/Player.js'; + +class BedWars extends BedWarsMode { + experience: number; + level: number; + prestige: BedWarsPrestige; + activeBedDestroy: BedWarsBedDestroy | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeDeathCry: BedWarsDeathCry | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeGlyph: BedWarsGlyph | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeIslandTopper: BedWarsIslandTopper | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeKillEffect: BedWarsKillEffect | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeKillMessages: BedWarsKillMessage | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeNPCSkin: BedWarsNPCSkin | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeProjectileTrail: BedWarsProjectileTrail | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeSprays: BedWarsSpray | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeVictoryDance: BedWarsVictoryDance | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeWoodType: BedWarsWoodSkin | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + activeStartingWeapon: BedWarsStartingWeapon | PlayerGeneralSelectedCosmetic | 'UNKNOWN'; + tokens: number; + firstJoin7: boolean; + glyphStorage: string[]; + packages: string[]; + quickbuyPrivacy: BedWarsQuickbuyPrivacy; + seenBetaMenu: boolean; + selectedUltimate: BedWarsUltimate | 'UNKNOWN'; + shopSort: ShopSort | 'UNKNOWN'; + shopSortEnableOwnedFirst: boolean; + spookyOpenAch: number; + sprayGlyphField: string[]; + sprayStorage: string[]; + understandsResourceBank: boolean; + understandsStreaks: boolean; + updateBook: string | 'UNKNOWN'; + boxes: BedWarsBoxes; + favorites: BedWarsFavorites; + figurines: BedWarsFigurines; + privateGameSettings: BedWarsPrivateGameSettings; + settings: BedWarsSettings; + eightOne: BedWarsEightOne; + eightTwo: BedWarsEightTwo; + fourThree: BedWarsFourThree; + fourFour: BedWarsFourFour; + twoFour: BedWarsTwoFour; + castle: BedWarsMode; + slumber: BedWarsSlumber; + constructor(data: Record) { + super(data); + this.experience = data?.Experience || 0; + this.level = BedWars.getLevel(this.experience); + this.prestige = BedWars.getPrestige(this.level); + this.activeBedDestroy = data?.activeBedDestroy || 'UNKNOWN'; + this.activeDeathCry = data?.activeDeathCry || 'UNKNOWN'; + this.activeGlyph = data?.activeGlyph || 'UNKNOWN'; + this.activeIslandTopper = data?.activeIslandTopper || 'UNKNOWN'; + this.activeKillEffect = data?.activeKillEffect || 'UNKNOWN'; + this.activeKillMessages = data?.activeKillMessages || 'UNKNOWN'; + this.activeNPCSkin = data?.activeNPCSkin || 'UNKNOWN'; + this.activeProjectileTrail = data?.activeProjectileTrail || 'UNKNOWN'; + this.activeSprays = data?.activeSprays || 'UNKNOWN'; + this.activeVictoryDance = data?.activeVictoryDance || 'UNKNOWN'; + this.activeWoodType = data?.activeWoodType || 'UNKNOWN'; + this.activeStartingWeapon = data?.active_starting_weapon || 'UNKNOWN'; + this.tokens = data?.tokens || data?.coins || 0; + this.firstJoin7 = data?.first_join_7 || false; + this.glyphStorage = (data?.glyph_storage_new || '').split(','); + this.packages = data?.packages || []; + this.quickbuyPrivacy = data?.quickbuy_privacy || 'NONE'; + this.seenBetaMenu = data?.seen_beta_menu || false; + this.selectedUltimate = data?.selected_ultimate || 'UNKNOWN'; + this.shopSort = data?.shop_sort || 'UNKNOWN'; + this.shopSortEnableOwnedFirst = data?.shop_sort_enable_owned_first || false; + this.spookyOpenAch = data?.spooky_open_ach || 0; + this.sprayGlyphField = (data?.spray_glyph_field || '').split(','); + this.sprayStorage = (data?.spray_storage_new || '').split(','); + this.understandsResourceBank = data?.understands_resource_bank || false; + this.understandsStreaks = data?.understands_streaks || false; + this.updateBook = data?.updatebook_bedwars || 'UNKNOWN'; + this.boxes = new BedWarsBoxes(data); + this.favorites = new BedWarsFavorites(data); + this.figurines = new BedWarsFigurines(data?.figurines || {}); + this.privateGameSettings = new BedWarsPrivateGameSettings(data?.privategames || {}); + this.settings = new BedWarsSettings(data?.settings || {}); + this.eightOne = new BedWarsEightOne(data); + this.eightTwo = new BedWarsEightTwo(data); + this.fourThree = new BedWarsFourThree(data); + this.fourFour = new BedWarsFourFour(data); + this.twoFour = new BedWarsTwoFour(data); + this.castle = new BedWarsMode(data, 'castle'); + this.slumber = new BedWarsSlumber(data?.slumber || {}); + } + + static getPrestige(level: number): BedWarsPrestige { + return ( + ( + BedWarsPrestiges.slice() + .reverse() + .find((t) => level >= t.requirement) || BedWarsPrestiges[0] + )?.prestige || 'Stone' + ); + } + + static getLevel(xp: number): number { + let level = Math.floor(xp / 487000) * 100; + xp = xp % 487000; + if (xp < 500) return level + xp / 500; + level++; + if (xp < 1500) return level + (xp - 500) / 1000; + level++; + if (xp < 3500) return level + (xp - 1500) / 2000; + level++; + if (xp < 7000) return level + (xp - 3500) / 3500; + level++; + xp -= 7000; + return level + xp / 5000; + } +} + +export default BedWars; diff --git a/src/Structures/MiniGames/BedWars/BedWarsBeds.test.ts b/src/Structures/MiniGames/BedWars/BedWarsBeds.test.ts new file mode 100644 index 000000000..bcf9aaa9f --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsBeds.test.ts @@ -0,0 +1,18 @@ +import BedWarsBeds from './BedWarsBeds.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsBeds', () => { + const data = new BedWarsBeds({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsBeds); + expectTypeOf(data).toEqualTypeOf(); + expect(data.broken).toBeDefined(); + expect(data.broken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.broken).toEqualTypeOf(); + expect(data.lost).toBeDefined(); + expect(data.lost).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lost).toEqualTypeOf(); + expect(data.ratio).toBeDefined(); + expect(data.ratio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ratio).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsBeds.ts b/src/Structures/MiniGames/BedWars/BedWarsBeds.ts new file mode 100644 index 000000000..39d8bdf90 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsBeds.ts @@ -0,0 +1,17 @@ +import Divide from '../../../Utils/Divide.js'; +import { ParseModeBefore } from '../../../Utils/ParseMode.ts'; +import type { BedWarsModeId } from '../../../Types/Player.js'; + +class BedWarsBeds { + broken: number; + lost: number; + ratio: number; + constructor(data: Record, mode?: BedWarsModeId) { + mode = ParseModeBefore(mode) as BedWarsModeId; + this.broken = data?.[`${mode}beds_broken_bedwars`] || 0; + this.lost = data?.[`${mode}beds_lost_bedwars`] || 0; + this.ratio = Divide(this.broken, this.lost); + } +} + +export default BedWarsBeds; diff --git a/src/Structures/MiniGames/BedWars/BedWarsBoxes.test.ts b/src/Structures/MiniGames/BedWars/BedWarsBoxes.test.ts new file mode 100644 index 000000000..0a932afe1 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsBoxes.test.ts @@ -0,0 +1,57 @@ +import BedWarsBoxes from './BedWarsBoxes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsBoxes', () => { + const data = new BedWarsBoxes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsBoxes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.openedChests).toBeDefined(); + expect(data.openedChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedChests).toEqualTypeOf(); + expect(data.openedCommons).toBeDefined(); + expect(data.openedCommons).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedCommons).toEqualTypeOf(); + expect(data.openedEpics).toBeDefined(); + expect(data.openedEpics).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedEpics).toEqualTypeOf(); + expect(data.openedLegendaries).toBeDefined(); + expect(data.openedLegendaries).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedLegendaries).toEqualTypeOf(); + expect(data.openedRares).toBeDefined(); + expect(data.openedRares).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedRares).toEqualTypeOf(); + expect(data.box).toBeDefined(); + expect(data.box).toBeGreaterThanOrEqual(0); + expectTypeOf(data.box).toEqualTypeOf(); + expect(data.commons).toBeDefined(); + expect(data.commons).toBeGreaterThanOrEqual(0); + expectTypeOf(data.commons).toEqualTypeOf(); + expect(data.epics).toBeDefined(); + expect(data.epics).toBeGreaterThanOrEqual(0); + expectTypeOf(data.epics).toEqualTypeOf(); + expect(data.legendaries).toBeDefined(); + expect(data.legendaries).toBeGreaterThanOrEqual(0); + expectTypeOf(data.legendaries).toEqualTypeOf(); + expect(data.rares).toBeDefined(); + expect(data.rares).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rares).toEqualTypeOf(); + expect(data.boxes).toBeDefined(); + expect(data.boxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boxes).toEqualTypeOf(); + expect(data.christmas).toBeDefined(); + expect(data.christmas).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmas).toEqualTypeOf(); + expect(data.easter).toBeDefined(); + expect(data.easter).toBeGreaterThanOrEqual(0); + expectTypeOf(data.easter).toEqualTypeOf(); + expect(data.golden).toBeDefined(); + expect(data.golden).toBeGreaterThanOrEqual(0); + expectTypeOf(data.golden).toEqualTypeOf(); + expect(data.halloween).toBeDefined(); + expect(data.halloween).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloween).toEqualTypeOf(); + expect(data.lunar).toBeDefined(); + expect(data.lunar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lunar).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsBoxes.ts b/src/Structures/MiniGames/BedWars/BedWarsBoxes.ts new file mode 100644 index 000000000..84bc572bf --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsBoxes.ts @@ -0,0 +1,38 @@ +class BedWarsBoxes { + openedChests: number; + openedCommons: number; + openedEpics: number; + openedLegendaries: number; + openedRares: number; + box: number; + commons: number; + epics: number; + legendaries: number; + rares: number; + boxes: number; + christmas: number; + easter: number; + golden: number; + halloween: number; + lunar: number; + constructor(data: Record) { + this.openedChests = data?.Bedwars_openedChests || 0; + this.openedCommons = data?.Bedwars_openedCommons || 0; + this.openedEpics = data?.Bedwars_openedEpics || 0; + this.openedLegendaries = data?.Bedwars_openedLegendaries || 0; + this.openedRares = data?.Bedwars_openedRares || 0; + this.box = data?.bedwars_box || 0; + this.commons = data?.bedwars_box_commons || 0; + this.epics = data?.bedwars_box_epics || 0; + this.legendaries = data?.bedwars_box_legendaries || 0; + this.rares = data?.bedwars_box_rares || 0; + this.boxes = data?.bedwars_boxes || 0; + this.christmas = data?.bedwars_christmas_boxes || 0; + this.easter = data?.bedwars_easter_boxes || 0; + this.golden = data?.bedwars_golden_boxes || 0; + this.halloween = data?.bedwars_halloween_boxes || 0; + this.lunar = data?.bedwars_lunar_boxes || 0; + } +} + +export default BedWarsBoxes; diff --git a/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.test.ts b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.test.ts new file mode 100644 index 000000000..17c4181c6 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.test.ts @@ -0,0 +1,15 @@ +import BedWarsChallenge from './BedWarsChallenge.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsChallenge', () => { + const data = new BedWarsChallenge({ stats: 'meow' }, 'archer_only'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bestTime).toBeDefined(); + expect(data.bestTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestTime).toEqualTypeOf(); + expect(data.timesCompleted).toBeDefined(); + expect(data.timesCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesCompleted).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.ts b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.ts new file mode 100644 index 000000000..b829daa5d --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.ts @@ -0,0 +1,12 @@ +import type { BedWarsChallengeId } from '../../../../Types/Player.js'; + +class BedWarsChallenge { + bestTime: number; + timesCompleted: number; + constructor(data: Record, challenge: BedWarsChallengeId) { + this.bestTime = data?.challenge?.[`bw_challenge_${challenge}_best_time`] || 0; + this.timesCompleted = data?.[`bw_challenge_${challenge}`] || 0; + } +} + +export default BedWarsChallenge; diff --git a/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.test.ts b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.test.ts new file mode 100644 index 000000000..e3383b90a --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.test.ts @@ -0,0 +1,109 @@ +import BedWarsChallenge from './BedWarsChallenge.js'; +import BedWarsChallenges from './BedWarsChallenges.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BedWarsChallengeName } from '../../../../Types/Player.js'; + +test('BedWarsChallenges', () => { + const data = new BedWarsChallenges({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsChallenges); + expectTypeOf(data).toEqualTypeOf(); + expect(data.uniqueChallengesCompleted).toBeDefined(); + expect(data.uniqueChallengesCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.uniqueChallengesCompleted).toEqualTypeOf(); + expect(data.selectedChallengeType).toBeDefined(); + expectTypeOf(data.selectedChallengeType).toEqualTypeOf(); + expect(data.totalChallengesCompleted).toBeDefined(); + expect(data.totalChallengesCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalChallengesCompleted).toEqualTypeOf(); + expect(data.archerOnly).toBeDefined(); + expect(data.archerOnly).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.archerOnly).toEqualTypeOf(); + expect(data.assassin).toBeDefined(); + expect(data.assassin).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.assassin).toEqualTypeOf(); + expect(data.cantTouchThis).toBeDefined(); + expect(data.cantTouchThis).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.cantTouchThis).toEqualTypeOf(); + expect(data.cappedResources).toBeDefined(); + expect(data.cappedResources).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.cappedResources).toEqualTypeOf(); + expect(data.collector).toBeDefined(); + expect(data.collector).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.collector).toEqualTypeOf(); + expect(data.defuser).toBeDefined(); + expect(data.defuser).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.defuser).toEqualTypeOf(); + expect(data.delayedHitting).toBeDefined(); + expect(data.delayedHitting).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.delayedHitting).toEqualTypeOf(); + expect(data.hotbar).toBeDefined(); + expect(data.hotbar).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.hotbar).toEqualTypeOf(); + expect(data.invisibleShop).toBeDefined(); + expect(data.invisibleShop).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.invisibleShop).toEqualTypeOf(); + expect(data.knockbackStickOnly).toBeDefined(); + expect(data.knockbackStickOnly).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.knockbackStickOnly).toEqualTypeOf(); + expect(data.masterAssassin).toBeDefined(); + expect(data.masterAssassin).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.masterAssassin).toEqualTypeOf(); + expect(data.miningFatigue).toBeDefined(); + expect(data.miningFatigue).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.miningFatigue).toEqualTypeOf(); + expect(data.noHealing).toBeDefined(); + expect(data.noHealing).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noHealing).toEqualTypeOf(); + expect(data.noHitting).toBeDefined(); + expect(data.noHitting).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noHitting).toEqualTypeOf(); + expect(data.noShift).toBeDefined(); + expect(data.noShift).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noShift).toEqualTypeOf(); + expect(data.noSprint).toBeDefined(); + expect(data.noSprint).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noSprint).toEqualTypeOf(); + expect(data.noSwords).toBeDefined(); + expect(data.noSwords).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noSwords).toEqualTypeOf(); + expect(data.noTeamUpgrades).toBeDefined(); + expect(data.noTeamUpgrades).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noTeamUpgrades).toEqualTypeOf(); + expect(data.noUtilities).toBeDefined(); + expect(data.noUtilities).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.noUtilities).toEqualTypeOf(); + expect(data.patriot).toBeDefined(); + expect(data.patriot).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.patriot).toEqualTypeOf(); + expect(data.protectThePresident).toBeDefined(); + expect(data.protectThePresident).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.protectThePresident).toEqualTypeOf(); + expect(data.resetArmor).toBeDefined(); + expect(data.resetArmor).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.resetArmor).toEqualTypeOf(); + expect(data.selfish).toBeDefined(); + expect(data.selfish).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.selfish).toEqualTypeOf(); + expect(data.slowGenerator).toBeDefined(); + expect(data.slowGenerator).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.slowGenerator).toEqualTypeOf(); + expect(data.sponge).toBeDefined(); + expect(data.sponge).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.sponge).toEqualTypeOf(); + expect(data.stamina).toBeDefined(); + expect(data.stamina).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.stamina).toEqualTypeOf(); + expect(data.stopLight).toBeDefined(); + expect(data.stopLight).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.stopLight).toEqualTypeOf(); + expect(data.toxicRain).toBeDefined(); + expect(data.toxicRain).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.toxicRain).toEqualTypeOf(); + expect(data.weightedItems).toBeDefined(); + expect(data.weightedItems).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.weightedItems).toEqualTypeOf(); + expect(data.woodworker).toBeDefined(); + expect(data.woodworker).toBeInstanceOf(BedWarsChallenge); + expectTypeOf(data.woodworker).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.ts b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.ts new file mode 100644 index 000000000..6e5a561ad --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.ts @@ -0,0 +1,75 @@ +import BedWarsChallenge from './BedWarsChallenge.js'; +import type { BedWarsChallengeName } from '../../../../Types/Player.js'; + +class BedWarsChallenges { + uniqueChallengesCompleted: number; + selectedChallengeType: BedWarsChallengeName | 'NONE'; + totalChallengesCompleted: number; + archerOnly: BedWarsChallenge; + assassin: BedWarsChallenge; + cantTouchThis: BedWarsChallenge; + cappedResources: BedWarsChallenge; + collector: BedWarsChallenge; + defuser: BedWarsChallenge; + delayedHitting: BedWarsChallenge; + hotbar: BedWarsChallenge; + invisibleShop: BedWarsChallenge; + knockbackStickOnly: BedWarsChallenge; + masterAssassin: BedWarsChallenge; + miningFatigue: BedWarsChallenge; + noHealing: BedWarsChallenge; + noHitting: BedWarsChallenge; + noShift: BedWarsChallenge; + noSprint: BedWarsChallenge; + noSwords: BedWarsChallenge; + noTeamUpgrades: BedWarsChallenge; + noUtilities: BedWarsChallenge; + patriot: BedWarsChallenge; + protectThePresident: BedWarsChallenge; + resetArmor: BedWarsChallenge; + selfish: BedWarsChallenge; + slowGenerator: BedWarsChallenge; + sponge: BedWarsChallenge; + stamina: BedWarsChallenge; + stopLight: BedWarsChallenge; + toxicRain: BedWarsChallenge; + weightedItems: BedWarsChallenge; + woodworker: BedWarsChallenge; + constructor(data: Record) { + this.uniqueChallengesCompleted = data?.bw_unique_challenges_completed || 0; + this.selectedChallengeType = data?.selected_challenge_type || 'NONE'; + this.totalChallengesCompleted = data?.total_challenges_completed || 0; + this.archerOnly = new BedWarsChallenge(data, 'archer_only'); + this.assassin = new BedWarsChallenge(data, 'assassin'); + this.cantTouchThis = new BedWarsChallenge(data, 'cant_touch_this'); + this.cappedResources = new BedWarsChallenge(data, 'capped_resources'); + this.collector = new BedWarsChallenge(data, 'collector'); + this.defuser = new BedWarsChallenge(data, 'defuser'); + this.delayedHitting = new BedWarsChallenge(data, 'delayed_hitting'); + this.hotbar = new BedWarsChallenge(data, 'hotbar'); + this.invisibleShop = new BedWarsChallenge(data, 'invisible_shop'); + this.knockbackStickOnly = new BedWarsChallenge(data, 'knockback_stick_only'); + this.masterAssassin = new BedWarsChallenge(data, 'master_assassin'); + this.miningFatigue = new BedWarsChallenge(data, 'mining_fatigue'); + this.noHealing = new BedWarsChallenge(data, 'no_healing'); + this.noHitting = new BedWarsChallenge(data, 'no_hitting'); + this.noShift = new BedWarsChallenge(data, 'no_shift'); + this.noSprint = new BedWarsChallenge(data, 'no_sprint'); + this.noSwords = new BedWarsChallenge(data, 'no_swords'); + this.noTeamUpgrades = new BedWarsChallenge(data, 'no_team_upgrades'); + this.noUtilities = new BedWarsChallenge(data, 'no_utilities'); + this.patriot = new BedWarsChallenge(data, 'patriot'); + this.protectThePresident = new BedWarsChallenge(data, 'protect_the_president'); + this.resetArmor = new BedWarsChallenge(data, 'reset_armor'); + this.selfish = new BedWarsChallenge(data, 'selfish'); + this.slowGenerator = new BedWarsChallenge(data, 'slow_generator'); + this.sponge = new BedWarsChallenge(data, 'sponge'); + this.stamina = new BedWarsChallenge(data, 'stamina'); + this.stopLight = new BedWarsChallenge(data, 'stop_light'); + this.toxicRain = new BedWarsChallenge(data, 'toxic_rain'); + this.weightedItems = new BedWarsChallenge(data, 'weighted_items'); + this.woodworker = new BedWarsChallenge(data, 'woodworker'); + } +} + +export default BedWarsChallenges; diff --git a/src/Structures/MiniGames/BedWars/BedWarsEightOne.test.ts b/src/Structures/MiniGames/BedWars/BedWarsEightOne.test.ts new file mode 100644 index 000000000..fd25a88f5 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsEightOne.test.ts @@ -0,0 +1,19 @@ +import BedWarsEightOne from './BedWarsEightOne.js'; +import BedWarsMode from './BedWarsMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsEightOne', () => { + const data = new BedWarsEightOne({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsEightOne); + expectTypeOf(data).toEqualTypeOf(); + expect(data.oneblock).toBeDefined(); + expect(data.oneblock).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.oneblock).toEqualTypeOf(); + expect(data.rush).toBeDefined(); + expect(data.rush).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.rush).toEqualTypeOf(); + expect(data.ultimate).toBeDefined(); + expect(data.ultimate).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.ultimate).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsEightOne.ts b/src/Structures/MiniGames/BedWars/BedWarsEightOne.ts new file mode 100644 index 000000000..cfc1d4252 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsEightOne.ts @@ -0,0 +1,15 @@ +import BedWarsMode from './BedWarsMode.js'; + +class BedWarsEightOne extends BedWarsMode { + oneblock: BedWarsMode; + rush: BedWarsMode; + ultimate: BedWarsMode; + constructor(data: Record) { + super(data, 'eight_one'); + this.oneblock = new BedWarsMode(data, 'eight_one_oneblock'); + this.rush = new BedWarsMode(data, 'eight_one_rush'); + this.ultimate = new BedWarsMode(data, 'eight_one_ultimate'); + } +} + +export default BedWarsEightOne; diff --git a/src/Structures/MiniGames/BedWars/BedWarsEightTwo.test.ts b/src/Structures/MiniGames/BedWars/BedWarsEightTwo.test.ts new file mode 100644 index 000000000..a07f92d5e --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsEightTwo.test.ts @@ -0,0 +1,40 @@ +import BedWarsEightTwo from './BedWarsEightTwo.js'; +import BedWarsMode from './BedWarsMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsEightTwo', () => { + const data = new BedWarsEightTwo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsEightTwo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tourney1).toBeDefined(); + expect(data.tourney1).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney1).toEqualTypeOf(); + expect(data.tourney0).toBeDefined(); + expect(data.tourney0).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney0).toEqualTypeOf(); + expect(data.tourney).toBeDefined(); + expect(data.tourney).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney).toEqualTypeOf(); + expect(data.armed).toBeDefined(); + expect(data.armed).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.armed).toEqualTypeOf(); + expect(data.lucky).toBeDefined(); + expect(data.lucky).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.lucky).toEqualTypeOf(); + expect(data.rush).toBeDefined(); + expect(data.rush).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.rush).toEqualTypeOf(); + expect(data.swap).toBeDefined(); + expect(data.swap).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.swap).toEqualTypeOf(); + expect(data.ultimate).toBeDefined(); + expect(data.ultimate).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.ultimate).toEqualTypeOf(); + expect(data.underworld).toBeDefined(); + expect(data.underworld).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.underworld).toEqualTypeOf(); + expect(data.voidless).toBeDefined(); + expect(data.voidless).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.voidless).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsEightTwo.ts b/src/Structures/MiniGames/BedWars/BedWarsEightTwo.ts new file mode 100644 index 000000000..87dadbd20 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsEightTwo.ts @@ -0,0 +1,29 @@ +import BedWarsMode from './BedWarsMode.js'; + +class BedWarsEightTwo extends BedWarsMode { + tourney1: BedWarsMode; + tourney0: BedWarsMode; + tourney: BedWarsMode; + armed: BedWarsMode; + lucky: BedWarsMode; + rush: BedWarsMode; + swap: BedWarsMode; + ultimate: BedWarsMode; + underworld: BedWarsMode; + voidless: BedWarsMode; + constructor(data: Record) { + super(data, 'eight_two'); + this.tourney1 = new BedWarsMode(data, 'tourney_bedwars_eight_two_1'); + this.tourney0 = new BedWarsMode(data, 'tourney_bedwars_eight_two_0'); + this.tourney = new BedWarsMode(data, 'eight_two_tourney'); + this.armed = new BedWarsMode(data, 'eight_two_armed'); + this.lucky = new BedWarsMode(data, 'eight_two_lucky'); + this.rush = new BedWarsMode(data, 'eight_two_rush'); + this.swap = new BedWarsMode(data, 'eight_two_swap'); + this.ultimate = new BedWarsMode(data, 'eight_two_ultimate'); + this.underworld = new BedWarsMode(data, 'eight_two_underworld'); + this.voidless = new BedWarsMode(data, 'eight_two_voidless'); + } +} + +export default BedWarsEightTwo; diff --git a/src/Structures/MiniGames/BedWars/BedWarsFavorites.test.ts b/src/Structures/MiniGames/BedWars/BedWarsFavorites.test.ts new file mode 100644 index 000000000..1c5b9b93c --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFavorites.test.ts @@ -0,0 +1,43 @@ +import BedWarsFavorites from './BedWarsFavorites.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsFavorites', () => { + const data = new BedWarsFavorites({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsFavorites); + expectTypeOf(data).toEqualTypeOf(); + expect(data.streakSlots).toBeDefined(); + expectTypeOf(data.streakSlots).toEqualTypeOf(); + expect(data.hotbarSlots).toBeDefined(); + expectTypeOf(data.hotbarSlots).toEqualTypeOf(); + expect(data.shopSlots).toBeDefined(); + expectTypeOf(data.shopSlots).toEqualTypeOf(); + expect(data.shopSlots2).toBeDefined(); + expectTypeOf(data.shopSlots2).toEqualTypeOf(); + expect(data.bedDestroy).toBeDefined(); + expectTypeOf(data.bedDestroy).toEqualTypeOf(); + expect(data.deathcry).toBeDefined(); + expectTypeOf(data.deathcry).toEqualTypeOf(); + expect(data.figurine).toBeDefined(); + expectTypeOf(data.figurine).toEqualTypeOf(); + expect(data.glyph).toBeDefined(); + expectTypeOf(data.glyph).toEqualTypeOf(); + expect(data.islandTopper).toBeDefined(); + expectTypeOf(data.islandTopper).toEqualTypeOf(); + expect(data.killEffect).toBeDefined(); + expectTypeOf(data.killEffect).toEqualTypeOf(); + expect(data.killMessages).toBeDefined(); + expectTypeOf(data.killMessages).toEqualTypeOf(); + expect(data.npcSkin).toBeDefined(); + expectTypeOf(data.npcSkin).toEqualTypeOf(); + expect(data.projectileTrail).toBeDefined(); + expectTypeOf(data.projectileTrail).toEqualTypeOf(); + expect(data.sprays).toBeDefined(); + expectTypeOf(data.sprays).toEqualTypeOf(); + expect(data.startingWeapon).toBeDefined(); + expectTypeOf(data.startingWeapon).toEqualTypeOf(); + expect(data.victoryDance).toBeDefined(); + expectTypeOf(data.victoryDance).toEqualTypeOf(); + expect(data.woodSkin).toBeDefined(); + expectTypeOf(data.woodSkin).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsFavorites.ts b/src/Structures/MiniGames/BedWars/BedWarsFavorites.ts new file mode 100644 index 000000000..73da4892b --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFavorites.ts @@ -0,0 +1,40 @@ +class BedWarsFavorites { + streakSlots: string[]; + hotbarSlots: string[]; + shopSlots: string[]; + shopSlots2: string[]; + bedDestroy: string[]; + deathcry: string[]; + figurine: string[]; + glyph: string[]; + islandTopper: string[]; + killEffect: string[]; + killMessages: string[]; + npcSkin: string[]; + projectileTrail: string[]; + sprays: string[]; + startingWeapon: string[]; + victoryDance: string[]; + woodSkin: string[]; + constructor(data: Record) { + this.streakSlots = (data?.fav_streak_slots || '').split(','); + this.hotbarSlots = (data?.favorite_slots || '').split(','); + this.shopSlots = (data?.favourites_1 || '').split(','); + this.shopSlots2 = (data?.favourites_2 || '').split(','); + this.bedDestroy = data?.favorites?.beddestroy || []; + this.deathcry = data?.favorites?.deathcry || []; + this.figurine = data?.favorites?.figurine || []; + this.glyph = data?.favorites?.glyph || []; + this.islandTopper = data?.favorites?.islandtopper || []; + this.killEffect = data?.favorites?.killeffect || []; + this.killMessages = data?.favorites?.killmessages || []; + this.npcSkin = data?.favorites?.npcskin || []; + this.projectileTrail = data?.favorites?.projectiletrail || []; + this.sprays = data?.favorites?.sprays || []; + this.startingWeapon = data?.favorites?.starting_weapon || []; + this.victoryDance = data?.favorites?.victorydance || []; + this.woodSkin = data?.favorites?.woodSkin || []; + } +} + +export default BedWarsFavorites; diff --git a/src/Structures/MiniGames/BedWars/BedWarsFigurines.test.ts b/src/Structures/MiniGames/BedWars/BedWarsFigurines.test.ts new file mode 100644 index 000000000..897752f62 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFigurines.test.ts @@ -0,0 +1,17 @@ +import BedWarsFigurines from './BedWarsFigurines.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsFigurines', () => { + const data = new BedWarsFigurines({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsFigurines); + expectTypeOf(data).toEqualTypeOf(); + expect(data.active).toBeDefined(); + expectTypeOf(data.active).toEqualTypeOf(); + expect(data.featuredCommon).toBeDefined(); + expectTypeOf(data.featuredCommon).toEqualTypeOf(); + expect(data.featuredLegendary).toBeDefined(); + expectTypeOf(data.featuredLegendary).toEqualTypeOf(); + expect(data.featuredRare).toBeDefined(); + expectTypeOf(data.featuredRare).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsFigurines.ts b/src/Structures/MiniGames/BedWars/BedWarsFigurines.ts new file mode 100644 index 000000000..efce9902b --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFigurines.ts @@ -0,0 +1,14 @@ +class BedWarsFigurines { + active: string | 'UNKNOWN'; + featuredCommon: string[]; + featuredLegendary: string[]; + featuredRare: string[]; + constructor(data: Record) { + this.active = data?.active || 'UNKNOWN'; + this.featuredCommon = data?.featured?.COMMON || []; + this.featuredLegendary = data?.featured?.LEGENDARY || []; + this.featuredRare = data?.featured?.RARE || []; + } +} + +export default BedWarsFigurines; diff --git a/src/Structures/MiniGames/BedWars/BedWarsFourFour.test.ts b/src/Structures/MiniGames/BedWars/BedWarsFourFour.test.ts new file mode 100644 index 000000000..15416e681 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFourFour.test.ts @@ -0,0 +1,40 @@ +import BedWarsFourFour from './BedWarsFourFour.js'; +import BedWarsMode from './BedWarsMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsFourFour', () => { + const data = new BedWarsFourFour({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsFourFour); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tourney1).toBeDefined(); + expect(data.tourney1).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney1).toEqualTypeOf(); + expect(data.tourney0).toBeDefined(); + expect(data.tourney0).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney0).toEqualTypeOf(); + expect(data.tourney).toBeDefined(); + expect(data.tourney).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney).toEqualTypeOf(); + expect(data.armed).toBeDefined(); + expect(data.armed).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.armed).toEqualTypeOf(); + expect(data.lucky).toBeDefined(); + expect(data.lucky).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.lucky).toEqualTypeOf(); + expect(data.rush).toBeDefined(); + expect(data.rush).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.rush).toEqualTypeOf(); + expect(data.swap).toBeDefined(); + expect(data.swap).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.swap).toEqualTypeOf(); + expect(data.ultimate).toBeDefined(); + expect(data.ultimate).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.ultimate).toEqualTypeOf(); + expect(data.underworld).toBeDefined(); + expect(data.underworld).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.underworld).toEqualTypeOf(); + expect(data.voidless).toBeDefined(); + expect(data.voidless).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.voidless).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsFourFour.ts b/src/Structures/MiniGames/BedWars/BedWarsFourFour.ts new file mode 100644 index 000000000..9a5950f68 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFourFour.ts @@ -0,0 +1,29 @@ +import BedWarsMode from './BedWarsMode.js'; + +class BedWarsFourFour extends BedWarsMode { + tourney1: BedWarsMode; + tourney0: BedWarsMode; + tourney: BedWarsMode; + armed: BedWarsMode; + lucky: BedWarsMode; + rush: BedWarsMode; + swap: BedWarsMode; + ultimate: BedWarsMode; + underworld: BedWarsMode; + voidless: BedWarsMode; + constructor(data: Record) { + super(data, 'four_four'); + this.tourney1 = new BedWarsMode(data, 'tourney_bedwars4s_1'); + this.tourney0 = new BedWarsMode(data, 'tourney_bedwars4s_0'); + this.tourney = new BedWarsMode(data, 'tourney_bedwars4s'); + this.armed = new BedWarsMode(data, 'four_four_armed'); + this.lucky = new BedWarsMode(data, 'four_four_lucky'); + this.rush = new BedWarsMode(data, 'four_four_rush'); + this.swap = new BedWarsMode(data, 'four_four_swap'); + this.ultimate = new BedWarsMode(data, 'four_four_ultimate'); + this.underworld = new BedWarsMode(data, 'four_four_underworld'); + this.voidless = new BedWarsMode(data, 'four_four_voidless'); + } +} + +export default BedWarsFourFour; diff --git a/src/Structures/MiniGames/BedWars/BedWarsFourThree.test.ts b/src/Structures/MiniGames/BedWars/BedWarsFourThree.test.ts new file mode 100644 index 000000000..6ed5bc7db --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFourThree.test.ts @@ -0,0 +1,9 @@ +import BedWarsFourThree from './BedWarsFourThree.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsFourThree', () => { + const data = new BedWarsFourThree({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsFourThree); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsFourThree.ts b/src/Structures/MiniGames/BedWars/BedWarsFourThree.ts new file mode 100644 index 000000000..5ddc37d7f --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsFourThree.ts @@ -0,0 +1,9 @@ +import BedWarsMode from './BedWarsMode.js'; + +class BedWarsFourThree extends BedWarsMode { + constructor(data: Record) { + super(data, 'four_three'); + } +} + +export default BedWarsFourThree; diff --git a/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.test.ts b/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.test.ts new file mode 100644 index 000000000..3b3197f95 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.test.ts @@ -0,0 +1,15 @@ +import BedWarsItemsPurchased from './BedWarsItemsPurchased.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsItemsPurchased', () => { + const data = new BedWarsItemsPurchased({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsItemsPurchased); + expectTypeOf(data).toEqualTypeOf(); + expect(data.itemsPurchased).toBeDefined(); + expect(data.itemsPurchased).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemsPurchased).toEqualTypeOf(); + expect(data.permanentItemsPurchased).toBeDefined(); + expect(data.permanentItemsPurchased).toBeGreaterThanOrEqual(0); + expectTypeOf(data.permanentItemsPurchased).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.ts b/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.ts new file mode 100644 index 000000000..94870dd42 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsItemsPurchased.ts @@ -0,0 +1,13 @@ +import { ParseModeBefore } from '../../../Utils/ParseMode.ts'; + +class BedWarsItemsPurchased { + itemsPurchased: number; + permanentItemsPurchased: number; + constructor(data: Record, mode?: string) { + mode = ParseModeBefore(mode); + this.itemsPurchased = data?.[`${mode}items_purchased_bedwars`] || 0; + this.permanentItemsPurchased = data?.[`${mode}permanent_items_purchased_bedwars`] || 0; + } +} + +export default BedWarsItemsPurchased; diff --git a/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.test.ts b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.test.ts new file mode 100644 index 000000000..cd6bf90f8 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.test.ts @@ -0,0 +1,64 @@ +import BedWarsKillsDeaths from './BedWarsKillsDeaths.js'; +import BedWarsKillsDeathsType from './BedWarsKillsDeathsType.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsKillsDeaths', () => { + const data = new BedWarsKillsDeaths({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsKillsDeaths); + expectTypeOf(data).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.custom).toBeDefined(); + expect(data.custom).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.custom).toEqualTypeOf(); + expect(data.drowning).toBeDefined(); + expect(data.drowning).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.drowning).toEqualTypeOf(); + expect(data.entityAttack).toBeDefined(); + expect(data.entityAttack).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.entityAttack).toEqualTypeOf(); + expect(data.entityExplosion).toBeDefined(); + expect(data.entityExplosion).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.entityExplosion).toEqualTypeOf(); + expect(data.fall).toBeDefined(); + expect(data.fall).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.fall).toEqualTypeOf(); + expect(data.fire).toBeDefined(); + expect(data.fire).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.fire).toEqualTypeOf(); + expect(data.fireTick).toBeDefined(); + expect(data.fireTick).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.fireTick).toEqualTypeOf(); + expect(data.magic).toBeDefined(); + expect(data.magic).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.magic).toEqualTypeOf(); + expect(data.projectile).toBeDefined(); + expect(data.projectile).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.projectile).toEqualTypeOf(); + expect(data.suffocation).toBeDefined(); + expect(data.suffocation).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.suffocation).toEqualTypeOf(); + expect(data.void).toBeDefined(); + expect(data.void).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.void).toEqualTypeOf(); + expect(data.fallingBlock).toBeDefined(); + expect(data.fallingBlock).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.fallingBlock).toEqualTypeOf(); + expect(data.lava).toBeDefined(); + expect(data.lava).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.lava).toEqualTypeOf(); + expect(data.contact).toBeDefined(); + expect(data.contact).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.contact).toEqualTypeOf(); + expect(data.thorns).toBeDefined(); + expect(data.thorns).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.thorns).toEqualTypeOf(); + expect(data.wither).toBeDefined(); + expect(data.wither).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.wither).toEqualTypeOf(); + expect(data.blockExplosion).toBeDefined(); + expect(data.blockExplosion).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data.blockExplosion).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.ts b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.ts new file mode 100644 index 000000000..d7bc1af4c --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.ts @@ -0,0 +1,45 @@ +import BedWarsKillsDeathsType from './BedWarsKillsDeathsType.js'; +import type { BedWarsModeId } from '../../../../Types/Player.js'; + +class BedWarsKillsDeaths { + total: BedWarsKillsDeathsType; + custom: BedWarsKillsDeathsType; + drowning: BedWarsKillsDeathsType; + entityAttack: BedWarsKillsDeathsType; + entityExplosion: BedWarsKillsDeathsType; + fall: BedWarsKillsDeathsType; + fire: BedWarsKillsDeathsType; + fireTick: BedWarsKillsDeathsType; + magic: BedWarsKillsDeathsType; + projectile: BedWarsKillsDeathsType; + suffocation: BedWarsKillsDeathsType; + void: BedWarsKillsDeathsType; + fallingBlock: BedWarsKillsDeathsType; + lava: BedWarsKillsDeathsType; + contact: BedWarsKillsDeathsType; + thorns: BedWarsKillsDeathsType; + wither: BedWarsKillsDeathsType; + blockExplosion: BedWarsKillsDeathsType; + constructor(data: Record, mode?: BedWarsModeId, finals?: boolean) { + this.total = new BedWarsKillsDeathsType(data, '', mode, finals); + this.custom = new BedWarsKillsDeathsType(data, 'custom', mode, finals); + this.drowning = new BedWarsKillsDeathsType(data, 'drowning', mode, finals); + this.entityAttack = new BedWarsKillsDeathsType(data, 'entity_attack', mode, finals); + this.entityExplosion = new BedWarsKillsDeathsType(data, 'entity_explosion', mode, finals); + this.fall = new BedWarsKillsDeathsType(data, 'fall', mode, finals); + this.fire = new BedWarsKillsDeathsType(data, 'fire', mode, finals); + this.fireTick = new BedWarsKillsDeathsType(data, 'fire_tick', mode, finals); + this.magic = new BedWarsKillsDeathsType(data, 'magic', mode, finals); + this.projectile = new BedWarsKillsDeathsType(data, 'projectile', mode, finals); + this.suffocation = new BedWarsKillsDeathsType(data, 'suffocation', mode, finals); + this.void = new BedWarsKillsDeathsType(data, 'void', mode, finals); + this.fallingBlock = new BedWarsKillsDeathsType(data, 'falling_block', mode, finals); + this.lava = new BedWarsKillsDeathsType(data, 'lava', mode, finals); + this.contact = new BedWarsKillsDeathsType(data, 'contact', mode, finals); + this.thorns = new BedWarsKillsDeathsType(data, 'thorns', mode, finals); + this.wither = new BedWarsKillsDeathsType(data, 'wither', mode, finals); + this.blockExplosion = new BedWarsKillsDeathsType(data, 'block_explosion', mode, finals); + } +} + +export default BedWarsKillsDeaths; diff --git a/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.test.ts b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.test.ts new file mode 100644 index 000000000..8198265fa --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.test.ts @@ -0,0 +1,18 @@ +import BedWarsKillsDeathsType from './BedWarsKillsDeathsType.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsKillsDeathsType', () => { + const data = new BedWarsKillsDeathsType({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsKillsDeathsType); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.ratio).toBeDefined(); + expect(data.ratio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ratio).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.ts b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.ts new file mode 100644 index 000000000..de5681ade --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.ts @@ -0,0 +1,17 @@ +import BaseKillsDeathsType from '../../Shared/BaseKillDeathsType.ts'; +import Divide from '../../../../Utils/Divide.ts'; +import { ParseModeBefore } from '../../../../Utils/ParseMode.ts'; +import type { BedWarsFinalType, BedWarsModeId } from '../../../../Types/Player.js'; + +class BedWarsKillsDeathsType extends BaseKillsDeathsType { + constructor(data: Record, type?: BedWarsFinalType, mode?: BedWarsModeId, finals: boolean = false) { + type = ParseModeBefore(type) as BedWarsFinalType; + mode = ParseModeBefore(mode) as BedWarsModeId; + super(data); + this.kills = data?.[`${mode}${type}${finals ? 'final_' : ''}kills_bedwars`] || 0; + this.deaths = data?.[`${mode}${type}${finals ? 'final_' : ''}deaths_bedwars`] || 0; + this.ratio = Divide(this.kills, this.deaths); + } +} + +export default BedWarsKillsDeathsType; diff --git a/src/Structures/MiniGames/BedWars/BedWarsMode.test.ts b/src/Structures/MiniGames/BedWars/BedWarsMode.test.ts new file mode 100644 index 000000000..c79a223e1 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsMode.test.ts @@ -0,0 +1,39 @@ +import BedWarsBeds from './BedWarsBeds.js'; +import BedWarsKillsDeaths from './BedWarsKillsDeaths/BedWarsKillsDeaths.js'; +import BedWarsMode from './BedWarsMode.js'; +import BedWarsResourcesCollected from './BedWarsResourcesCollected.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsMode', () => { + const data = new BedWarsMode({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.resourcesCollected).toBeDefined(); + expect(data.resourcesCollected).toBeInstanceOf(BedWarsResourcesCollected); + expectTypeOf(data.resourcesCollected).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeInstanceOf(BedWarsKillsDeaths); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.finals).toBeDefined(); + expect(data.finals).toBeInstanceOf(BedWarsKillsDeaths); + expectTypeOf(data.finals).toEqualTypeOf(); + expect(data.beds).toBeDefined(); + expect(data.beds).toBeInstanceOf(BedWarsBeds); + expectTypeOf(data.beds).toEqualTypeOf(); + expect(data.winstreak).toBeDefined(); + expect(data.winstreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winstreak).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.winLossRatio).toBeDefined(); + expect(data.winLossRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winLossRatio).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsMode.ts b/src/Structures/MiniGames/BedWars/BedWarsMode.ts new file mode 100644 index 000000000..383181fa4 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsMode.ts @@ -0,0 +1,32 @@ +import BedWarsBeds from './BedWarsBeds.js'; +import BedWarsKillsDeaths from './BedWarsKillsDeaths/BedWarsKillsDeaths.js'; +import BedWarsResourcesCollected from './BedWarsResourcesCollected.js'; +import Divide from '../../../Utils/Divide.js'; +import { ParseModeBefore } from '../../../Utils/ParseMode.ts'; +import type { BedWarsModeId } from '../../../Types/Player.js'; + +class BedWarsMode { + resourcesCollected: BedWarsResourcesCollected; + kills: BedWarsKillsDeaths; + finals: BedWarsKillsDeaths; + beds: BedWarsBeds; + winstreak: number; + wins: number; + losses: number; + winLossRatio: number; + gamesPlayed: number; + constructor(data: Record, mode?: BedWarsModeId) { + mode = ParseModeBefore(mode) as BedWarsModeId; + this.resourcesCollected = new BedWarsResourcesCollected(data, mode); + this.kills = new BedWarsKillsDeaths(data, mode); + this.finals = new BedWarsKillsDeaths(data, mode, true); + this.beds = new BedWarsBeds(data, mode); + this.winstreak = data?.[`${mode}winstreak`] || 0; + this.wins = data?.[`${mode}wins_bedwars`] || 0; + this.losses = data?.[`${mode}losses_bedwars`] || 0; + this.winLossRatio = Divide(this.wins, this.losses); + this.gamesPlayed = data?.[`${mode}games_played_bedwars`] || 0; + } +} + +export default BedWarsMode; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.test.ts new file mode 100644 index 000000000..5f60e326e --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.test.ts @@ -0,0 +1,26 @@ +import BedWarsPractice from './BedWarsPractice.js'; +import BedWarsPracticeBridging from './BedWarsPracticeBridging.js'; +import BedWarsPracticeMode from './BedWarsPracticeMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BedWarsPracticeModeId } from '../../../../Types/Player.js'; + +test('BedWarsPractice', () => { + const data = new BedWarsPractice({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPractice); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bridging).toBeDefined(); + expect(data.bridging).toBeInstanceOf(BedWarsPracticeBridging); + expectTypeOf(data.bridging).toEqualTypeOf(); + expect(data.fireballJumping).toBeDefined(); + expect(data.fireballJumping).toBeInstanceOf(BedWarsPracticeMode); + expectTypeOf(data.fireballJumping).toEqualTypeOf(); + expect(data.mlg).toBeDefined(); + expect(data.mlg).toBeInstanceOf(BedWarsPracticeMode); + expectTypeOf(data.mlg).toEqualTypeOf(); + expect(data.pearlClutching).toBeDefined(); + expect(data.pearlClutching).toBeInstanceOf(BedWarsPracticeMode); + expectTypeOf(data.pearlClutching).toEqualTypeOf(); + expect(data.selected).toBeDefined(); + expectTypeOf(data.selected).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.ts new file mode 100644 index 000000000..67758145e --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.ts @@ -0,0 +1,20 @@ +import BedWarsPracticeBridging from './BedWarsPracticeBridging.js'; +import BedWarsPracticeMode from './BedWarsPracticeMode.js'; +import type { BedWarsPracticeModeId } from '../../../../Types/Player.js'; + +class BedWarsPractice { + bridging: BedWarsPracticeBridging; + fireballJumping: BedWarsPracticeMode; + mlg: BedWarsPracticeMode; + pearlClutching: BedWarsPracticeMode; + selected: BedWarsPracticeModeId | 'UNKNOWN'; + constructor(data: Record) { + this.bridging = new BedWarsPracticeBridging(data?.bridging || {}, data?.records || {}); + this.fireballJumping = new BedWarsPracticeMode(data?.fireball_jumping || {}); + this.mlg = new BedWarsPracticeMode(data?.mlg || {}); + this.pearlClutching = new BedWarsPracticeMode(data?.pearl_clutching || {}); + this.selected = data?.selected || 'UNKNOWN'; + } +} + +export default BedWarsPractice; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.test.ts new file mode 100644 index 000000000..10e56f86b --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.test.ts @@ -0,0 +1,13 @@ +import BedWarsPracticeBridging from './BedWarsPracticeBridging.js'; +import BedWarsPracticeBridgingRecords from './BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsPracticeBridging', () => { + const data = new BedWarsPracticeBridging({ stats: 'meow' }, { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPracticeBridging); + expectTypeOf(data).toEqualTypeOf(); + expect(data.records).toBeDefined(); + expect(data.records).toBeInstanceOf(BedWarsPracticeBridgingRecords); + expectTypeOf(data.records).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.ts new file mode 100644 index 000000000..eadab3085 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.ts @@ -0,0 +1,12 @@ +import BedWarsPracticeBridgingRecords from './BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.js'; +import BedWarsPracticeMode from './BedWarsPracticeMode.js'; + +class BedWarsPracticeBridging extends BedWarsPracticeMode { + records: BedWarsPracticeBridgingRecords; + constructor(data: Record, records: Record) { + super(data); + this.records = new BedWarsPracticeBridgingRecords(records); + } +} + +export default BedWarsPracticeBridging; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.test.ts new file mode 100644 index 000000000..d252b72b0 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.test.ts @@ -0,0 +1,19 @@ +import BedWarsPracticeBridgingRecords from './BedWarsPracticeBridgingRecords.js'; +import BedWarsPracticeBridgingRecordsDistance from './BedWarsPracticeBridgingRecordsDistance.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsPracticeBridgingRecords', () => { + const data = new BedWarsPracticeBridgingRecords({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPracticeBridgingRecords); + expectTypeOf(data).toEqualTypeOf(); + expect(data.blocks100).toBeDefined(); + expect(data.blocks100).toBeInstanceOf(BedWarsPracticeBridgingRecordsDistance); + expectTypeOf(data.blocks100).toEqualTypeOf(); + expect(data.blocks50).toBeDefined(); + expect(data.blocks50).toBeInstanceOf(BedWarsPracticeBridgingRecordsDistance); + expectTypeOf(data.blocks50).toEqualTypeOf(); + expect(data.blocks30).toBeDefined(); + expect(data.blocks30).toBeInstanceOf(BedWarsPracticeBridgingRecordsDistance); + expectTypeOf(data.blocks30).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.ts new file mode 100644 index 000000000..35038a341 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.ts @@ -0,0 +1,14 @@ +import BedWarsPracticeBridgingRecordsDistance from './BedWarsPracticeBridgingRecordsDistance.js'; + +class BedWarsPracticeBridgingRecords { + blocks100: BedWarsPracticeBridgingRecordsDistance; + blocks50: BedWarsPracticeBridgingRecordsDistance; + blocks30: BedWarsPracticeBridgingRecordsDistance; + constructor(data: Record) { + this.blocks100 = new BedWarsPracticeBridgingRecordsDistance(data, '100'); + this.blocks50 = new BedWarsPracticeBridgingRecordsDistance(data, '50'); + this.blocks30 = new BedWarsPracticeBridgingRecordsDistance(data, '30'); + } +} + +export default BedWarsPracticeBridgingRecords; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.test.ts new file mode 100644 index 000000000..f3e3320b5 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.test.ts @@ -0,0 +1,19 @@ +import BedWarsPracticeBridgingRecordsDistance from './BedWarsPracticeBridgingRecordsDistance.js'; +import BedWarsPracticeBridgingRecordsEevation from './BedWarsPracticeBridgingRecordsEevation.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsPracticeBridgingRecordsDistance', () => { + const data = new BedWarsPracticeBridgingRecordsDistance({ stats: 'meow' }, '100'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPracticeBridgingRecordsDistance); + expectTypeOf(data).toEqualTypeOf(); + expect(data.none).toBeDefined(); + expect(data.none).toBeInstanceOf(BedWarsPracticeBridgingRecordsEevation); + expectTypeOf(data.none).toEqualTypeOf(); + expect(data.slight).toBeDefined(); + expect(data.slight).toBeInstanceOf(BedWarsPracticeBridgingRecordsEevation); + expectTypeOf(data.slight).toEqualTypeOf(); + expect(data.staircase).toBeDefined(); + expect(data.staircase).toBeInstanceOf(BedWarsPracticeBridgingRecordsEevation); + expectTypeOf(data.staircase).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.ts new file mode 100644 index 000000000..1add09ee4 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.ts @@ -0,0 +1,15 @@ +import BedWarsPracticeBridgingRecordsEevation from './BedWarsPracticeBridgingRecordsEevation.js'; +import type { BedWarsPracticeBridgingRecordsDistances } from '../../../../../Types/Player.js'; + +class BedWarsPracticeBridgingRecordsDistance { + none: BedWarsPracticeBridgingRecordsEevation; + slight: BedWarsPracticeBridgingRecordsEevation; + staircase: BedWarsPracticeBridgingRecordsEevation; + constructor(data: Record, distance: BedWarsPracticeBridgingRecordsDistances) { + this.none = new BedWarsPracticeBridgingRecordsEevation(data, distance, 'NONE'); + this.slight = new BedWarsPracticeBridgingRecordsEevation(data, distance, 'SLIGHT'); + this.staircase = new BedWarsPracticeBridgingRecordsEevation(data, distance, 'STAIRCASE'); + } +} + +export default BedWarsPracticeBridgingRecordsDistance; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.test.ts new file mode 100644 index 000000000..a5b916ae0 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.test.ts @@ -0,0 +1,15 @@ +import BedWarsPracticeBridgingRecordsEevation from './BedWarsPracticeBridgingRecordsEevation.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsPracticeBridgingRecordsEevation', () => { + const data = new BedWarsPracticeBridgingRecordsEevation({ stats: 'meow' }, '100', 'NONE'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPracticeBridgingRecordsEevation); + expectTypeOf(data).toEqualTypeOf(); + expect(data.diagonal).toBeDefined(); + expect(data.diagonal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diagonal).toEqualTypeOf(); + expect(data.straight).toBeDefined(); + expect(data.straight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.straight).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.ts new file mode 100644 index 000000000..2dcf92dd1 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.ts @@ -0,0 +1,19 @@ +import type { + BedWarsPracticeBridgingRecordsDistances, + BedWarsPracticeBridgingRecordsElevations +} from '../../../../../Types/Player.js'; + +class BedWarsPracticeBridgingRecordsEevation { + diagonal: number; + straight: number; + constructor( + data: Record, + distance: BedWarsPracticeBridgingRecordsDistances, + elevation: BedWarsPracticeBridgingRecordsElevations + ) { + this.diagonal = data?.[`bridging_distance_${distance}:elevation_${elevation}:angle_DIAGONAL`] || 0; + this.straight = data?.[`bridging_distance_${distance}:elevation_${elevation}:angle_STRAIGHT`] || 0; + } +} + +export default BedWarsPracticeBridgingRecordsEevation; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.test.ts new file mode 100644 index 000000000..3e4264153 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.test.ts @@ -0,0 +1,24 @@ +import BedWarsPracticeMode from './BedWarsPracticeMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsPracticeMode', () => { + const data = new BedWarsPracticeMode({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPracticeMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.successfulAttempts).toBeDefined(); + expect(data.successfulAttempts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.successfulAttempts).toEqualTypeOf(); + expect(data.failedAttempts).toBeDefined(); + expect(data.failedAttempts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.failedAttempts).toEqualTypeOf(); + expect(data.attempts).toBeDefined(); + expect(data.attempts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.attempts).toEqualTypeOf(); + expect(data.successfulRatio).toBeDefined(); + expect(data.successfulRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.successfulRatio).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.ts b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.ts new file mode 100644 index 000000000..afef64ad4 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.ts @@ -0,0 +1,18 @@ +import Divide from '../../../../Utils/Divide.js'; + +class BedWarsPracticeMode { + blocksPlaced: number; + successfulAttempts: number; + failedAttempts: number; + attempts: number; + successfulRatio: number; + constructor(data: Record) { + this.blocksPlaced = data?.blocks_placed || 0; + this.successfulAttempts = data?.successful_attempts || 0; + this.failedAttempts = data?.failed_attempts || 0; + this.attempts = this.successfulAttempts + this.failedAttempts; + this.successfulRatio = Divide(this.successfulAttempts, this.failedAttempts); + } +} + +export default BedWarsPracticeMode; diff --git a/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.test.ts b/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.test.ts new file mode 100644 index 000000000..50f413fac --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.test.ts @@ -0,0 +1,37 @@ +import BedWarsPrivateGameSettings from './BedWarsPrivateGameSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + BedWarsPrivateGameSettingsEventTime, + BedWarsPrivateGameSettingsRespawnTime, + PrivateGameSettingsGameSpeed, + PrivateGameSettingsHealthBuff +} from '../../../Types/Player.js'; + +test('BedWarsPrivateGameSettings', () => { + const data = new BedWarsPrivateGameSettings({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsPrivateGameSettings); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bedInstaBreak).toBeDefined(); + expectTypeOf(data.bedInstaBreak).toEqualTypeOf(); + expect(data.disableBlockProtection).toBeDefined(); + expectTypeOf(data.disableBlockProtection).toEqualTypeOf(); + expect(data.eventTime).toBeDefined(); + expectTypeOf(data.eventTime).toEqualTypeOf(); + expect(data.healthBuff).toBeDefined(); + expectTypeOf(data.healthBuff).toEqualTypeOf(); + expect(data.lowGravity).toBeDefined(); + expectTypeOf(data.lowGravity).toEqualTypeOf(); + expect(data.maxTeamUpgrades).toBeDefined(); + expectTypeOf(data.maxTeamUpgrades).toEqualTypeOf(); + expect(data.noDiamonds).toBeDefined(); + expectTypeOf(data.noDiamonds).toEqualTypeOf(); + expect(data.noEmeralds).toBeDefined(); + expectTypeOf(data.noEmeralds).toEqualTypeOf(); + expect(data.oneHitOneKill).toBeDefined(); + expectTypeOf(data.oneHitOneKill).toEqualTypeOf(); + expect(data.respawnTime).toBeDefined(); + expectTypeOf(data.respawnTime).toEqualTypeOf(); + expect(data.speed).toBeDefined(); + expectTypeOf(data.speed).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.ts b/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.ts new file mode 100644 index 000000000..38512cbdc --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.ts @@ -0,0 +1,35 @@ +import type { + BedWarsPrivateGameSettingsEventTime, + BedWarsPrivateGameSettingsRespawnTime, + PrivateGameSettingsGameSpeed, + PrivateGameSettingsHealthBuff +} from '../../../Types/Player.js'; + +class BedWarsPrivateGameSettings { + bedInstaBreak: boolean; + disableBlockProtection: boolean; + eventTime: BedWarsPrivateGameSettingsEventTime; + healthBuff: PrivateGameSettingsHealthBuff; + lowGravity: boolean; + maxTeamUpgrades: boolean; + noDiamonds: boolean; + noEmeralds: boolean; + oneHitOneKill: boolean; + respawnTime: BedWarsPrivateGameSettingsRespawnTime; + speed: PrivateGameSettingsGameSpeed; + constructor(data: Record) { + this.bedInstaBreak = data?.bed_instabreak || false; + this.disableBlockProtection = data?.disable_block_protection || false; + this.eventTime = data?.event_time || '1x - Normal'; + this.healthBuff = data?.health_buff || 'Normal Health'; + this.lowGravity = data?.low_gravity || false; + this.maxTeamUpgrades = data?.max_team_upgrades || false; + this.noDiamonds = data?.no_diamonds || false; + this.noEmeralds = data?.no_emeralds || false; + this.oneHitOneKill = data?.one_hit_one_kill || false; + this.respawnTime = data?.respawn_time || '5 Seconds'; + this.speed = data?.speed || 'No Speed'; + } +} + +export default BedWarsPrivateGameSettings; diff --git a/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.test.ts b/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.test.ts new file mode 100644 index 000000000..3b11ae887 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.test.ts @@ -0,0 +1,34 @@ +import BedWarsItemsPurchased from './BedWarsItemsPurchased.js'; +import BedWarsResourcesCollected from './BedWarsResourcesCollected.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsResourcesCollected', () => { + const data = new BedWarsResourcesCollected({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsResourcesCollected); + expectTypeOf(data).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.emerald).toBeDefined(); + expect(data.emerald).toBeGreaterThanOrEqual(0); + expectTypeOf(data.emerald).toEqualTypeOf(); + expect(data.diamond).toBeDefined(); + expect(data.diamond).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamond).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expect(data.gold).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gold).toEqualTypeOf(); + expect(data.iron).toBeDefined(); + expect(data.iron).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iron).toEqualTypeOf(); + expect(data.wrappedPresent).toBeDefined(); + expect(data.wrappedPresent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wrappedPresent).toEqualTypeOf(); + expect(data.bed).toBeDefined(); + expect(data.bed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bed).toEqualTypeOf(); + expect(data.itemsPurchased).toBeDefined(); + expect(data.itemsPurchased).toBeInstanceOf(BedWarsItemsPurchased); + expectTypeOf(data.itemsPurchased).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.ts b/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.ts new file mode 100644 index 000000000..a30c04e95 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsResourcesCollected.ts @@ -0,0 +1,27 @@ +import BedWarsItemsPurchased from './BedWarsItemsPurchased.js'; +import { ParseModeBefore } from '../../../Utils/ParseMode.ts'; +import type { BedWarsModeId } from '../../../Types/Player.js'; + +class BedWarsResourcesCollected { + total: number; + emerald: number; + diamond: number; + gold: number; + iron: number; + wrappedPresent: number; + bed: number; + itemsPurchased: BedWarsItemsPurchased; + constructor(data: Record, mode?: BedWarsModeId) { + mode = ParseModeBefore(mode) as BedWarsModeId; + this.total = data?.[`${mode}resources_collected_bedwars`] || 0; + this.emerald = data?.[`${mode}emerald_resources_collected_bedwars`] || 0; + this.diamond = data?.[`${mode}diamond_resources_collected_bedwars`] || 0; + this.gold = data?.[`${mode}gold_resources_collected_bedwars`] || 0; + this.iron = data?.[`${mode}iron_resources_collected_bedwars`] || 0; + this.wrappedPresent = data?.[`${mode}wrapped_present_resources_collected_bedwars`] || 0; + this.bed = data?.[`${mode}bed_resources_collected_bedwars`] || 0; + this.itemsPurchased = new BedWarsItemsPurchased(data, mode); + } +} + +export default BedWarsResourcesCollected; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSettings.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSettings.test.ts new file mode 100644 index 000000000..c9a125cca --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSettings.test.ts @@ -0,0 +1,18 @@ +import BedWarsSettings from './BedWarsSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BedWarsSettingsDeposit, BedWarsSettingsSlumberItemNotification } from '../../../Types/Player.js'; + +test('BedWarsSettings', () => { + const data = new BedWarsSettings({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSettings); + expectTypeOf(data).toEqualTypeOf(); + expect(data.deposit).toBeDefined(); + expectTypeOf(data.deposit).toEqualTypeOf(); + expect(data.slumberItemNotification).toBeDefined(); + expectTypeOf(data.slumberItemNotification).toEqualTypeOf(); + expect(data.slumberWalletFull).toBeDefined(); + expectTypeOf(data.slumberWalletFull).toEqualTypeOf(); + expect(data.trapRemoval).toBeDefined(); + expectTypeOf(data.trapRemoval).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSettings.ts b/src/Structures/MiniGames/BedWars/BedWarsSettings.ts new file mode 100644 index 000000000..d4af5ed3d --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSettings.ts @@ -0,0 +1,16 @@ +import type { BedWarsSettingsDeposit, BedWarsSettingsSlumberItemNotification } from '../../../Types/Player.js'; + +class BedWarsSettings { + deposit: BedWarsSettingsDeposit; + slumberItemNotification: BedWarsSettingsSlumberItemNotification; + slumberWalletFull: boolean; + trapRemoval: boolean; + constructor(data: Record) { + this.deposit = data?.deposit || 'ENABLED'; + this.slumberItemNotification = data?.slumberItemNotification || 'CHAT_MESSAGES'; + this.slumberWalletFull = data?.slumberWalletFull || true; + this.trapRemoval = data?.trapRemoval || false; + } +} + +export default BedWarsSettings; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.test.ts new file mode 100644 index 000000000..153048c6c --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.test.ts @@ -0,0 +1,57 @@ +import BedWarsSLumberSandman from './BedWarsSlumberSandman.js'; +import BedWarsSlumber from './BedWarsSlumber.js'; +import BedWarsSlumberMinion from './BedWarsSlumberMinion.js'; +import BedWarsSlumberPhase from './BedWarsSlumberPhase.js'; +import BedWarsSlumberPhaseThree from './BedWarsSlumberPhaseThree.js'; +import BedWarsSlumberQuest from './BedWarsSlumberQuest/BedWarsSlumberQuest.js'; +import BedWarsSlumberRoom from './BedWarsSlumberRoom.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BedWarsSlumberBag, ShopSort } from '../../../../Types/Player.js'; + +test('BedWarsSlumber', () => { + const data = new BedWarsSlumber({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumber); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bagType).toBeDefined(); + expectTypeOf(data.bagType).toEqualTypeOf(); + expect(data.boonMultiplier).toBeDefined(); + expect(data.boonMultiplier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boonMultiplier).toEqualTypeOf(); + expect(data.currentCosmeticSorting).toBeDefined(); + expectTypeOf(data.currentCosmeticSorting).toEqualTypeOf(); + expect(data.doublers).toBeDefined(); + expect(data.doublers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doublers).toEqualTypeOf(); + expect(data.minion).toBeDefined(); + expect(data.minion).toBeInstanceOf(BedWarsSlumberMinion); + expectTypeOf(data.minion).toEqualTypeOf(); + expect(data.phase).toBeDefined(); + expect(data.phase).toBeInstanceOf(BedWarsSlumberPhase); + expectTypeOf(data.phase).toEqualTypeOf(); + expect(data.phasethree).toBeDefined(); + expect(data.phasethree).toBeInstanceOf(BedWarsSlumberPhaseThree); + expectTypeOf(data.phasethree).toEqualTypeOf(); + expect(data.quest).toBeDefined(); + expect(data.quest).toBeInstanceOf(BedWarsSlumberQuest); + expectTypeOf(data.quest).toEqualTypeOf(); + expect(data.rooms).toBeDefined(); + expect(data.rooms).toBeInstanceOf(BedWarsSlumberRoom); + expectTypeOf(data.rooms).toEqualTypeOf(); + expect(data.sandman).toBeDefined(); + expect(data.sandman).toBeInstanceOf(BedWarsSLumberSandman); + expectTypeOf(data.sandman).toEqualTypeOf(); + expect(data.tickets).toBeDefined(); + expect(data.tickets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tickets).toEqualTypeOf(); + expect(data.ticketsGivenToDoorman).toBeDefined(); + expect(data.ticketsGivenToDoorman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ticketsGivenToDoorman).toEqualTypeOf(); + expect(data.ticketsRequirementMet).toBeDefined(); + expectTypeOf(data.ticketsRequirementMet).toEqualTypeOf(); + expect(data.totalTicketsEarned).toBeDefined(); + expect(data.totalTicketsEarned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalTicketsEarned).toEqualTypeOf(); + expect(data.walletFullWarning).toBeDefined(); + expectTypeOf(data.walletFullWarning).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.ts new file mode 100644 index 000000000..91721f509 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.ts @@ -0,0 +1,44 @@ +import BedWarsSLumberSandman from './BedWarsSlumberSandman.js'; +import BedWarsSlumberMinion from './BedWarsSlumberMinion.js'; +import BedWarsSlumberPhase from './BedWarsSlumberPhase.js'; +import BedWarsSlumberPhaseThree from './BedWarsSlumberPhaseThree.js'; +import BedWarsSlumberQuest from './BedWarsSlumberQuest/BedWarsSlumberQuest.js'; +import BedWarsSlumberRoom from './BedWarsSlumberRoom.js'; +import type { BedWarsSlumberBag, ShopSort } from '../../../../Types/Player.js'; + +class BedWarsSlumber { + bagType: BedWarsSlumberBag | 'UNKNOWN'; + boonMultiplier: number; + currentCosmeticSorting: ShopSort | 'UNKNOWN'; + doublers: number; + minion: BedWarsSlumberMinion; + phase: BedWarsSlumberPhase; + phasethree: BedWarsSlumberPhaseThree; + quest: BedWarsSlumberQuest; + rooms: BedWarsSlumberRoom; + sandman: BedWarsSLumberSandman; + tickets: number; + ticketsGivenToDoorman: number; + ticketsRequirementMet: boolean; + totalTicketsEarned: number; + walletFullWarning: boolean; + constructor(data: Record) { + this.bagType = data?.bag_type || 'UNKNOWN'; + this.boonMultiplier = data?.boon_multiplier || 0; + this.currentCosmeticSorting = data?.currentCosmeticSorting || 'UNKNOWN'; + this.doublers = data?.doublers || 0; + this.minion = new BedWarsSlumberMinion(data?.minion || {}); + this.phase = new BedWarsSlumberPhase(data?.phase || {}); + this.phasethree = new BedWarsSlumberPhaseThree(data?.phasethree || {}); + this.quest = new BedWarsSlumberQuest(data?.quest || {}); + this.rooms = new BedWarsSlumberRoom(data?.room || {}); + this.sandman = new BedWarsSLumberSandman(data?.sandman || {}); + this.tickets = data?.tickets || 0; + this.ticketsGivenToDoorman = data?.tickets_given_doorman || 0; + this.ticketsRequirementMet = data?.tickets_requirement_met || false; + this.totalTicketsEarned = data?.total_tickets_earned || 0; + this.walletFullWarning = data?.wallet_full_warning || false; + } +} + +export default BedWarsSlumber; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.test.ts new file mode 100644 index 000000000..0c60da22e --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.test.ts @@ -0,0 +1,24 @@ +import BedWarsSlumberMinion from './BedWarsSlumberMinion.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberMinion', () => { + const data = new BedWarsSlumberMinion({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberMinion); + expectTypeOf(data).toEqualTypeOf(); + expect(data.enderDust).toBeDefined(); + expect(data.enderDust).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderDust).toEqualTypeOf(); + expect(data.enderDustCollected).toBeDefined(); + expect(data.enderDustCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderDustCollected).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeGreaterThanOrEqual(0); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.tickets).toBeDefined(); + expect(data.tickets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tickets).toEqualTypeOf(); + expect(data.ticketsCollected).toBeDefined(); + expect(data.ticketsCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ticketsCollected).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.ts new file mode 100644 index 000000000..8f6a1fa14 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.ts @@ -0,0 +1,16 @@ +class BedWarsSlumberMinion { + enderDust: number; + enderDustCollected: number; + games: number; + tickets: number; + ticketsCollected: number; + constructor(data: Record) { + this.enderDust = data?.ender_dust || 0; + this.enderDustCollected = data?.ender_dust_collected || 0; + this.games = data?.games || 0; + this.tickets = data?.tickets || 0; + this.ticketsCollected = data?.tickets_collected || 0; + } +} + +export default BedWarsSlumberMinion; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.test.ts new file mode 100644 index 000000000..7d4aa204d --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.test.ts @@ -0,0 +1,12 @@ +import BedWarsSlumberPhase from './BedWarsSlumberPhase.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberPhase', () => { + const data = new BedWarsSlumberPhase({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberPhase); + expectTypeOf(data).toEqualTypeOf(); + expect(data.current).toBeDefined(); + expect(data.current).toBeGreaterThanOrEqual(0); + expectTypeOf(data.current).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.ts new file mode 100644 index 000000000..18e7ab349 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.ts @@ -0,0 +1,8 @@ +class BedWarsSlumberPhase { + current: number; + constructor(data: Record) { + this.current = data?.current || 0; + } +} + +export default BedWarsSlumberPhase; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.test.ts new file mode 100644 index 000000000..1789d662a --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.test.ts @@ -0,0 +1,12 @@ +import BedWarsSlumberPhaseThree from './BedWarsSlumberPhaseThree.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberPhaseThree', () => { + const data = new BedWarsSlumberPhaseThree({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberPhaseThree); + expectTypeOf(data).toEqualTypeOf(); + expect(data.completedQuests).toBeDefined(); + expect(data.completedQuests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completedQuests).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.ts new file mode 100644 index 000000000..733292123 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.ts @@ -0,0 +1,8 @@ +class BedWarsSlumberPhaseThree { + completedQuests: number; + constructor(data: Record) { + this.completedQuests = data?.completed_quests || 0; + } +} + +export default BedWarsSlumberPhaseThree; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.test.ts new file mode 100644 index 000000000..1cf98bd9f --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.test.ts @@ -0,0 +1,39 @@ +import BedWarsSlumberQuest from './BedWarsSlumberQuest.js'; +import BedWarsSlumberQuestGamblerGeorge from './BedWarsSlumberQuestGamblerGeorge.js'; +import BedWarsSlumberQuestItem from './BedWarsSlumberQuestItem.js'; +import BedWarsSlumberQuestNPC from './BedWarsSlumberQuestNPC.js'; +import BedWarsSlumberQuestNPCSBoolean from './BedWarsSlumberQuestNPCSBoolean.js'; +import BedWarsSlumberQuestNPCSNumber from './BedWarsSlumberQuestNPCSNumber.js'; +import BedWarsSlumberQuestObjective from './BedWarsSlumberQuestObjective.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuest', () => { + const data = new BedWarsSlumberQuest({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.completed).toBeDefined(); + expect(data.completed).toBeInstanceOf(BedWarsSlumberQuestNPCSBoolean); + expectTypeOf(data.completed).toEqualTypeOf(); + expect(data.gamblerGeorge).toBeDefined(); + expect(data.gamblerGeorge).toBeInstanceOf(BedWarsSlumberQuestGamblerGeorge); + expectTypeOf(data.gamblerGeorge).toEqualTypeOf(); + expect(data.item).toBeDefined(); + expect(data.item).toBeInstanceOf(BedWarsSlumberQuestItem); + expectTypeOf(data.item).toEqualTypeOf(); + expect(data.lastCompleted).toBeDefined(); + expect(data.lastCompleted).toBeInstanceOf(BedWarsSlumberQuestNPCSNumber); + expectTypeOf(data.lastCompleted).toEqualTypeOf(); + expect(data.lastStarted).toBeDefined(); + expect(data.lastStarted).toBeInstanceOf(BedWarsSlumberQuestNPCSNumber); + expectTypeOf(data.lastStarted).toEqualTypeOf(); + expect(data.npc).toBeDefined(); + expect(data.npc).toBeInstanceOf(BedWarsSlumberQuestNPC); + expectTypeOf(data.npc).toEqualTypeOf(); + expect(data.objective).toBeDefined(); + expect(data.objective).toBeInstanceOf(BedWarsSlumberQuestObjective); + expectTypeOf(data.objective).toEqualTypeOf(); + expect(data.started).toBeDefined(); + expect(data.started).toBeInstanceOf(BedWarsSlumberQuestNPCSBoolean); + expectTypeOf(data.started).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.ts new file mode 100644 index 000000000..fe9113bc8 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.ts @@ -0,0 +1,29 @@ +import BedWarsSlumberQuestGamblerGeorge from './BedWarsSlumberQuestGamblerGeorge.js'; +import BedWarsSlumberQuestItem from './BedWarsSlumberQuestItem.js'; +import BedWarsSlumberQuestNPC from './BedWarsSlumberQuestNPC.js'; +import BedWarsSlumberQuestNPCSBoolean from './BedWarsSlumberQuestNPCSBoolean.js'; +import BedWarsSlumberQuestNPCSNumber from './BedWarsSlumberQuestNPCSNumber.js'; +import BedWarsSlumberQuestObjective from './BedWarsSlumberQuestObjective.js'; + +class BedWarsSlumberQuest { + completed: BedWarsSlumberQuestNPCSBoolean; + gamblerGeorge: BedWarsSlumberQuestGamblerGeorge; + item: BedWarsSlumberQuestItem; + lastCompleted: BedWarsSlumberQuestNPCSNumber; + lastStarted: BedWarsSlumberQuestNPCSNumber; + npc: BedWarsSlumberQuestNPC; + objective: BedWarsSlumberQuestObjective; + started: BedWarsSlumberQuestNPCSBoolean; + constructor(data: Record) { + this.completed = new BedWarsSlumberQuestNPCSBoolean(data?.completed || {}); + this.gamblerGeorge = new BedWarsSlumberQuestGamblerGeorge(data?.gambler_george || {}); + this.item = new BedWarsSlumberQuestItem(data?.item || {}); + this.lastCompleted = new BedWarsSlumberQuestNPCSNumber(data?.lastCompleted || {}); + this.lastStarted = new BedWarsSlumberQuestNPCSNumber(data?.lastStarted || {}); + this.npc = new BedWarsSlumberQuestNPC(data?.npc || {}); + this.objective = new BedWarsSlumberQuestObjective(data?.objective || {}); + this.started = new BedWarsSlumberQuestNPCSBoolean(data?.started || {}); + } +} + +export default BedWarsSlumberQuest; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.test.ts new file mode 100644 index 000000000..cbf129504 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.test.ts @@ -0,0 +1,24 @@ +import BedWarsSlumberQuestGamblerGeorge from './BedWarsSlumberQuestGamblerGeorge.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestGamblerGeorge', () => { + const data = new BedWarsSlumberQuestGamblerGeorge({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestGamblerGeorge); + expectTypeOf(data).toEqualTypeOf(); + expect(data.betAmount).toBeDefined(); + expect(data.betAmount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.betAmount).toEqualTypeOf(); + expect(data.gambleGamesWon).toBeDefined(); + expect(data.gambleGamesWon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gambleGamesWon).toEqualTypeOf(); + expect(data.lostBet).toBeDefined(); + expectTypeOf(data.lostBet).toEqualTypeOf(); + expect(data.lostBetTime).toBeDefined(); + expect(data.lostBetTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lostBetTime).toEqualTypeOf(); + expect(data.shouldReward).toBeDefined(); + expectTypeOf(data.shouldReward).toEqualTypeOf(); + expect(data.wonLastGame).toBeDefined(); + expectTypeOf(data.wonLastGame).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.ts new file mode 100644 index 000000000..e8f5ce1a3 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.ts @@ -0,0 +1,18 @@ +class BedWarsSlumberQuestGamblerGeorge { + betAmount: number; + gambleGamesWon: number; + lostBet: boolean; + lostBetTime: number; + shouldReward: boolean; + wonLastGame: boolean; + constructor(data: Record) { + this.betAmount = data?.bet_amount || 0; + this.gambleGamesWon = data?.gamble_games_won || 0; + this.lostBet = data?.lost_bet || false; + this.lostBetTime = data?.lost_bet_time || 0; + this.shouldReward = data?.should_reward || false; + this.wonLastGame = data?.won_last_game || false; + } +} + +export default BedWarsSlumberQuestGamblerGeorge; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.test.ts new file mode 100644 index 000000000..55e563130 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.test.ts @@ -0,0 +1,135 @@ +import BedWarsSlumberQuestItem from './BedWarsSlumberQuestItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestItem', () => { + const data = new BedWarsSlumberQuestItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.airFreshener).toBeDefined(); + expect(data.airFreshener).toBeGreaterThanOrEqual(0); + expectTypeOf(data.airFreshener).toEqualTypeOf(); + expect(data.amulet).toBeDefined(); + expect(data.amulet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amulet).toEqualTypeOf(); + expect(data.bedSheets).toBeDefined(); + expect(data.bedSheets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bedSheets).toEqualTypeOf(); + expect(data.blitzStar).toBeDefined(); + expect(data.blitzStar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blitzStar).toEqualTypeOf(); + expect(data.blockOfMegaWallsObsidian).toBeDefined(); + expect(data.blockOfMegaWallsObsidian).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blockOfMegaWallsObsidian).toEqualTypeOf(); + expect(data.boots).toBeDefined(); + expect(data.boots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boots).toEqualTypeOf(); + expect(data.cable).toBeDefined(); + expect(data.cable).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cable).toEqualTypeOf(); + expect(data.cleanedUpMurderKnife).toBeDefined(); + expect(data.cleanedUpMurderKnife).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cleanedUpMurderKnife).toEqualTypeOf(); + expect(data.comfyPillow).toBeDefined(); + expect(data.comfyPillow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.comfyPillow).toEqualTypeOf(); + expect(data.diamondFragment).toBeDefined(); + expect(data.diamondFragment).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamondFragment).toEqualTypeOf(); + expect(data.discardedKartWheel).toBeDefined(); + expect(data.discardedKartWheel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.discardedKartWheel).toEqualTypeOf(); + expect(data.dwarvenMithril).toBeDefined(); + expect(data.dwarvenMithril).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dwarvenMithril).toEqualTypeOf(); + expect(data.emeraldShard).toBeDefined(); + expect(data.emeraldShard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.emeraldShard).toEqualTypeOf(); + expect(data.enchantedHammer).toBeDefined(); + expect(data.enchantedHammer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enchantedHammer).toEqualTypeOf(); + expect(data.enderDust).toBeDefined(); + expect(data.enderDust).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderDust).toEqualTypeOf(); + expect(data.fadedBlitzStar).toBeDefined(); + expect(data.fadedBlitzStar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fadedBlitzStar).toEqualTypeOf(); + expect(data.gloves).toBeDefined(); + expect(data.gloves).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gloves).toEqualTypeOf(); + expect(data.glowingSandPaper).toBeDefined(); + expect(data.glowingSandPaper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.glowingSandPaper).toEqualTypeOf(); + expect(data.goldBar).toBeDefined(); + expect(data.goldBar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldBar).toEqualTypeOf(); + expect(data.goldenTicket).toBeDefined(); + expect(data.goldenTicket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenTicket).toEqualTypeOf(); + expect(data.imperialLeather).toBeDefined(); + expect(data.imperialLeather).toBeGreaterThanOrEqual(0); + expectTypeOf(data.imperialLeather).toEqualTypeOf(); + expect(data.indigosMap).toBeDefined(); + expect(data.indigosMap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.indigosMap).toEqualTypeOf(); + expect(data.ironNugget).toBeDefined(); + expect(data.ironNugget).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ironNugget).toEqualTypeOf(); + expect(data.limboDust).toBeDefined(); + expect(data.limboDust).toBeGreaterThanOrEqual(0); + expectTypeOf(data.limboDust).toEqualTypeOf(); + expect(data.missingAmulet).toBeDefined(); + expect(data.missingAmulet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.missingAmulet).toEqualTypeOf(); + expect(data.moonStoneNugget).toBeDefined(); + expect(data.moonStoneNugget).toBeGreaterThanOrEqual(0); + expectTypeOf(data.moonStoneNugget).toEqualTypeOf(); + expect(data.murderWeapon).toBeDefined(); + expect(data.murderWeapon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murderWeapon).toEqualTypeOf(); + expect(data.netherStar).toBeDefined(); + expect(data.netherStar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.netherStar).toEqualTypeOf(); + expect(data.oasisWater).toBeDefined(); + expect(data.oasisWater).toBeGreaterThanOrEqual(0); + expectTypeOf(data.oasisWater).toEqualTypeOf(); + expect(data.perfume).toBeDefined(); + expect(data.perfume).toBeGreaterThanOrEqual(0); + expectTypeOf(data.perfume).toEqualTypeOf(); + expect(data.proofOfSuccess).toBeDefined(); + expect(data.proofOfSuccess).toBeGreaterThanOrEqual(0); + expectTypeOf(data.proofOfSuccess).toEqualTypeOf(); + expect(data.ratmanMask).toBeDefined(); + expect(data.ratmanMask).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ratmanMask).toEqualTypeOf(); + expect(data.silverBladeReplay).toBeDefined(); + expect(data.silverBladeReplay).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silverBladeReplay).toEqualTypeOf(); + expect(data.silverCoins).toBeDefined(); + expect(data.silverCoins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silverCoins).toEqualTypeOf(); + expect(data.soul).toBeDefined(); + expect(data.soul).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soul).toEqualTypeOf(); + expect(data.sparkPlug).toBeDefined(); + expect(data.sparkPlug).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sparkPlug).toEqualTypeOf(); + expect(data.timewornMysteryBox).toBeDefined(); + expect(data.timewornMysteryBox).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timewornMysteryBox).toEqualTypeOf(); + expect(data.tokenOfFerocity).toBeDefined(); + expect(data.tokenOfFerocity).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokenOfFerocity).toEqualTypeOf(); + expect(data.trustyRope).toBeDefined(); + expect(data.trustyRope).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trustyRope).toEqualTypeOf(); + expect(data.unusedBombMaterials).toBeDefined(); + expect(data.unusedBombMaterials).toBeGreaterThanOrEqual(0); + expectTypeOf(data.unusedBombMaterials).toEqualTypeOf(); + expect(data.victimPhoto).toBeDefined(); + expect(data.victimPhoto).toBeGreaterThanOrEqual(0); + expectTypeOf(data.victimPhoto).toEqualTypeOf(); + expect(data.weaponMold).toBeDefined(); + expect(data.weaponMold).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weaponMold).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.ts new file mode 100644 index 000000000..a9bc709ed --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.ts @@ -0,0 +1,90 @@ +class BedWarsSlumberQuestItem { + airFreshener: number; + amulet: number; + bedSheets: number; + blitzStar: number; + blockOfMegaWallsObsidian: number; + boots: number; + cable: number; + cleanedUpMurderKnife: number; + comfyPillow: number; + diamondFragment: number; + discardedKartWheel: number; + dwarvenMithril: number; + emeraldShard: number; + enchantedHammer: number; + enderDust: number; + fadedBlitzStar: number; + gloves: number; + glowingSandPaper: number; + goldBar: number; + goldenTicket: number; + imperialLeather: number; + indigosMap: number; + ironNugget: number; + limboDust: number; + missingAmulet: number; + moonStoneNugget: number; + murderWeapon: number; + netherStar: number; + oasisWater: number; + perfume: number; + proofOfSuccess: number; + ratmanMask: number; + silverBladeReplay: number; + silverCoins: number; + soul: number; + sparkPlug: number; + timewornMysteryBox: number; + tokenOfFerocity: number; + trustyRope: number; + unusedBombMaterials: number; + victimPhoto: number; + weaponMold: number; + constructor(data: Record) { + this.airFreshener = data?.slumber_item_air_freshener || 0; + this.amulet = data?.slumber_item_amulet || 0; + this.bedSheets = data?.slumber_item_bed_sheets || 0; + this.blitzStar = data?.slumber_item_blitz_star || 0; + this.blockOfMegaWallsObsidian = data?.slumber_item_block_of_mega_walls_obsidian || 0; + this.boots = data?.slumber_item_boots || 0; + this.cable = data?.slumber_item_cable || 0; + this.cleanedUpMurderKnife = data?.slumber_item_cleaned_up_murder_knife || 0; + this.comfyPillow = data?.slumber_item_comfy_pillow || 0; + this.diamondFragment = data?.slumber_item_diamond_fragment || 0; + this.discardedKartWheel = data?.slumber_item_discarded_kart_wheel || 0; + this.dwarvenMithril = data?.slumber_item_dwarven_mithril || 0; + this.emeraldShard = data?.slumber_item_emerald_shard || 0; + this.enchantedHammer = data?.slumber_item_enchanted_hammer || 0; + this.enderDust = data?.slumber_item_ender_dust || 0; + this.fadedBlitzStar = data?.slumber_item_faded_blitz_star || 0; + this.gloves = data?.slumber_item_gloves || 0; + this.glowingSandPaper = data?.slumber_item_glowing_sand_paper || 0; + this.goldBar = data?.slumber_item_gold_bar || 0; + this.goldenTicket = data?.slumber_item_golden_ticket || 0; + this.imperialLeather = data?.slumber_item_imperial_leather || 0; + this.indigosMap = data?.slumber_item_indigos_map || 0; + this.ironNugget = data?.slumber_item_iron_nugget || 0; + this.limboDust = data?.slumber_item_limbo_dust || 0; + this.missingAmulet = data?.slumber_item_missing_amulet || 0; + this.moonStoneNugget = data?.slumber_item_moon_stone_nugget || 0; + this.murderWeapon = data?.slumber_item_murder_weapon || 0; + this.netherStar = data?.slumber_item_nether_star || 0; + this.oasisWater = data?.slumber_item_oasis_water || 0; + this.perfume = data?.slumber_item_perfume || 0; + this.proofOfSuccess = data?.slumber_item_proof_of_success || 0; + this.ratmanMask = data?.slumber_item_ratman_mask || 0; + this.silverBladeReplay = data?.slumber_item_silver_blade_replay || 0; + this.silverCoins = data?.slumber_item_silver_coins || 0; + this.soul = data?.slumber_item_soul || 0; + this.sparkPlug = data?.slumber_item_spark_plug || 0; + this.timewornMysteryBox = data?.slumber_item_timeworn_mystery_box || 0; + this.tokenOfFerocity = data?.slumber_item_token_of_ferocity || 0; + this.trustyRope = data?.slumber_item_trusty_rope || 0; + this.unusedBombMaterials = data?.slumber_item_unused_bomb_materials || 0; + this.victimPhoto = data?.slumber_item_victim_photo || 0; + this.weaponMold = data?.slumber_item_weapon_mold || 0; + } +} + +export default BedWarsSlumberQuestItem; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.test.ts new file mode 100644 index 000000000..cb2490f4b --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.test.ts @@ -0,0 +1,25 @@ +import BedWarsSlumberQuestNPC from './BedWarsSlumberQuestNPC.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestNPC', () => { + const data = new BedWarsSlumberQuestNPC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestNPC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.doorMan).toBeDefined(); + expectTypeOf(data.doorMan).toEqualTypeOf(); + expect(data.fredericFernton).toBeDefined(); + expectTypeOf(data.fredericFernton).toEqualTypeOf(); + expect(data.generalDaku).toBeDefined(); + expectTypeOf(data.generalDaku).toEqualTypeOf(); + expect(data.hostessKatrina).toBeDefined(); + expectTypeOf(data.hostessKatrina).toEqualTypeOf(); + expect(data.hotelReceptionist).toBeDefined(); + expectTypeOf(data.hotelReceptionist).toEqualTypeOf(); + expect(data.johnIndigos).toBeDefined(); + expectTypeOf(data.johnIndigos).toEqualTypeOf(); + expect(data.ladySaichi).toBeDefined(); + expectTypeOf(data.ladySaichi).toEqualTypeOf(); + expect(data.ticketMachine).toBeDefined(); + expectTypeOf(data.ticketMachine).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.ts new file mode 100644 index 000000000..929202cd3 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.ts @@ -0,0 +1,22 @@ +class BedWarsSlumberQuestNPC { + doorMan: boolean; + fredericFernton: boolean; + generalDaku: boolean; + hostessKatrina: boolean; + hotelReceptionist: boolean; + johnIndigos: boolean; + ladySaichi: boolean; + ticketMachine: boolean; + constructor(data: Record) { + this.doorMan = data?.DoorManNpc || false; + this.fredericFernton = data?.FredericFerntonNpc || false; + this.generalDaku = data?.GeneralDakuNpc || false; + this.hostessKatrina = data?.HostessKatrinaNpc || false; + this.hotelReceptionist = data?.HotelReceptionistNpc || false; + this.johnIndigos = data?.JohnIndigosNpc || false; + this.ladySaichi = data?.LadySaichiNpc || false; + this.ticketMachine = data?.TicketMachineNpc || false; + } +} + +export default BedWarsSlumberQuestNPC; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.test.ts new file mode 100644 index 000000000..99f07db45 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.test.ts @@ -0,0 +1,99 @@ +import BedWarsSlumberQuestNPCSBoolean from './BedWarsSlumberQuestNPCSBoolean.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestNPCSBoolean', () => { + const data = new BedWarsSlumberQuestNPCSBoolean({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestNPCSBoolean); + expectTypeOf(data).toEqualTypeOf(); + expect(data.arcadePlayer).toBeDefined(); + expectTypeOf(data.arcadePlayer).toEqualTypeOf(); + expect(data.billStarr).toBeDefined(); + expectTypeOf(data.billStarr).toEqualTypeOf(); + expect(data.blacksmith).toBeDefined(); + expectTypeOf(data.blacksmith).toEqualTypeOf(); + expect(data.blacksmithApprentice).toBeDefined(); + expectTypeOf(data.blacksmithApprentice).toEqualTypeOf(); + expect(data.bucky).toBeDefined(); + expectTypeOf(data.bucky).toEqualTypeOf(); + expect(data.combatArtistSally).toBeDefined(); + expectTypeOf(data.combatArtistSally).toEqualTypeOf(); + expect(data.donEspresso).toBeDefined(); + expectTypeOf(data.donEspresso).toEqualTypeOf(); + expect(data.electricianRussel).toBeDefined(); + expectTypeOf(data.electricianRussel).toEqualTypeOf(); + expect(data.executives).toBeDefined(); + expectTypeOf(data.executives).toEqualTypeOf(); + expect(data.gamblerGeorge).toBeDefined(); + expectTypeOf(data.gamblerGeorge).toEqualTypeOf(); + expect(data.generalDaku).toBeDefined(); + expectTypeOf(data.generalDaku).toEqualTypeOf(); + expect(data.gizzyMoonpowder).toBeDefined(); + expectTypeOf(data.gizzyMoonpowder).toEqualTypeOf(); + expect(data.hammer).toBeDefined(); + expectTypeOf(data.hammer).toEqualTypeOf(); + expect(data.hammerPartTwo).toBeDefined(); + expectTypeOf(data.hammerPartTwo).toEqualTypeOf(); + expect(data.hermes).toBeDefined(); + expectTypeOf(data.hermes).toEqualTypeOf(); + expect(data.inspector).toBeDefined(); + expectTypeOf(data.inspector).toEqualTypeOf(); + expect(data.jeremyJagger).toBeDefined(); + expectTypeOf(data.jeremyJagger).toEqualTypeOf(); + expect(data.jetsMcturbo).toBeDefined(); + expectTypeOf(data.jetsMcturbo).toEqualTypeOf(); + expect(data.jimmyBimmy).toBeDefined(); + expectTypeOf(data.jimmyBimmy).toEqualTypeOf(); + expect(data.johnIndigosHammer).toBeDefined(); + expectTypeOf(data.johnIndigosHammer).toEqualTypeOf(); + expect(data.johnPireso).toBeDefined(); + expectTypeOf(data.johnPireso).toEqualTypeOf(); + expect(data.kingFlut).toBeDefined(); + expectTypeOf(data.kingFlut).toEqualTypeOf(); + expect(data.ladySaichi).toBeDefined(); + expectTypeOf(data.ladySaichi).toEqualTypeOf(); + expect(data.laundry).toBeDefined(); + expectTypeOf(data.laundry).toEqualTypeOf(); + expect(data.laundryGal).toBeDefined(); + expectTypeOf(data.laundryGal).toEqualTypeOf(); + expect(data.lesterBrody).toBeDefined(); + expectTypeOf(data.lesterBrody).toEqualTypeOf(); + expect(data.masterMeyer).toBeDefined(); + expectTypeOf(data.masterMeyer).toEqualTypeOf(); + expect(data.meetTheSandman).toBeDefined(); + expectTypeOf(data.meetTheSandman).toEqualTypeOf(); + expect(data.oasis).toBeDefined(); + expectTypeOf(data.oasis).toEqualTypeOf(); + expect(data.peter).toBeDefined(); + expectTypeOf(data.peter).toEqualTypeOf(); + expect(data.quizShowHost).toBeDefined(); + expectTypeOf(data.quizShowHost).toEqualTypeOf(); + expect(data.receptionStart).toBeDefined(); + expectTypeOf(data.receptionStart).toEqualTypeOf(); + expect(data.skyblockPlayer).toBeDefined(); + expectTypeOf(data.skyblockPlayer).toEqualTypeOf(); + expect(data.spaceman).toBeDefined(); + expectTypeOf(data.spaceman).toEqualTypeOf(); + expect(data.theRatman).toBeDefined(); + expectTypeOf(data.theRatman).toEqualTypeOf(); + expect(data.wally).toBeDefined(); + expectTypeOf(data.wally).toEqualTypeOf(); + expect(data.phaseFourAscensionQ1).toBeDefined(); + expectTypeOf(data.phaseFourAscensionQ1).toEqualTypeOf(); + expect(data.phaseFourAscensionQ2).toBeDefined(); + expectTypeOf(data.phaseFourAscensionQ2).toEqualTypeOf(); + expect(data.phaseFourAscensionQ3).toBeDefined(); + expectTypeOf(data.phaseFourAscensionQ3).toEqualTypeOf(); + expect(data.phaseFourAscensionQ4).toBeDefined(); + expectTypeOf(data.phaseFourAscensionQ4).toEqualTypeOf(); + expect(data.phaseFourAscensionQ5).toBeDefined(); + expectTypeOf(data.phaseFourAscensionQ5).toEqualTypeOf(); + expect(data.phaseFourAscensionWalletQ).toBeDefined(); + expectTypeOf(data.phaseFourAscensionWalletQ).toEqualTypeOf(); + expect(data.phaseThreeAsc).toBeDefined(); + expectTypeOf(data.phaseThreeAsc).toEqualTypeOf(); + expect(data.phaseTwoAsc).toBeDefined(); + expectTypeOf(data.phaseTwoAsc).toEqualTypeOf(); + expect(data.staffWalletUpgrade).toBeDefined(); + expectTypeOf(data.staffWalletUpgrade).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.ts new file mode 100644 index 000000000..43b3f3d37 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.ts @@ -0,0 +1,96 @@ +class BedWarsSlumberQuestNPCSBoolean { + arcadePlayer: boolean; + billStarr: boolean; + blacksmith: boolean; + blacksmithApprentice: boolean; + bucky: boolean; + combatArtistSally: boolean; + donEspresso: boolean; + electricianRussel: boolean; + executives: boolean; + gamblerGeorge: boolean; + generalDaku: boolean; + gizzyMoonpowder: boolean; + hammer: boolean; + hammerPartTwo: boolean; + hermes: boolean; + inspector: boolean; + jeremyJagger: boolean; + jetsMcturbo: boolean; + jimmyBimmy: boolean; + johnIndigosHammer: boolean; + johnPireso: boolean; + kingFlut: boolean; + ladySaichi: boolean; + laundry: boolean; + laundryGal: boolean; + lesterBrody: boolean; + masterMeyer: boolean; + meetTheSandman: boolean; + oasis: boolean; + peter: boolean; + quizShowHost: boolean; + receptionStart: boolean; + skyblockPlayer: boolean; + spaceman: boolean; + theRatman: boolean; + wally: boolean; + phaseFourAscensionQ1: boolean; + phaseFourAscensionQ2: boolean; + phaseFourAscensionQ3: boolean; + phaseFourAscensionQ4: boolean; + phaseFourAscensionQ5: boolean; + phaseFourAscensionWalletQ: boolean; + phaseThreeAsc: boolean; + phaseTwoAsc: boolean; + staffWalletUpgrade: boolean; + constructor(data: Record) { + this.arcadePlayer = data?.npc_arcade_player || false; + this.billStarr = data?.npc_bill_starr || false; + this.blacksmith = data?.npc_blacksmith || false; + this.blacksmithApprentice = data?.npc_blacksmith_apprentice || false; + this.bucky = data?.npc_bucky || false; + this.combatArtistSally = data?.npc_combat_artist_sally || false; + this.donEspresso = data?.npc_don_espresso || false; + this.electricianRussel = data?.npc_electrician_russel || false; + this.executives = data?.npc_executives || false; + this.gamblerGeorge = data?.npc_gambler_george || false; + this.generalDaku = data?.npc_general_daku || false; + this.gizzyMoonpowder = data?.npc_gizzy_moonpowder || false; + this.hammer = data?.npc_hammer || false; + this.hammerPartTwo = data?.npc_hammer_part_two || false; + this.hermes = data?.npc_hermes || false; + this.inspector = data?.npc_inspector || false; + this.jeremyJagger = data?.npc_jeremy_jagger || false; + this.jetsMcturbo = data?.npc_jets_mcturbo || false; + this.jimmyBimmy = data?.npc_jimmy_bimmy || false; + this.johnIndigosHammer = data?.npc_john_indigos_hammer || false; + this.johnPireso = data?.npc_john_pireso || false; + this.kingFlut = data?.npc_king_flut || false; + this.ladySaichi = data?.npc_lady_saichi || false; + this.laundry = data?.npc_laundry || false; + this.laundryGal = data?.npc_laundry_gal || false; + this.lesterBrody = data?.npc_lester_brody || false; + this.masterMeyer = data?.npc_master_meyer || false; + this.meetTheSandman = data?.npc_meet_the_sandman || false; + this.oasis = data?.npc_oasis || false; + this.peter = data?.npc_peter || false; + this.quizShowHost = data?.npc_quiz_show_host || false; + this.receptionStart = data?.npc_reception_start || false; + this.skyblockPlayer = data?.npc_skyblock_player || false; + this.spaceman = data?.npc_spaceman || false; + this.theRatman = data?.npc_the_ratman || false; + this.wally = data?.npc_wally || false; + this.phaseFourAscensionQ1 = data?.phase_four_ascension_q1 || false; + this.phaseFourAscensionQ2 = data?.phase_four_ascension_q2 || false; + this.phaseFourAscensionQ3 = data?.phase_four_ascension_q3 || false; + this.phaseFourAscensionQ4 = data?.phase_four_ascension_q4 || false; + this.phaseFourAscensionQ5 = data?.phase_four_ascension_q5 || false; + this.phaseFourAscensionWalletQ = data?.phase_four_ascension_wallet_q || false; + this.phaseThreeAsc = data?.phase_three_asc || false; + this.phaseTwoAsc = data?.phase_two_asc || false; + this.staffWalletUpgrade = data?.staff_wallet_upgrade || false; + } +} + +export default BedWarsSlumberQuestNPCSBoolean; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.test.ts new file mode 100644 index 000000000..6a6a0a279 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.test.ts @@ -0,0 +1,144 @@ +import BedWarsSlumberQuestNPCSNumber from './BedWarsSlumberQuestNPCSNumber.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestNPCSNumber', () => { + const data = new BedWarsSlumberQuestNPCSNumber({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestNPCSNumber); + expectTypeOf(data).toEqualTypeOf(); + expect(data.arcadePlayer).toBeDefined(); + expect(data.arcadePlayer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arcadePlayer).toEqualTypeOf(); + expect(data.billStarr).toBeDefined(); + expect(data.billStarr).toBeGreaterThanOrEqual(0); + expectTypeOf(data.billStarr).toEqualTypeOf(); + expect(data.blacksmith).toBeDefined(); + expect(data.blacksmith).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blacksmith).toEqualTypeOf(); + expect(data.blacksmithApprentice).toBeDefined(); + expect(data.blacksmithApprentice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blacksmithApprentice).toEqualTypeOf(); + expect(data.bucky).toBeDefined(); + expect(data.bucky).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bucky).toEqualTypeOf(); + expect(data.combatArtistSally).toBeDefined(); + expect(data.combatArtistSally).toBeGreaterThanOrEqual(0); + expectTypeOf(data.combatArtistSally).toEqualTypeOf(); + expect(data.donEspresso).toBeDefined(); + expect(data.donEspresso).toBeGreaterThanOrEqual(0); + expectTypeOf(data.donEspresso).toEqualTypeOf(); + expect(data.electricianRussel).toBeDefined(); + expect(data.electricianRussel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.electricianRussel).toEqualTypeOf(); + expect(data.executives).toBeDefined(); + expect(data.executives).toBeGreaterThanOrEqual(0); + expectTypeOf(data.executives).toEqualTypeOf(); + expect(data.gamblerGeorge).toBeDefined(); + expect(data.gamblerGeorge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamblerGeorge).toEqualTypeOf(); + expect(data.generalDaku).toBeDefined(); + expect(data.generalDaku).toBeGreaterThanOrEqual(0); + expectTypeOf(data.generalDaku).toEqualTypeOf(); + expect(data.gizzyMoonpowder).toBeDefined(); + expect(data.gizzyMoonpowder).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gizzyMoonpowder).toEqualTypeOf(); + expect(data.hammer).toBeDefined(); + expect(data.hammer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hammer).toEqualTypeOf(); + expect(data.hammerPartTwo).toBeDefined(); + expect(data.hammerPartTwo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hammerPartTwo).toEqualTypeOf(); + expect(data.hermes).toBeDefined(); + expect(data.hermes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hermes).toEqualTypeOf(); + expect(data.inspector).toBeDefined(); + expect(data.inspector).toBeGreaterThanOrEqual(0); + expectTypeOf(data.inspector).toEqualTypeOf(); + expect(data.jeremyJagger).toBeDefined(); + expect(data.jeremyJagger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jeremyJagger).toEqualTypeOf(); + expect(data.jetsMcturbo).toBeDefined(); + expect(data.jetsMcturbo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jetsMcturbo).toEqualTypeOf(); + expect(data.jimmyBimmy).toBeDefined(); + expect(data.jimmyBimmy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jimmyBimmy).toEqualTypeOf(); + expect(data.johnIndigosHammer).toBeDefined(); + expect(data.johnIndigosHammer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.johnIndigosHammer).toEqualTypeOf(); + expect(data.johnPireso).toBeDefined(); + expect(data.johnPireso).toBeGreaterThanOrEqual(0); + expectTypeOf(data.johnPireso).toEqualTypeOf(); + expect(data.kingFlut).toBeDefined(); + expect(data.kingFlut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kingFlut).toEqualTypeOf(); + expect(data.ladySaichi).toBeDefined(); + expect(data.ladySaichi).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ladySaichi).toEqualTypeOf(); + expect(data.laundry).toBeDefined(); + expect(data.laundry).toBeGreaterThanOrEqual(0); + expectTypeOf(data.laundry).toEqualTypeOf(); + expect(data.laundryGal).toBeDefined(); + expect(data.laundryGal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.laundryGal).toEqualTypeOf(); + expect(data.lesterBrody).toBeDefined(); + expect(data.lesterBrody).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lesterBrody).toEqualTypeOf(); + expect(data.masterMeyer).toBeDefined(); + expect(data.masterMeyer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.masterMeyer).toEqualTypeOf(); + expect(data.meetTheSandman).toBeDefined(); + expect(data.meetTheSandman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meetTheSandman).toEqualTypeOf(); + expect(data.oasis).toBeDefined(); + expect(data.oasis).toBeGreaterThanOrEqual(0); + expectTypeOf(data.oasis).toEqualTypeOf(); + expect(data.peter).toBeDefined(); + expect(data.peter).toBeGreaterThanOrEqual(0); + expectTypeOf(data.peter).toEqualTypeOf(); + expect(data.quizShowHost).toBeDefined(); + expect(data.quizShowHost).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quizShowHost).toEqualTypeOf(); + expect(data.receptionStart).toBeDefined(); + expect(data.receptionStart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.receptionStart).toEqualTypeOf(); + expect(data.skyblockPlayer).toBeDefined(); + expect(data.skyblockPlayer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skyblockPlayer).toEqualTypeOf(); + expect(data.spaceman).toBeDefined(); + expect(data.spaceman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spaceman).toEqualTypeOf(); + expect(data.theRatman).toBeDefined(); + expect(data.theRatman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theRatman).toEqualTypeOf(); + expect(data.wally).toBeDefined(); + expect(data.wally).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wally).toEqualTypeOf(); + expect(data.phaseFourAscensionQ1).toBeDefined(); + expect(data.phaseFourAscensionQ1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionQ1).toEqualTypeOf(); + expect(data.phaseFourAscensionQ2).toBeDefined(); + expect(data.phaseFourAscensionQ2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionQ2).toEqualTypeOf(); + expect(data.phaseFourAscensionQ3).toBeDefined(); + expect(data.phaseFourAscensionQ3).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionQ3).toEqualTypeOf(); + expect(data.phaseFourAscensionQ4).toBeDefined(); + expect(data.phaseFourAscensionQ4).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionQ4).toEqualTypeOf(); + expect(data.phaseFourAscensionQ5).toBeDefined(); + expect(data.phaseFourAscensionQ5).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionQ5).toEqualTypeOf(); + expect(data.phaseFourAscensionWalletQ).toBeDefined(); + expect(data.phaseFourAscensionWalletQ).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseFourAscensionWalletQ).toEqualTypeOf(); + expect(data.phaseThreeAsc).toBeDefined(); + expect(data.phaseThreeAsc).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseThreeAsc).toEqualTypeOf(); + expect(data.phaseTwoAsc).toBeDefined(); + expect(data.phaseTwoAsc).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phaseTwoAsc).toEqualTypeOf(); + expect(data.staffWalletUpgrade).toBeDefined(); + expect(data.staffWalletUpgrade).toBeGreaterThanOrEqual(0); + expectTypeOf(data.staffWalletUpgrade).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.ts new file mode 100644 index 000000000..770758be3 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.ts @@ -0,0 +1,96 @@ +class BedWarsSlumberQuestNPCSNumber { + arcadePlayer: number; + billStarr: number; + blacksmith: number; + blacksmithApprentice: number; + bucky: number; + combatArtistSally: number; + donEspresso: number; + electricianRussel: number; + executives: number; + gamblerGeorge: number; + generalDaku: number; + gizzyMoonpowder: number; + hammer: number; + hammerPartTwo: number; + hermes: number; + inspector: number; + jeremyJagger: number; + jetsMcturbo: number; + jimmyBimmy: number; + johnIndigosHammer: number; + johnPireso: number; + kingFlut: number; + ladySaichi: number; + laundry: number; + laundryGal: number; + lesterBrody: number; + masterMeyer: number; + meetTheSandman: number; + oasis: number; + peter: number; + quizShowHost: number; + receptionStart: number; + skyblockPlayer: number; + spaceman: number; + theRatman: number; + wally: number; + phaseFourAscensionQ1: number; + phaseFourAscensionQ2: number; + phaseFourAscensionQ3: number; + phaseFourAscensionQ4: number; + phaseFourAscensionQ5: number; + phaseFourAscensionWalletQ: number; + phaseThreeAsc: number; + phaseTwoAsc: number; + staffWalletUpgrade: number; + constructor(data: Record) { + this.arcadePlayer = data?.npc_arcade_player || 0; + this.billStarr = data?.npc_bill_starr || 0; + this.blacksmith = data?.npc_blacksmith || 0; + this.blacksmithApprentice = data?.npc_blacksmith_apprentice || 0; + this.bucky = data?.npc_bucky || 0; + this.combatArtistSally = data?.npc_combat_artist_sally || 0; + this.donEspresso = data?.npc_don_espresso || 0; + this.electricianRussel = data?.npc_electrician_russel || 0; + this.executives = data?.npc_executives || 0; + this.gamblerGeorge = data?.npc_gambler_george || 0; + this.generalDaku = data?.npc_general_daku || 0; + this.gizzyMoonpowder = data?.npc_gizzy_moonpowder || 0; + this.hammer = data?.npc_hammer || 0; + this.hammerPartTwo = data?.npc_hammer_part_two || 0; + this.hermes = data?.npc_hermes || 0; + this.inspector = data?.npc_inspector || 0; + this.jeremyJagger = data?.npc_jeremy_jagger || 0; + this.jetsMcturbo = data?.npc_jets_mcturbo || 0; + this.jimmyBimmy = data?.npc_jimmy_bimmy || 0; + this.johnIndigosHammer = data?.npc_john_indigos_hammer || 0; + this.johnPireso = data?.npc_john_pireso || 0; + this.kingFlut = data?.npc_king_flut || 0; + this.ladySaichi = data?.npc_lady_saichi || 0; + this.laundry = data?.npc_laundry || 0; + this.laundryGal = data?.npc_laundry_gal || 0; + this.lesterBrody = data?.npc_lester_brody || 0; + this.masterMeyer = data?.npc_master_meyer || 0; + this.meetTheSandman = data?.npc_meet_the_sandman || 0; + this.oasis = data?.npc_oasis || 0; + this.peter = data?.npc_peter || 0; + this.quizShowHost = data?.npc_quiz_show_host || 0; + this.receptionStart = data?.npc_reception_start || 0; + this.skyblockPlayer = data?.npc_skyblock_player || 0; + this.spaceman = data?.npc_spaceman || 0; + this.theRatman = data?.npc_the_ratman || 0; + this.wally = data?.npc_wally || 0; + this.phaseFourAscensionQ1 = data?.phase_four_ascension_q1 || 0; + this.phaseFourAscensionQ2 = data?.phase_four_ascension_q2 || 0; + this.phaseFourAscensionQ3 = data?.phase_four_ascension_q3 || 0; + this.phaseFourAscensionQ4 = data?.phase_four_ascension_q4 || 0; + this.phaseFourAscensionQ5 = data?.phase_four_ascension_q5 || 0; + this.phaseFourAscensionWalletQ = data?.phase_four_ascension_wallet_q || 0; + this.phaseThreeAsc = data?.phase_three_asc || 0; + this.phaseTwoAsc = data?.phase_two_asc || 0; + this.staffWalletUpgrade = data?.staff_wallet_upgrade || 0; + } +} + +export default BedWarsSlumberQuestNPCSNumber; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.test.ts new file mode 100644 index 000000000..29e1ee4b2 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.test.ts @@ -0,0 +1,167 @@ +import BedWarsSlumberQuestObjective from './BedWarsSlumberQuestObjective.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberQuestObjective', () => { + const data = new BedWarsSlumberQuestObjective({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberQuestObjective); + expectTypeOf(data).toEqualTypeOf(); + expect(data.arcadeQuarters).toBeDefined(); + expectTypeOf(data.arcadeQuarters).toEqualTypeOf(); + expect(data.arcadeQuartersRepeat).toBeDefined(); + expectTypeOf(data.arcadeQuartersRepeat).toEqualTypeOf(); + expect(data.billStarrBlitz).toBeDefined(); + expectTypeOf(data.billStarrBlitz).toEqualTypeOf(); + expect(data.blacksmithAmulet).toBeDefined(); + expectTypeOf(data.blacksmithAmulet).toEqualTypeOf(); + expect(data.blacksmithApprenticeCoins).toBeDefined(); + expectTypeOf(data.blacksmithApprenticeCoins).toEqualTypeOf(); + expect(data.blacksmithApprenticeCoinsRepeat).toBeDefined(); + expectTypeOf(data.blacksmithApprenticeCoinsRepeat).toEqualTypeOf(); + expect(data.blacksmithApprenticeIron).toBeDefined(); + expectTypeOf(data.blacksmithApprenticeIron).toEqualTypeOf(); + expect(data.blacksmithApprenticeIronRepeat).toBeDefined(); + expectTypeOf(data.blacksmithApprenticeIronRepeat).toEqualTypeOf(); + expect(data.blacksmithGoldenTicket).toBeDefined(); + expectTypeOf(data.blacksmithGoldenTicket).toEqualTypeOf(); + expect(data.blacksmithIronBars).toBeDefined(); + expectTypeOf(data.blacksmithIronBars).toEqualTypeOf(); + expect(data.blacksmithMold).toBeDefined(); + expectTypeOf(data.blacksmithMold).toEqualTypeOf(); + expect(data.blacksmithWater).toBeDefined(); + expectTypeOf(data.blacksmithWater).toEqualTypeOf(); + expect(data.buckyFragments).toBeDefined(); + expectTypeOf(data.buckyFragments).toEqualTypeOf(); + expect(data.buckyFragmentsRepeat).toBeDefined(); + expectTypeOf(data.buckyFragmentsRepeat).toEqualTypeOf(); + expect(data.buckySkyTeaLeaves).toBeDefined(); + expectTypeOf(data.buckySkyTeaLeaves).toEqualTypeOf(); + expect(data.buckySkyTeaLeavesRepeat).toBeDefined(); + expectTypeOf(data.buckySkyTeaLeavesRepeat).toEqualTypeOf(); + expect(data.chessTickets).toBeDefined(); + expectTypeOf(data.chessTickets).toEqualTypeOf(); + expect(data.chessTokensOfFerocity).toBeDefined(); + expectTypeOf(data.chessTokensOfFerocity).toEqualTypeOf(); + expect(data.chessWoolCables).toBeDefined(); + expectTypeOf(data.chessWoolCables).toEqualTypeOf(); + expect(data.combatArtistSally).toBeDefined(); + expectTypeOf(data.combatArtistSally).toEqualTypeOf(); + expect(data.combatArtistSallyRepeat).toBeDefined(); + expectTypeOf(data.combatArtistSallyRepeat).toEqualTypeOf(); + expect(data.donEspressoGold).toBeDefined(); + expectTypeOf(data.donEspressoGold).toEqualTypeOf(); + expect(data.electricianRussel).toBeDefined(); + expectTypeOf(data.electricianRussel).toEqualTypeOf(); + expect(data.electricianRusselRepeat).toBeDefined(); + expectTypeOf(data.electricianRusselRepeat).toEqualTypeOf(); + expect(data.executivesMeetingNumbers).toBeDefined(); + expectTypeOf(data.executivesMeetingNumbers).toEqualTypeOf(); + expect(data.gamblerGeorgeWin).toBeDefined(); + expectTypeOf(data.gamblerGeorgeWin).toEqualTypeOf(); + expect(data.generalDakuTea).toBeDefined(); + expectTypeOf(data.generalDakuTea).toEqualTypeOf(); + expect(data.gizzyMoonpowder).toBeDefined(); + expectTypeOf(data.gizzyMoonpowder).toEqualTypeOf(); + expect(data.gizzyMoonpowderRepeat).toBeDefined(); + expectTypeOf(data.gizzyMoonpowderRepeat).toEqualTypeOf(); + expect(data.hammerCoins).toBeDefined(); + expectTypeOf(data.hammerCoins).toEqualTypeOf(); + expect(data.hammerPartTwoSilverBlade).toBeDefined(); + expectTypeOf(data.hammerPartTwoSilverBlade).toEqualTypeOf(); + expect(data.hermesMysteryBoxes).toBeDefined(); + expectTypeOf(data.hermesMysteryBoxes).toEqualTypeOf(); + expect(data.inspectorAirFreshener).toBeDefined(); + expectTypeOf(data.inspectorAirFreshener).toEqualTypeOf(); + expect(data.inspectorClueWeapon).toBeDefined(); + expectTypeOf(data.inspectorClueWeapon).toEqualTypeOf(); + expect(data.inspectorGloves).toBeDefined(); + expectTypeOf(data.inspectorGloves).toEqualTypeOf(); + expect(data.inspectorPhoto).toBeDefined(); + expectTypeOf(data.inspectorPhoto).toEqualTypeOf(); + expect(data.inspectorWorkBoots).toBeDefined(); + expectTypeOf(data.inspectorWorkBoots).toEqualTypeOf(); + expect(data.jaggerDiamond).toBeDefined(); + expectTypeOf(data.jaggerDiamond).toEqualTypeOf(); + expect(data.jaggerEmerald).toBeDefined(); + expectTypeOf(data.jaggerEmerald).toEqualTypeOf(); + expect(data.jaggerGold).toBeDefined(); + expectTypeOf(data.jaggerGold).toEqualTypeOf(); + expect(data.jaggerIron).toBeDefined(); + expectTypeOf(data.jaggerIron).toEqualTypeOf(); + expect(data.jaggerWool).toBeDefined(); + expectTypeOf(data.jaggerWool).toEqualTypeOf(); + expect(data.jetsCables).toBeDefined(); + expectTypeOf(data.jetsCables).toEqualTypeOf(); + expect(data.jetsEmeralds).toBeDefined(); + expectTypeOf(data.jetsEmeralds).toEqualTypeOf(); + expect(data.jetsIronBars).toBeDefined(); + expectTypeOf(data.jetsIronBars).toEqualTypeOf(); + expect(data.jetsNetherStars).toBeDefined(); + expectTypeOf(data.jetsNetherStars).toEqualTypeOf(); + expect(data.johnIndigosHammer).toBeDefined(); + expectTypeOf(data.johnIndigosHammer).toEqualTypeOf(); + expect(data.johnPiresoMap).toBeDefined(); + expectTypeOf(data.johnPiresoMap).toEqualTypeOf(); + expect(data.kingFlutAmulet).toBeDefined(); + expectTypeOf(data.kingFlutAmulet).toEqualTypeOf(); + expect(data.kingFlutPillow).toBeDefined(); + expectTypeOf(data.kingFlutPillow).toEqualTypeOf(); + expect(data.ladySaichiMattress).toBeDefined(); + expectTypeOf(data.ladySaichiMattress).toEqualTypeOf(); + expect(data.laundryGalPillows).toBeDefined(); + expectTypeOf(data.laundryGalPillows).toEqualTypeOf(); + expect(data.laundryGalPillowsRepeat).toBeDefined(); + expectTypeOf(data.laundryGalPillowsRepeat).toEqualTypeOf(); + expect(data.laundryManagerSheets).toBeDefined(); + expectTypeOf(data.laundryManagerSheets).toEqualTypeOf(); + expect(data.laundryManagerSheetsRepeat).toBeDefined(); + expectTypeOf(data.laundryManagerSheetsRepeat).toEqualTypeOf(); + expect(data.lesterBrody).toBeDefined(); + expectTypeOf(data.lesterBrody).toEqualTypeOf(); + expect(data.lesterBrodyRepeat).toBeDefined(); + expectTypeOf(data.lesterBrodyRepeat).toEqualTypeOf(); + expect(data.masterMeyer).toBeDefined(); + expectTypeOf(data.masterMeyer).toEqualTypeOf(); + expect(data.masterMeyerRepeat).toBeDefined(); + expectTypeOf(data.masterMeyerRepeat).toEqualTypeOf(); + expect(data.meetTheSandman).toBeDefined(); + expectTypeOf(data.meetTheSandman).toEqualTypeOf(); + expect(data.oasisSouls).toBeDefined(); + expectTypeOf(data.oasisSouls).toEqualTypeOf(); + expect(data.peterEscape).toBeDefined(); + expectTypeOf(data.peterEscape).toEqualTypeOf(); + expect(data.phaseFourAscensionO1).toBeDefined(); + expectTypeOf(data.phaseFourAscensionO1).toEqualTypeOf(); + expect(data.phaseFourAscensionO2).toBeDefined(); + expectTypeOf(data.phaseFourAscensionO2).toEqualTypeOf(); + expect(data.phaseFourAscensionO3).toBeDefined(); + expectTypeOf(data.phaseFourAscensionO3).toEqualTypeOf(); + expect(data.phaseFourAscensionO4).toBeDefined(); + expectTypeOf(data.phaseFourAscensionO4).toEqualTypeOf(); + expect(data.phaseFourAscensionO5).toBeDefined(); + expectTypeOf(data.phaseFourAscensionO5).toEqualTypeOf(); + expect(data.phaseThreeRecp).toBeDefined(); + expectTypeOf(data.phaseThreeRecp).toEqualTypeOf(); + expect(data.phaseTwoRecp).toBeDefined(); + expectTypeOf(data.phaseTwoRecp).toEqualTypeOf(); + expect(data.ratmanBedsheets).toBeDefined(); + expectTypeOf(data.ratmanBedsheets).toEqualTypeOf(); + expect(data.ratmanIronBars).toBeDefined(); + expectTypeOf(data.ratmanIronBars).toEqualTypeOf(); + expect(data.ratmanPillow).toBeDefined(); + expectTypeOf(data.ratmanPillow).toEqualTypeOf(); + expect(data.ratmanSparkPlug).toBeDefined(); + expectTypeOf(data.ratmanSparkPlug).toEqualTypeOf(); + expect(data.receptionistIntroduction).toBeDefined(); + expectTypeOf(data.receptionistIntroduction).toEqualTypeOf(); + expect(data.skyblockPlayerLeaves).toBeDefined(); + expectTypeOf(data.skyblockPlayerLeaves).toEqualTypeOf(); + expect(data.spacemanNetherStars).toBeDefined(); + expectTypeOf(data.spacemanNetherStars).toEqualTypeOf(); + expect(data.wallyBedSheets).toBeDefined(); + expectTypeOf(data.wallyBedSheets).toEqualTypeOf(); + expect(data.wallyNetherStars).toBeDefined(); + expectTypeOf(data.wallyNetherStars).toEqualTypeOf(); + expect(data.zzzzzzzmeow).toBeDefined(); + expectTypeOf(data.zzzzzzzmeow).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.ts new file mode 100644 index 000000000..38573bc23 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.ts @@ -0,0 +1,164 @@ +class BedWarsSlumberQuestObjective { + arcadeQuarters: boolean; + arcadeQuartersRepeat: boolean; + billStarrBlitz: boolean; + blacksmithAmulet: boolean; + blacksmithApprenticeCoins: boolean; + blacksmithApprenticeCoinsRepeat: boolean; + blacksmithApprenticeIron: boolean; + blacksmithApprenticeIronRepeat: boolean; + blacksmithGoldenTicket: boolean; + blacksmithIronBars: boolean; + blacksmithMold: boolean; + blacksmithWater: boolean; + buckyFragments: boolean; + buckyFragmentsRepeat: boolean; + buckySkyTeaLeaves: boolean; + buckySkyTeaLeavesRepeat: boolean; + chessTickets: boolean; + chessTokensOfFerocity: boolean; + chessWoolCables: boolean; + combatArtistSally: boolean; + combatArtistSallyRepeat: boolean; + donEspressoGold: boolean; + electricianRussel: boolean; + electricianRusselRepeat: boolean; + executivesMeetingNumbers: boolean; + gamblerGeorgeWin: boolean; + generalDakuTea: boolean; + gizzyMoonpowder: boolean; + gizzyMoonpowderRepeat: boolean; + hammerCoins: boolean; + hammerPartTwoSilverBlade: boolean; + hermesMysteryBoxes: boolean; + inspectorAirFreshener: boolean; + inspectorClueWeapon: boolean; + inspectorGloves: boolean; + inspectorPhoto: boolean; + inspectorWorkBoots: boolean; + jaggerDiamond: boolean; + jaggerEmerald: boolean; + jaggerGold: boolean; + jaggerIron: boolean; + jaggerWool: boolean; + jetsCables: boolean; + jetsEmeralds: boolean; + jetsIronBars: boolean; + jetsNetherStars: boolean; + johnIndigosHammer: boolean; + johnPiresoMap: boolean; + kingFlutAmulet: boolean; + kingFlutPillow: boolean; + ladySaichiMattress: boolean; + laundryGalPillows: boolean; + laundryGalPillowsRepeat: boolean; + laundryManagerSheets: boolean; + laundryManagerSheetsRepeat: boolean; + lesterBrody: boolean; + lesterBrodyRepeat: boolean; + masterMeyer: boolean; + masterMeyerRepeat: boolean; + meetTheSandman: boolean; + oasisSouls: boolean; + peterEscape: boolean; + phaseFourAscensionO1: boolean; + phaseFourAscensionO2: boolean; + phaseFourAscensionO3: boolean; + phaseFourAscensionO4: boolean; + phaseFourAscensionO5: boolean; + phaseThreeRecp: boolean; + phaseTwoRecp: boolean; + ratmanBedsheets: boolean; + ratmanIronBars: boolean; + ratmanPillow: boolean; + ratmanSparkPlug: boolean; + receptionistIntroduction: boolean; + skyblockPlayerLeaves: boolean; + spacemanNetherStars: boolean; + wallyBedSheets: boolean; + wallyNetherStars: boolean; + zzzzzzzmeow: boolean; + constructor(data: Record) { + this.arcadeQuarters = data?.arcade_quarters || false; + this.arcadeQuartersRepeat = data?.arcade_quarters_repeat || false; + this.billStarrBlitz = data?.bill_starr_blitz || false; + this.blacksmithAmulet = data?.blacksmith_amulet || false; + this.blacksmithApprenticeCoins = data?.blacksmith_apprentice_coins || false; + this.blacksmithApprenticeCoinsRepeat = data?.blacksmith_apprentice_coins_repeat || false; + this.blacksmithApprenticeIron = data?.blacksmith_apprentice_iron || false; + this.blacksmithApprenticeIronRepeat = data?.blacksmith_apprentice_iron_repeat || false; + this.blacksmithGoldenTicket = data?.blacksmith_golden_ticket || false; + this.blacksmithIronBars = data?.blacksmith_iron_bars || false; + this.blacksmithMold = data?.blacksmith_mold || false; + this.blacksmithWater = data?.blacksmith_water || false; + this.buckyFragments = data?.bucky_fragments || false; + this.buckyFragmentsRepeat = data?.bucky_fragments_repeat || false; + this.buckySkyTeaLeaves = data?.bucky_sky_tea_leaves || false; + this.buckySkyTeaLeavesRepeat = data?.bucky_sky_tea_leaves_repeat || false; + this.chessTickets = data?.chess_tickets || false; + this.chessTokensOfFerocity = data?.chess_tokens_of_ferocity || false; + this.chessWoolCables = data?.chess_wool_cables || false; + this.combatArtistSally = data?.combat_artist_sally || false; + this.combatArtistSallyRepeat = data?.combat_artist_sally_repeat || false; + this.donEspressoGold = data?.don_espresso_gold || false; + this.electricianRussel = data?.electrician_russel || false; + this.electricianRusselRepeat = data?.electrician_russel_repeat || false; + this.executivesMeetingNumbers = data?.executives_meeting_numbers || false; + this.gamblerGeorgeWin = data?.gambler_george_win || false; + this.generalDakuTea = data?.general_daku_tea || false; + this.gizzyMoonpowder = data?.gizzy_moonpowder || false; + this.gizzyMoonpowderRepeat = data?.gizzy_moonpowder_repeat || false; + this.hammerCoins = data?.hammer_coins || false; + this.hammerPartTwoSilverBlade = data?.hammer_part_two_silver_blade || false; + this.hermesMysteryBoxes = data?.hermes_mystery_boxes || false; + this.inspectorAirFreshener = data?.inspector_air_freshener || false; + this.inspectorClueWeapon = data?.inspector_clue_weapon || false; + this.inspectorGloves = data?.inspector_gloves || false; + this.inspectorPhoto = data?.inspector_photo || false; + this.inspectorWorkBoots = data?.inspector_work_boots || false; + this.jaggerDiamond = data?.jagger_diamond || false; + this.jaggerEmerald = data?.jagger_emerald || false; + this.jaggerGold = data?.jagger_gold || false; + this.jaggerIron = data?.jagger_iron || false; + this.jaggerWool = data?.jagger_wool || false; + this.jetsCables = data?.jets_cables || false; + this.jetsEmeralds = data?.jets_emeralds || false; + this.jetsIronBars = data?.jets_iron_bars || false; + this.jetsNetherStars = data?.jets_nether_stars || false; + this.johnIndigosHammer = data?.john_indigos_hammer || false; + this.johnPiresoMap = data?.john_pireso_map || false; + this.kingFlutAmulet = data?.king_flut_amulet || false; + this.kingFlutPillow = data?.king_flut_pillow || false; + this.ladySaichiMattress = data?.lady_saichi_mattress || false; + this.laundryGalPillows = data?.laundry_gal_pillows || false; + this.laundryGalPillowsRepeat = data?.laundry_gal_pillows_repeat || false; + this.laundryManagerSheets = data?.laundry_manager_sheets || false; + this.laundryManagerSheetsRepeat = data?.laundry_manager_sheets_repeat || false; + this.lesterBrody = data?.lester_brody || false; + this.lesterBrodyRepeat = data?.lester_brody_repeat || false; + this.masterMeyer = data?.master_meyer || false; + this.masterMeyerRepeat = data?.master_meyer_repeat || false; + this.meetTheSandman = data?.meet_the_sandman || false; + this.oasisSouls = data?.oasis_souls || false; + this.peterEscape = data?.peter_escape || false; + this.phaseFourAscensionO1 = data?.phase_four_ascension_o1 || false; + this.phaseFourAscensionO2 = data?.phase_four_ascension_o2 || false; + this.phaseFourAscensionO3 = data?.phase_four_ascension_o3 || false; + this.phaseFourAscensionO4 = data?.phase_four_ascension_o4 || false; + this.phaseFourAscensionO5 = data?.phase_four_ascension_o5 || false; + this.phaseThreeRecp = data?.phase_three_recp || false; + this.phaseTwoRecp = data?.phase_two_recp || false; + this.ratmanBedsheets = data?.ratman_bedsheets || false; + this.ratmanIronBars = data?.ratman_iron_bars || false; + this.ratmanPillow = data?.ratman_pillow || false; + this.ratmanSparkPlug = data?.ratman_spark_plug || false; + this.receptionistIntroduction = data?.receptionist_introduction || false; + this.skyblockPlayerLeaves = data?.skyblock_player_leaves || false; + this.spacemanNetherStars = data?.spaceman_nether_stars || false; + this.wallyBedSheets = data?.wally_bed_sheets || false; + this.wallyNetherStars = data?.wally_nether_stars || false; + this.zzzzzzzmeow = data?.zzzzzzzMEOW || false; + } +} + +export default BedWarsSlumberQuestObjective; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.test.ts new file mode 100644 index 000000000..ed7130696 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.test.ts @@ -0,0 +1,35 @@ +import BedWarsSlumberRoom from './BedWarsSlumberRoom.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberRoom', () => { + const data = new BedWarsSlumberRoom({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberRoom); + expectTypeOf(data).toEqualTypeOf(); + expect(data.ownersOffice).toBeDefined(); + expectTypeOf(data.ownersOffice).toEqualTypeOf(); + expect(data.room1).toBeDefined(); + expectTypeOf(data.room1).toEqualTypeOf(); + expect(data.room2).toBeDefined(); + expectTypeOf(data.room2).toEqualTypeOf(); + expect(data.room3).toBeDefined(); + expectTypeOf(data.room3).toEqualTypeOf(); + expect(data.room4).toBeDefined(); + expectTypeOf(data.room4).toEqualTypeOf(); + expect(data.room5).toBeDefined(); + expectTypeOf(data.room5).toEqualTypeOf(); + expect(data.room6).toBeDefined(); + expectTypeOf(data.room6).toEqualTypeOf(); + expect(data.room7).toBeDefined(); + expectTypeOf(data.room7).toEqualTypeOf(); + expect(data.room8).toBeDefined(); + expectTypeOf(data.room8).toEqualTypeOf(); + expect(data.room9).toBeDefined(); + expectTypeOf(data.room9).toEqualTypeOf(); + expect(data.room10).toBeDefined(); + expectTypeOf(data.room10).toEqualTypeOf(); + expect(data.room11).toBeDefined(); + expectTypeOf(data.room11).toEqualTypeOf(); + expect(data.room12).toBeDefined(); + expectTypeOf(data.room12).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.ts new file mode 100644 index 000000000..224f51871 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.ts @@ -0,0 +1,32 @@ +class BedWarsSlumberRoom { + ownersOffice: boolean; + room1: boolean; + room2: boolean; + room3: boolean; + room4: boolean; + room5: boolean; + room6: boolean; + room7: boolean; + room8: boolean; + room9: boolean; + room10: boolean; + room11: boolean; + room12: boolean; + constructor(data: Record) { + this.ownersOffice = data?.owners_office || false; + this.room1 = data?.room_1 || false; + this.room2 = data?.room_2 || false; + this.room3 = data?.room_3 || false; + this.room4 = data?.room_4 || false; + this.room5 = data?.room_5 || false; + this.room6 = data?.room_6 || false; + this.room7 = data?.room_7 || false; + this.room8 = data?.room_8 || false; + this.room9 = data?.room_9 || false; + this.room10 = data?.room_10 || false; + this.room11 = data?.room_11 || false; + this.room12 = data?.room_12 || false; + } +} + +export default BedWarsSlumberRoom; diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.test.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.test.ts new file mode 100644 index 000000000..f0d6c4170 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.test.ts @@ -0,0 +1,15 @@ +import BedWarsSlumberSandman from './BedWarsSlumberSandman.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsSlumberSandman', () => { + const data = new BedWarsSlumberSandman({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsSlumberSandman); + expectTypeOf(data).toEqualTypeOf(); + expect(data.expMultiplier).toBeDefined(); + expect(data.expMultiplier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.expMultiplier).toEqualTypeOf(); + expect(data.ticketMultiplier).toBeDefined(); + expect(data.ticketMultiplier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ticketMultiplier).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.ts b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.ts new file mode 100644 index 000000000..fe56c0549 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.ts @@ -0,0 +1,10 @@ +class BedWarsSlumberSandman { + expMultiplier: number; + ticketMultiplier: number; + constructor(data: Record) { + this.expMultiplier = data?.exp_multiplier || 0; + this.ticketMultiplier = data?.ticket_multiplier || 0; + } +} + +export default BedWarsSlumberSandman; diff --git a/src/Structures/MiniGames/BedWars/BedWarsTwoFour.test.ts b/src/Structures/MiniGames/BedWars/BedWarsTwoFour.test.ts new file mode 100644 index 000000000..7eb518d60 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsTwoFour.test.ts @@ -0,0 +1,13 @@ +import BedWarsMode from './BedWarsMode.js'; +import BedWarsTwoFour from './BedWarsTwoFour.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BedWarsTwoFour', () => { + const data = new BedWarsTwoFour({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BedWarsTwoFour); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tourney).toBeDefined(); + expect(data.tourney).toBeInstanceOf(BedWarsMode); + expectTypeOf(data.tourney).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BedWars/BedWarsTwoFour.ts b/src/Structures/MiniGames/BedWars/BedWarsTwoFour.ts new file mode 100644 index 000000000..4009854e9 --- /dev/null +++ b/src/Structures/MiniGames/BedWars/BedWarsTwoFour.ts @@ -0,0 +1,11 @@ +import BedWarsMode from './BedWarsMode.js'; + +class BedWarsTwoFour extends BedWarsMode { + tourney: BedWarsMode; + constructor(data: Record) { + super(data, 'two_four'); + this.tourney = new BedWarsMode(data, 'tourney_bedwars_two_four_0'); + } +} + +export default BedWarsTwoFour; diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.test.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.test.ts new file mode 100644 index 000000000..4a0fa7a3f --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.test.ts @@ -0,0 +1,216 @@ +import BlitzSurvivalGames from './BlitzSurvivalGames.js'; +import BlitzSurvivalGamesKit from './BlitzSurvivalGamesKit.js'; +import BlitzSurvivalGamesPrivateGames from './BlitzSurvivalGamesPrivateGames.js'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + BlitzSurvivalGamesAura, + BlitzSurvivalGamesFinisher, + BlitzSurvivalGamesKillEffect, + BlitzSurvivalGamesKitName, + BlitzSurvivalGamesLeaderboardSettingsMode, + BlitzSurvivalGamesTaunt, + BlitzSurvivalGamesVictoryDance +} from '../../../Types/Player.js'; + +test('BlitzSurvivalGames', () => { + const data = new BlitzSurvivalGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BlitzSurvivalGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.aura).toBeDefined(); + expectTypeOf(data.aura).toEqualTypeOf(); + expect(data.auraToggle).toBeDefined(); + expectTypeOf(data.auraToggle).toEqualTypeOf(); + expect(data.blood).toBeDefined(); + expectTypeOf(data.blood).toEqualTypeOf(); + expect(data.chosenTaunt).toBeDefined(); + expectTypeOf(data.chosenTaunt).toEqualTypeOf(); + expect(data.chosenVictoryDance).toBeDefined(); + expectTypeOf(data.chosenVictoryDance).toEqualTypeOf(); + expect(data.chosenFinisher).toBeDefined(); + expectTypeOf(data.chosenFinisher).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.monthlyKills).toBeDefined(); + expect(data.monthlyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKills).toEqualTypeOf(); + expect(data.monthlyKillsA).toBeDefined(); + expect(data.monthlyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsA).toEqualTypeOf(); + expect(data.monthlyKillsB).toBeDefined(); + expect(data.monthlyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsB).toEqualTypeOf(); + expect(data.weeklyKills).toBeDefined(); + expect(data.weeklyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKills).toEqualTypeOf(); + expect(data.weeklyKillsA).toBeDefined(); + expect(data.weeklyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsA).toEqualTypeOf(); + expect(data.weeklyKillsB).toBeDefined(); + expect(data.weeklyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsB).toEqualTypeOf(); + expect(data.autoArmor).toBeDefined(); + expectTypeOf(data.autoArmor).toEqualTypeOf(); + expect(data.defaultKit).toBeDefined(); + expectTypeOf(data.defaultKit).toEqualTypeOf(); + expect(data.combatTracker).toBeDefined(); + expectTypeOf(data.combatTracker).toEqualTypeOf(); + expect(data.alternativeKillMessageEnabled).toBeDefined(); + expectTypeOf(data.alternativeKillMessageEnabled).toEqualTypeOf(); + expect(data.prefersFullKitsMenu).toBeDefined(); + expectTypeOf(data.prefersFullKitsMenu).toEqualTypeOf(); + expect(data.disablePrestigeFinisher).toBeDefined(); + expectTypeOf(data.disablePrestigeFinisher).toEqualTypeOf(); + expect(data.toggled).toBeDefined(); + expectTypeOf(data.toggled).toEqualTypeOf(); + expect(data.fancyMode).toBeDefined(); + expectTypeOf(data.fancyMode).toEqualTypeOf(); + expect(data.afterKillEffect).toBeDefined(); + expectTypeOf(data.afterKillEffect).toEqualTypeOf(); + expect(data.leaderboardSettings).toBeDefined(); + expectTypeOf(data.leaderboardSettings).toEqualTypeOf< + LeaderboardSettings + >(); + expect(data.privateGames).toBeDefined(); + expect(data.privateGames).toBeInstanceOf(BlitzSurvivalGamesPrivateGames); + expectTypeOf(data.privateGames).toEqualTypeOf(); + expect(data.arachnologist).toBeDefined(); + expect(data.arachnologist).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.arachnologist).toEqualTypeOf(); + expect(data.archer).toBeDefined(); + expect(data.archer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.archer).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.astronaut).toBeDefined(); + expect(data.astronaut).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.astronaut).toEqualTypeOf(); + expect(data.backup).toBeDefined(); + expect(data.backup).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.backup).toEqualTypeOf(); + expect(data.baker).toBeDefined(); + expect(data.baker).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.baker).toEqualTypeOf(); + expect(data.blaze).toBeDefined(); + expect(data.blaze).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.blaze).toEqualTypeOf(); + expect(data.creepertamer).toBeDefined(); + expect(data.creepertamer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.creepertamer).toEqualTypeOf(); + expect(data.diver).toBeDefined(); + expect(data.diver).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.diver).toEqualTypeOf(); + expect(data.donkeytamer).toBeDefined(); + expect(data.donkeytamer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.donkeytamer).toEqualTypeOf(); + expect(data.farmer).toBeDefined(); + expect(data.farmer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.farmer).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.florist).toBeDefined(); + expect(data.florist).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.florist).toEqualTypeOf(); + expect(data.golem).toBeDefined(); + expect(data.golem).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.golem).toEqualTypeOf(); + expect(data.guardian).toBeDefined(); + expect(data.guardian).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.guardian).toEqualTypeOf(); + expect(data.horsetamer).toBeDefined(); + expect(data.horsetamer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.horsetamer).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.hypeTrain).toBeDefined(); + expect(data.hypeTrain).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.hypeTrain).toEqualTypeOf(); + expect(data.jockey).toBeDefined(); + expect(data.jockey).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.jockey).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.meatmaster).toBeDefined(); + expect(data.meatmaster).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.meatmaster).toEqualTypeOf(); + expect(data.milkman).toBeDefined(); + expect(data.milkman).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.milkman).toEqualTypeOf(); + expect(data.necromancer).toBeDefined(); + expect(data.necromancer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.necromancer).toEqualTypeOf(); + expect(data.paladin).toBeDefined(); + expect(data.paladin).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.paladin).toEqualTypeOf(); + expect(data.phoenix).toBeDefined(); + expect(data.phoenix).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.phoenix).toEqualTypeOf(); + expect(data.pigman).toBeDefined(); + expect(data.pigman).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.pigman).toEqualTypeOf(); + expect(data.rambo).toBeDefined(); + expect(data.rambo).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.rambo).toEqualTypeOf(); + expect(data.random).toBeDefined(); + expect(data.random).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.random).toEqualTypeOf(); + expect(data.ranger).toBeDefined(); + expect(data.ranger).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.ranger).toEqualTypeOf(); + expect(data.reaper).toBeDefined(); + expect(data.reaper).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.reaper).toEqualTypeOf(); + expect(data.reddragon).toBeDefined(); + expect(data.reddragon).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.reddragon).toEqualTypeOf(); + expect(data.rogue).toBeDefined(); + expect(data.rogue).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.rogue).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.shadowKnight).toBeDefined(); + expect(data.shadowKnight).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.shadowKnight).toEqualTypeOf(); + expect(data.shark).toBeDefined(); + expect(data.shark).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.shark).toEqualTypeOf(); + expect(data.slimeyslime).toBeDefined(); + expect(data.slimeyslime).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.slimeyslime).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.speleologist).toBeDefined(); + expect(data.speleologist).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.speleologist).toEqualTypeOf(); + expect(data.tim).toBeDefined(); + expect(data.tim).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.tim).toEqualTypeOf(); + expect(data.toxicologist).toBeDefined(); + expect(data.toxicologist).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.toxicologist).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.troll).toEqualTypeOf(); + expect(data.viking).toBeDefined(); + expect(data.viking).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.viking).toEqualTypeOf(); + expect(data.warlock).toBeDefined(); + expect(data.warlock).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.warlock).toEqualTypeOf(); + expect(data.warrior).toBeDefined(); + expect(data.warrior).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.warrior).toEqualTypeOf(); + expect(data.wolftamer).toBeDefined(); + expect(data.wolftamer).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data.wolftamer).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.ts new file mode 100644 index 000000000..647282396 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.ts @@ -0,0 +1,164 @@ +import BlitzSurvivalGamesData from './BlitzSurvivalGamesData.ts'; +import BlitzSurvivalGamesKit from './BlitzSurvivalGamesKit.ts'; +import BlitzSurvivalGamesPrivateGames from './BlitzSurvivalGamesPrivateGames.ts'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import { monthAB } from '../../../Utils/Oscillation.ts'; +import type { + BlitzSurvivalGamesAura, + BlitzSurvivalGamesFinisher, + BlitzSurvivalGamesKillEffect, + BlitzSurvivalGamesKitName, + BlitzSurvivalGamesLeaderboardSettingsMode, + BlitzSurvivalGamesTaunt, + BlitzSurvivalGamesVictoryDance +} from '../../../Types/Player.ts'; + +class BlitzSurvivalGames extends BlitzSurvivalGamesData { + aura: BlitzSurvivalGamesAura | 'UNKNOWN'; + auraToggle: boolean; + blood: boolean; + chosenTaunt: BlitzSurvivalGamesTaunt; + chosenVictoryDance: BlitzSurvivalGamesVictoryDance | 'UNKNOWN'; + chosenFinisher: BlitzSurvivalGamesFinisher | 'UNKNOWN'; + coins: number; + packages: string[]; + monthlyKills: number; + monthlyKillsA: number; + monthlyKillsB: number; + weeklyKills: number; + weeklyKillsA: number; + weeklyKillsB: number; + autoArmor: boolean; + defaultKit: BlitzSurvivalGamesKitName | 'UNKNOWN'; + combatTracker: boolean; + alternativeKillMessageEnabled: boolean; + prefersFullKitsMenu: boolean; + disablePrestigeFinisher: boolean; + toggled: boolean; + fancyMode: boolean; + afterKillEffect: BlitzSurvivalGamesKillEffect; + leaderboardSettings: LeaderboardSettings; + privateGames: BlitzSurvivalGamesPrivateGames; + arachnologist: BlitzSurvivalGamesKit; + archer: BlitzSurvivalGamesKit; + armorer: BlitzSurvivalGamesKit; + astronaut: BlitzSurvivalGamesKit; + backup: BlitzSurvivalGamesKit; + baker: BlitzSurvivalGamesKit; + blaze: BlitzSurvivalGamesKit; + creepertamer: BlitzSurvivalGamesKit; + diver: BlitzSurvivalGamesKit; + donkeytamer: BlitzSurvivalGamesKit; + farmer: BlitzSurvivalGamesKit; + fisherman: BlitzSurvivalGamesKit; + florist: BlitzSurvivalGamesKit; + golem: BlitzSurvivalGamesKit; + guardian: BlitzSurvivalGamesKit; + horsetamer: BlitzSurvivalGamesKit; + hunter: BlitzSurvivalGamesKit; + hypeTrain: BlitzSurvivalGamesKit; + jockey: BlitzSurvivalGamesKit; + knight: BlitzSurvivalGamesKit; + meatmaster: BlitzSurvivalGamesKit; + milkman: BlitzSurvivalGamesKit; + necromancer: BlitzSurvivalGamesKit; + paladin: BlitzSurvivalGamesKit; + phoenix: BlitzSurvivalGamesKit; + pigman: BlitzSurvivalGamesKit; + rambo: BlitzSurvivalGamesKit; + random: BlitzSurvivalGamesKit; + ranger: BlitzSurvivalGamesKit; + reaper: BlitzSurvivalGamesKit; + reddragon: BlitzSurvivalGamesKit; + rogue: BlitzSurvivalGamesKit; + scout: BlitzSurvivalGamesKit; + shadowKnight: BlitzSurvivalGamesKit; + shark: BlitzSurvivalGamesKit; + slimeyslime: BlitzSurvivalGamesKit; + snowman: BlitzSurvivalGamesKit; + speleologist: BlitzSurvivalGamesKit; + tim: BlitzSurvivalGamesKit; + toxicologist: BlitzSurvivalGamesKit; + troll: BlitzSurvivalGamesKit; + viking: BlitzSurvivalGamesKit; + warlock: BlitzSurvivalGamesKit; + warrior: BlitzSurvivalGamesKit; + wolftamer: BlitzSurvivalGamesKit; + constructor(data: Record) { + super(data); + this.aura = data?.aura || 'UNKNOWN'; + this.auraToggle = data?.auratoggle || false; + this.blood = data?.blood || true; + this.chosenTaunt = data?.chosen_taunt || 'DEFAULT'; + this.chosenVictoryDance = data?.chosen_victorydance || 'UNKNOWN'; + this.chosenFinisher = data?.chosen_finisher || 'UNKNOWN'; + this.coins = data?.coins || 0; + this.packages = data?.packages || []; + this.monthlyKills = parseInt(data?.[`monthly_kills_${monthAB()}`] || 0, 10); + this.monthlyKillsA = data?.monthly_kills_a || 0; + this.monthlyKillsB = data?.monthly_kills_b || 0; + this.weeklyKills = parseInt(data?.[`weekly_kills_${monthAB()}`] || 0, 10); + this.weeklyKillsA = data?.weekly_kills_a || 0; + this.weeklyKillsB = data?.weekly_kills_b || 0; + this.autoArmor = data?.autoarmor || true; + this.defaultKit = data?.defaultkit || 'UNKNOWN'; + this.combatTracker = data?.combatTracker || true; + this.alternativeKillMessageEnabled = data?.alternative_kill_message_enabled || true; + this.prefersFullKitsMenu = data?.prefers_full_kits_menu || true; + this.disablePrestigeFinisher = data?.disableprestigefinisher || true; + this.toggled = data?.toggled || true; + this.fancyMode = data?.fancyMode || false; + this.afterKillEffect = data?.afterkill || 'rapid_fire'; + this.leaderboardSettings = new LeaderboardSettings( + data?.leaderboardSettings || {} + ); + this.privateGames = new BlitzSurvivalGamesPrivateGames(data?.privategames || {}); + this.arachnologist = new BlitzSurvivalGamesKit(data, 'arachnologist'); + this.archer = new BlitzSurvivalGamesKit(data, 'archer'); + this.armorer = new BlitzSurvivalGamesKit(data, 'armorer'); + this.astronaut = new BlitzSurvivalGamesKit(data, 'astronaut'); + this.backup = new BlitzSurvivalGamesKit(data, 'backup'); + this.baker = new BlitzSurvivalGamesKit(data, 'baker'); + this.blaze = new BlitzSurvivalGamesKit(data, 'blaze'); + this.creepertamer = new BlitzSurvivalGamesKit(data, 'creepertamer'); + this.diver = new BlitzSurvivalGamesKit(data, 'diver'); + this.donkeytamer = new BlitzSurvivalGamesKit(data, 'donkeytamer'); + this.farmer = new BlitzSurvivalGamesKit(data, 'farmer'); + this.fisherman = new BlitzSurvivalGamesKit(data, 'fisherman'); + this.florist = new BlitzSurvivalGamesKit(data, 'florist'); + this.golem = new BlitzSurvivalGamesKit(data, 'golem'); + this.guardian = new BlitzSurvivalGamesKit(data, 'guardian'); + this.horsetamer = new BlitzSurvivalGamesKit(data, 'horsetamer'); + this.hunter = new BlitzSurvivalGamesKit(data, 'hunter'); + this.hypeTrain = new BlitzSurvivalGamesKit(data, 'hype train'); + this.jockey = new BlitzSurvivalGamesKit(data, 'jockey'); + this.knight = new BlitzSurvivalGamesKit(data, 'knight'); + this.meatmaster = new BlitzSurvivalGamesKit(data, 'meatmaster'); + this.milkman = new BlitzSurvivalGamesKit(data, 'milkman'); + this.necromancer = new BlitzSurvivalGamesKit(data, 'necromancer'); + this.paladin = new BlitzSurvivalGamesKit(data, 'paladin'); + this.phoenix = new BlitzSurvivalGamesKit(data, 'phoenix'); + this.pigman = new BlitzSurvivalGamesKit(data, 'pigman'); + this.rambo = new BlitzSurvivalGamesKit(data, 'rambo'); + this.random = new BlitzSurvivalGamesKit(data, 'random'); + this.ranger = new BlitzSurvivalGamesKit(data, 'ranger'); + this.reaper = new BlitzSurvivalGamesKit(data, 'reaper'); + this.reddragon = new BlitzSurvivalGamesKit(data, 'reddragon'); + this.rogue = new BlitzSurvivalGamesKit(data, 'rogue'); + this.scout = new BlitzSurvivalGamesKit(data, 'scout'); + this.shadowKnight = new BlitzSurvivalGamesKit(data, 'shadow knight'); + this.shark = new BlitzSurvivalGamesKit(data, 'shark'); + this.slimeyslime = new BlitzSurvivalGamesKit(data, 'slimeyslime'); + this.snowman = new BlitzSurvivalGamesKit(data, 'snowman'); + this.speleologist = new BlitzSurvivalGamesKit(data, 'speleologist'); + this.tim = new BlitzSurvivalGamesKit(data, 'tim'); + this.toxicologist = new BlitzSurvivalGamesKit(data, 'toxicologist'); + this.troll = new BlitzSurvivalGamesKit(data, 'troll'); + this.viking = new BlitzSurvivalGamesKit(data, 'viking'); + this.warlock = new BlitzSurvivalGamesKit(data, 'warlock'); + this.warrior = new BlitzSurvivalGamesKit(data, 'warrior'); + this.wolftamer = new BlitzSurvivalGamesKit(data, 'wolftamer'); + } +} + +export default BlitzSurvivalGames; diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.test.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.test.ts new file mode 100644 index 000000000..7af5ba63c --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.test.ts @@ -0,0 +1,108 @@ +import BlitzSurvivalGamesData from './BlitzSurvivalGamesData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BlitzSurvivalGamesData', () => { + const data = new BlitzSurvivalGamesData({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BlitzSurvivalGamesData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.winsTeams).toBeDefined(); + expect(data.winsTeams).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsTeams).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLRatio).toBeDefined(); + expect(data.WLRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLRatio).toEqualTypeOf(); + expect(data.arrowsHit).toBeDefined(); + expect(data.arrowsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsHit).toEqualTypeOf(); + expect(data.arrowsFired).toBeDefined(); + expect(data.arrowsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsFired).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksTraveledBoat).toBeDefined(); + expect(data.blocksTraveledBoat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksTraveledBoat).toEqualTypeOf(); + expect(data.blocksTraveledHorse).toBeDefined(); + expect(data.blocksTraveledHorse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksTraveledHorse).toEqualTypeOf(); + expect(data.blocksTraveledMinecart).toBeDefined(); + expect(data.blocksTraveledMinecart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksTraveledMinecart).toEqualTypeOf(); + expect(data.blocksTraveledPig).toBeDefined(); + expect(data.blocksTraveledPig).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksTraveledPig).toEqualTypeOf(); + expect(data.bottlesThrown).toBeDefined(); + expect(data.bottlesThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bottlesThrown).toEqualTypeOf(); + expect(data.chestsOpened).toBeDefined(); + expect(data.chestsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chestsOpened).toEqualTypeOf(); + expect(data.damage).toBeDefined(); + expect(data.damage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damage).toEqualTypeOf(); + expect(data.damageTaken).toBeDefined(); + expect(data.damageTaken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageTaken).toEqualTypeOf(); + expect(data.eggsCollected).toBeDefined(); + expect(data.eggsCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggsCollected).toEqualTypeOf(); + expect(data.eggsThrown).toBeDefined(); + expect(data.eggsThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggsThrown).toEqualTypeOf(); + expect(data.explosiveKills).toBeDefined(); + expect(data.explosiveKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.explosiveKills).toEqualTypeOf(); + expect(data.fallDamage).toBeDefined(); + expect(data.fallDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fallDamage).toEqualTypeOf(); + expect(data.fallKills).toBeDefined(); + expect(data.fallKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fallKills).toEqualTypeOf(); + expect(data.itemsEnchanted).toBeDefined(); + expect(data.itemsEnchanted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemsEnchanted).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDRatio).toBeDefined(); + expect(data.KDRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatio).toEqualTypeOf(); + expect(data.mobsSpawned).toBeDefined(); + expect(data.mobsSpawned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mobsSpawned).toEqualTypeOf(); + expect(data.potionsDrunk).toBeDefined(); + expect(data.potionsDrunk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.potionsDrunk).toEqualTypeOf(); + expect(data.potionsThrown).toBeDefined(); + expect(data.potionsThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.potionsThrown).toEqualTypeOf(); + expect(data.railsPlaced).toBeDefined(); + expect(data.railsPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.railsPlaced).toEqualTypeOf(); + expect(data.snowballsThrown).toBeDefined(); + expect(data.snowballsThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowballsThrown).toEqualTypeOf(); + expect(data.tauntKills).toBeDefined(); + expect(data.tauntKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tauntKills).toEqualTypeOf(); + expect(data.timePlayed).toBeDefined(); + expect(data.timePlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timePlayed).toEqualTypeOf(); + expect(data.tntPlaced).toBeDefined(); + expect(data.tntPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tntPlaced).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.ts new file mode 100644 index 000000000..02ef91605 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.ts @@ -0,0 +1,77 @@ +import Divide from '../../../Utils/Divide.ts'; +import { ParseModeAfter } from '../../../Utils/ParseMode.ts'; +import type { BlitzSurvivalGamesKitId } from '../../../Types/Player.ts'; + +class BlitzSurvivalGamesData { + wins: number; + winsTeams: number; + gamesPlayed: number; + losses: number; + WLRatio: number; + arrowsHit: number; + arrowsFired: number; + bowAccuracy: number; + blocksTraveledBoat: number; + blocksTraveledHorse: number; + blocksTraveledMinecart: number; + blocksTraveledPig: number; + bottlesThrown: number; + chestsOpened: number; + damage: number; + damageTaken: number; + eggsCollected: number; + eggsThrown: number; + explosiveKills: number; + fallDamage: number; + fallKills: number; + itemsEnchanted: number; + kills: number; + deaths: number; + KDRatio: number; + mobsSpawned: number; + potionsDrunk: number; + potionsThrown: number; + railsPlaced: number; + snowballsThrown: number; + tauntKills: number; + timePlayed: number; + tntPlaced: number; + constructor(data: Record, kitName?: BlitzSurvivalGamesKitId) { + kitName = ParseModeAfter(kitName) as BlitzSurvivalGamesKitId; + this.wins = data?.[`wins${kitName}`] || 0; + this.winsTeams = data?.[`wins_teams${kitName}`] || 0; + this.gamesPlayed = data?.[`games_played${kitName}`] || 0; + this.losses = this.gamesPlayed - this.wins; + this.WLRatio = Divide(this.wins, this.losses); + this.arrowsHit = data?.[`arrows_hit${kitName}`] || 0; + this.arrowsFired = data?.[`arrows_fired${kitName}`] || 0; + this.bowAccuracy = Divide(this.arrowsHit, this.arrowsFired); + this.blocksTraveledBoat = data?.[`blocks_traveled_boat${kitName}`] || 0; + this.blocksTraveledHorse = data?.[`blocks_traveled_horse${kitName}`] || 0; + this.blocksTraveledMinecart = data?.[`blocks_traveled_minecart${kitName}`] || 0; + this.blocksTraveledPig = data?.[`blocks_traveled_pig${kitName}`] || 0; + this.bottlesThrown = data?.[`bottles_thrown${kitName}`] || 0; + this.chestsOpened = data?.[`chests_opened${kitName}`] || 0; + this.damage = data?.[`damage${kitName}`] || 0; + this.damageTaken = data?.[`damage_taken${kitName}`] || 0; + this.eggsCollected = data?.[`eggs_collected${kitName}`] || 0; + this.eggsThrown = data?.[`eggs_thrown${kitName}`] || 0; + this.explosiveKills = data?.[`explosive_kills${kitName}`] || 0; + this.fallDamage = data?.[`fall_damage${kitName}`] || 0; + this.fallKills = data?.[`fall_kills${kitName}`] || 0; + this.itemsEnchanted = data?.[`items_enchanted${kitName}`] || 0; + this.kills = data?.[`kills${kitName}`] || 0; + this.deaths = data?.[`deaths_${kitName}`] || 0; + this.KDRatio = Divide(this.kills, this.deaths); + this.mobsSpawned = data?.[`mobs_spawned${kitName}`] || 0; + this.potionsDrunk = data?.[`potions_drunk${kitName}`] || 0; + this.potionsThrown = data?.[`potions_thrown${kitName}`] || 0; + this.railsPlaced = data?.[`rails_placed${kitName}`] || 0; + this.snowballsThrown = data?.[`snowballs_thrown${kitName}`] || 0; + this.tauntKills = data?.[`taunt_kills${kitName}`] || 0; + this.timePlayed = data?.[`time_played${kitName}`] || 0; + this.tntPlaced = data?.[`tnt_placed${kitName}`] || 0; + } +} + +export default BlitzSurvivalGamesData; diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.test.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.test.ts new file mode 100644 index 000000000..a39a72967 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.test.ts @@ -0,0 +1,20 @@ +import BlitzSurvivalGamesKit from './BlitzSurvivalGamesKit.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BlitzSurvivalGamesKit', () => { + const data = new BlitzSurvivalGamesKit({ stats: 'meow' }, 'arachnologist'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BlitzSurvivalGamesKit); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.exp).toBeDefined(); + expect(data.exp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.exp).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expect(data.prestige).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prestige).toEqualTypeOf(); + expect(data.inventory).toBeDefined(); + expectTypeOf(data.inventory).toEqualTypeOf>(); +}); diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.ts new file mode 100644 index 000000000..373ec3287 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.ts @@ -0,0 +1,23 @@ +import BlitzSurvivalGamesData from './BlitzSurvivalGamesData.ts'; +import { ParseModeAfter } from '../../../Utils/ParseMode.ts'; +import type { BlitzSurvivalGamesKitId } from '../../../Types/Player.ts'; + +class BlitzSurvivalGamesKit extends BlitzSurvivalGamesData { + level: number; + exp: number; + prestige: number; + inventory: Record; + constructor(data: Record, kitName: BlitzSurvivalGamesKitId) { + super(data, kitName); + this.level = data?.[kitName] || 0; + kitName = ParseModeAfter(kitName) as BlitzSurvivalGamesKitId; + this.exp = data?.[`exp${kitName}`] || 0; + this.prestige = data?.[`p${kitName}`] || 0; + this.inventory = + data?.[ + `${kitName.replaceAll('_', '').charAt(0).toUpperCase()}${kitName.replaceAll('_', '').slice(1)}Inventory` + ] || {}; + } +} + +export default BlitzSurvivalGamesKit; diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.test.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.test.ts new file mode 100644 index 000000000..c61a8c063 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.test.ts @@ -0,0 +1,28 @@ +import BlitzSurvivalGamesPrivateGames from './BlitzSurvivalGamesPrivateGames.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + BlitzSurvivalGamesPrivateGamesExtraStars, + PrivateGameSettingsGameSpeed, + PrivateGameSettingsHealthBuff +} from '../../../Types/Player.js'; + +test('BlitzSurvivalGamesPrivateGames', () => { + const data = new BlitzSurvivalGamesPrivateGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BlitzSurvivalGamesPrivateGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.healthBuff).toBeDefined(); + expectTypeOf(data.healthBuff).toEqualTypeOf(); + expect(data.lowGravity).toBeDefined(); + expectTypeOf(data.lowGravity).toEqualTypeOf(); + expect(data.speed).toBeDefined(); + expectTypeOf(data.speed).toEqualTypeOf(); + expect(data.extraBlitzStars).toBeDefined(); + expectTypeOf(data.extraBlitzStars).toEqualTypeOf(); + expect(data.oneHitOneKill).toBeDefined(); + expectTypeOf(data.oneHitOneKill).toEqualTypeOf(); + expect(data.nightTime).toBeDefined(); + expectTypeOf(data.nightTime).toEqualTypeOf(); + expect(data.noKits).toBeDefined(); + expectTypeOf(data.noKits).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.ts b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.ts new file mode 100644 index 000000000..8d78005a0 --- /dev/null +++ b/src/Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.ts @@ -0,0 +1,26 @@ +import type { + BlitzSurvivalGamesPrivateGamesExtraStars, + PrivateGameSettingsGameSpeed, + PrivateGameSettingsHealthBuff +} from '../../../Types/Player.ts'; + +class BlitzSurvivalGamesPrivateGames { + healthBuff: PrivateGameSettingsHealthBuff | 'UNKNOWN'; + lowGravity: boolean; + speed: PrivateGameSettingsGameSpeed | 'UNKNOWN'; + extraBlitzStars: BlitzSurvivalGamesPrivateGamesExtraStars; + oneHitOneKill: boolean; + nightTime: boolean; + noKits: boolean; + constructor(data: Record) { + this.healthBuff = data?.health_buff || 'UNKNOWN'; + this.lowGravity = data?.low_gravity || false; + this.speed = data?.speed || 'UNKNOWN'; + this.extraBlitzStars = data?.extra_blitz_stars || '1 Star - Normal'; + this.oneHitOneKill = data?.one_hit_one_kill_blitz || false; + this.nightTime = data?.enable_night_time || false; + this.noKits = data?.no_kits || false; + } +} + +export default BlitzSurvivalGamesPrivateGames; diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattle.test.ts b/src/Structures/MiniGames/BuildBattle/BuildBattle.test.ts new file mode 100644 index 000000000..d05d7b0d7 --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattle.test.ts @@ -0,0 +1,123 @@ +import BuildBattle from './BuildBattle.js'; +import BuildBattleLastWin from './BuildBattleLastWin.js'; +import BuildBattleVotes from './BuildBattleVotes.js'; +import Emblem from '../Shared/Emblem/Emblem.js'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + BuildBattleBackdrop, + BuildBattleEmblemIcon, + BuildBattleHat, + BuildBattleIsland, + BuildBattleLeaderboardSettingsMode, + BuildBattleMovementTrail, + BuildBattlePackageItem, + BuildBattleSong, + BuildBattleSuit, + BuildBattleTitle, + BuildBattleVictoryDance, + ShopSort +} from '../../../Types/Player.js'; + +test('BuildBattle', () => { + const data = new BuildBattle({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BuildBattle); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeIsland).toBeDefined(); + expectTypeOf(data.activeIsland).toEqualTypeOf(); + expect(data.activeMovementTrail).toBeDefined(); + expectTypeOf(data.activeMovementTrail).toEqualTypeOf(); + expect(data.correctGuesses).toBeDefined(); + expect(data.correctGuesses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.correctGuesses).toEqualTypeOf(); + expect(data.emblem).toBeDefined(); + expectTypeOf(data.emblem).toEqualTypeOf>(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.lastPurchasedSong).toBeDefined(); + expectTypeOf(data.lastPurchasedSong).toEqualTypeOf(); + expect(data.lastWon).toBeDefined(); + expect(data.lastWon).toBeInstanceOf(BuildBattleLastWin); + expectTypeOf(data.lastWon).toEqualTypeOf(); + expect(data.leaderboardSettings).toBeDefined(); + expectTypeOf(data.leaderboardSettings).toEqualTypeOf>(); + expect(data.loadout).toBeDefined(); + expectTypeOf(data.loadout).toEqualTypeOf(); + expect(data.monthlyTokensA).toBeDefined(); + expect(data.monthlyTokensA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokensA).toEqualTypeOf(); + expect(data.monthlyTokensB).toBeDefined(); + expect(data.monthlyTokensB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokensB).toEqualTypeOf(); + expect(data.monthlyTokens).toBeDefined(); + expect(data.monthlyTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyTokens).toEqualTypeOf(); + expect(data.music).toBeDefined(); + expectTypeOf(data.music).toEqualTypeOf(); + expect(data.selectedHat).toBeDefined(); + expectTypeOf(data.selectedHat).toEqualTypeOf(); + expect(data.suit).toBeDefined(); + expectTypeOf(data.suit).toEqualTypeOf(); + expect(data.victoryDance).toBeDefined(); + expectTypeOf(data.victoryDance).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.score).toBeDefined(); + expect(data.score).toBeGreaterThanOrEqual(0); + expectTypeOf(data.score).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.selectedBackdrop).toBeDefined(); + expectTypeOf(data.selectedBackdrop).toEqualTypeOf(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.shopSortEnableOwnedFirst).toBeDefined(); + expectTypeOf(data.shopSortEnableOwnedFirst).toEqualTypeOf(); + expect(data.soloMostPoints).toBeDefined(); + expect(data.soloMostPoints).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloMostPoints).toEqualTypeOf(); + expect(data.superVotes).toBeDefined(); + expect(data.superVotes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.superVotes).toEqualTypeOf(); + expect(data.teamsMostPoints).toBeDefined(); + expect(data.teamsMostPoints).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsMostPoints).toEqualTypeOf(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.totalVotes).toBeDefined(); + expect(data.totalVotes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalVotes).toEqualTypeOf(); + expect(data.weeklyTokensA).toBeDefined(); + expect(data.weeklyTokensA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyTokensA).toEqualTypeOf(); + expect(data.weeklyTokensB).toBeDefined(); + expect(data.weeklyTokensB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyTokensB).toEqualTypeOf(); + expect(data.votes).toBeDefined(); + expect(data.votes).toBeInstanceOf(BuildBattleVotes); + expectTypeOf(data.votes).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.winsGuessTheBuild).toBeDefined(); + expect(data.winsGuessTheBuild).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsGuessTheBuild).toEqualTypeOf(); + expect(data.winsHalloween).toBeDefined(); + expect(data.winsHalloween).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsHalloween).toEqualTypeOf(); + expect(data.winsSoloNormal).toBeDefined(); + expect(data.winsSoloNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsSoloNormal).toEqualTypeOf(); + expect(data.winsSoloPro).toBeDefined(); + expect(data.winsSoloPro).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsSoloPro).toEqualTypeOf(); + expect(data.winsSpeedBuilders).toBeDefined(); + expect(data.winsSpeedBuilders).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsSpeedBuilders).toEqualTypeOf(); + expect(data.winsTeamsNormal).toBeDefined(); + expect(data.winsTeamsNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsTeamsNormal).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattle.ts b/src/Structures/MiniGames/BuildBattle/BuildBattle.ts new file mode 100644 index 000000000..638c656cd --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattle.ts @@ -0,0 +1,114 @@ +import BuildBattleLastWin from './BuildBattleLastWin.js'; +import BuildBattleVotes from './BuildBattleVotes.js'; +import Emblem from '../Shared/Emblem/Emblem.js'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import { BuildBattleTitleRequirements } from '../../../Utils/Constants.js'; +import { monthAB } from '../../../Utils/Oscillation.js'; +import type { + BuildBattleBackdrop, + BuildBattleEmblemIcon, + BuildBattleHat, + BuildBattleIsland, + BuildBattleLeaderboardSettingsMode, + BuildBattleMovementTrail, + BuildBattlePackageItem, + BuildBattleSong, + BuildBattleSuit, + BuildBattleTitle, + BuildBattleVictoryDance, + ShopSort +} from '../../../Types/Player.js'; + +class BuildBattle { + activeIsland: BuildBattleIsland | 'island_none'; + activeMovementTrail: BuildBattleMovementTrail | 'movement_trail_none'; + correctGuesses: number; + emblem: Emblem; + playedGames: number; + lastPurchasedSong: BuildBattleSong | 'UNKNOWN'; + lastWon: BuildBattleLastWin; + leaderboardSettings: LeaderboardSettings; + loadout: string[]; + monthlyTokensA: number; + monthlyTokensB: number; + monthlyTokens: number; + music: boolean; + selectedHat: BuildBattleHat | 'hats_none'; + suit: BuildBattleSuit | 'suit_none'; + victoryDance: BuildBattleVictoryDance | 'victory_dance_none'; + packages: BuildBattlePackageItem[]; + score: number; + title: BuildBattleTitle; + selectedBackdrop: BuildBattleBackdrop | 'backdrops_none'; + shopSort: ShopSort | 'UNKNOWN'; + shopSortEnableOwnedFirst: boolean; + soloMostPoints: number; + superVotes: number; + teamsMostPoints: number; + tokens: number; + totalVotes: number; + weeklyTokensA: number; + weeklyTokensB: number; + votes: BuildBattleVotes; + wins: number; + winsGuessTheBuild: number; + winsHalloween: number; + winsSoloNormal: number; + winsSoloPro: number; + winsSpeedBuilders: number; + winsTeamsNormal: number; + constructor(data: Record) { + this.activeIsland = data?.active_island || 'island_none'; + this.activeMovementTrail = data?.active_movement_trail || 'movement_trail_none'; + this.correctGuesses = data?.correct_guesses || 0; + this.emblem = new Emblem(data?.emblem || {}); + this.playedGames = data?.games_played || 0; + this.lastPurchasedSong = data?.last_purchased_song || 'UNKNOWN'; + this.lastWon = new BuildBattleLastWin(data?.last_won || {}); + this.leaderboardSettings = new LeaderboardSettings( + data?.leaderboardSettings || {} + ); + this.loadout = data?.buildbattle_loadout || []; + this.monthlyTokensA = data?.monthly_tokens_a || data?.monthly_coins_a || 0; + this.monthlyTokensB = data?.monthly_tokens_b || data?.monthly_coins_b || 0; + this.monthlyTokens = data?.[`monthly_tokens_${monthAB()}`] || data?.[`monthly_coins_${monthAB()}`] || 0; + this.music = data?.music || true; + this.selectedHat = data?.new_selected_hat || 'hats_none'; + this.suit = data?.new_suit || 'suit_none'; + this.victoryDance = data?.new_victory_dance || 'victory_dance_none'; + this.packages = data?.packages || []; + this.score = data?.score || 0; + this.title = BuildBattle.getBuildBattleTitle(this.score); + this.selectedBackdrop = data?.selected_backdrop || 'backdrops_none'; + this.shopSort = data?.shop_sort || 'UNKNOWN'; + this.shopSortEnableOwnedFirst = data?.shop_sort_enable_owned_first || false; + this.soloMostPoints = data?.solo_most_points || 0; + this.superVotes = data?.super_votes || 0; + this.teamsMostPoints = data?.teams_most_points || 0; + this.tokens = data?.tokens || data?.coins || 0; + this.totalVotes = data?.total_votes || 0; + this.weeklyTokensA = data?.weekly_tokens_a || data?.weekly_coins_a || 0; + this.weeklyTokensB = data?.weekly_tokens_b || data?.weekly_coins_b || 0; + this.monthlyTokens = data?.[`weekly_tokens_${monthAB()}`] || data?.[`weekly_coins_${monthAB()}`] || 0; + this.votes = new BuildBattleVotes(data); + this.wins = data?.wins || 0; + this.winsGuessTheBuild = data?.wins_guess_the_build || 0; + this.winsHalloween = data?.wins_halloween || 0; + this.winsSoloNormal = data?.wins_solo_normal || 0; + this.winsSoloPro = data?.wins_solo_pro || 0; + this.winsSpeedBuilders = data?.wins_speed_builders || 0; + this.winsTeamsNormal = data?.wins_teams_normal || 0; + } + + static getBuildBattleTitle(score: number): BuildBattleTitle { + return ( + ( + BuildBattleTitleRequirements.slice() + .reverse() + .find((t) => score >= t.requirement) || BuildBattleTitleRequirements[0] + )?.title || 'Rookie' + ); + } +} + +export default BuildBattle; diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.test.ts b/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.test.ts new file mode 100644 index 000000000..709ec23e7 --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.test.ts @@ -0,0 +1,19 @@ +import BuildBattleLastWin from './BuildBattleLastWin.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BuildBattleLastWin', () => { + const data = new BuildBattleLastWin({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BuildBattleLastWin); + expectTypeOf(data).toEqualTypeOf(); + expect(data.guessTheBuildAt).toBeDefined(); + expectTypeOf(data.guessTheBuildAt).toEqualTypeOf(); + expect(data.soloNormalAt).toBeDefined(); + expectTypeOf(data.soloNormalAt).toEqualTypeOf(); + expect(data.soloProAt).toBeDefined(); + expectTypeOf(data.soloProAt).toEqualTypeOf(); + expect(data.speedBuildersAt).toBeDefined(); + expectTypeOf(data.speedBuildersAt).toEqualTypeOf(); + expect(data.teamsNormalAt).toBeDefined(); + expectTypeOf(data.teamsNormalAt).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.ts b/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.ts new file mode 100644 index 000000000..5c0668aac --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattleLastWin.ts @@ -0,0 +1,16 @@ +class BuildBattleLastWin { + guessTheBuildAt: Date | null; + soloNormalAt: Date | null; + soloProAt: Date | null; + speedBuildersAt: Date | null; + teamsNormalAt: Date | null; + constructor(data: Record) { + this.guessTheBuildAt = data?.GUESS_THE_BUILD ? new Date(data?.GUESS_THE_BUILD) : null; + this.soloNormalAt = data?.SOLO_NORMAL ? new Date(data?.SOLO_NORMAL) : null; + this.soloProAt = data?.SOLO_PRO ? new Date(data?.SOLO_PRO) : null; + this.speedBuildersAt = data?.SPEED_BUILDERS ? new Date(data?.SPEED_BUILDERS) : null; + this.teamsNormalAt = data?.TEAMS_NORMAL ? new Date(data?.TEAMS_NORMAL) : null; + } +} + +export default BuildBattleLastWin; diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.test.ts b/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.test.ts new file mode 100644 index 000000000..575d0629f --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.test.ts @@ -0,0 +1,1869 @@ +import BuildBattleVotes from './BuildBattleVotes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BuildBattleVotes', () => { + const data = new BuildBattleVotes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BuildBattleVotes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.abandoned).toBeDefined(); + expect(data.abandoned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.abandoned).toEqualTypeOf(); + expect(data.abandonedMansion).toBeDefined(); + expect(data.abandonedMansion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.abandonedMansion).toEqualTypeOf(); + expect(data.adventCalendar).toBeDefined(); + expect(data.adventCalendar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.adventCalendar).toEqualTypeOf(); + expect(data.airplane).toBeDefined(); + expect(data.airplane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.airplane).toEqualTypeOf(); + expect(data.aladdin).toBeDefined(); + expect(data.aladdin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.aladdin).toEqualTypeOf(); + expect(data.alien).toBeDefined(); + expect(data.alien).toBeGreaterThanOrEqual(0); + expectTypeOf(data.alien).toEqualTypeOf(); + expect(data.alienInvasion).toBeDefined(); + expect(data.alienInvasion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.alienInvasion).toEqualTypeOf(); + expect(data.anchor).toBeDefined(); + expect(data.anchor).toBeGreaterThanOrEqual(0); + expectTypeOf(data.anchor).toEqualTypeOf(); + expect(data.ancient).toBeDefined(); + expect(data.ancient).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ancient).toEqualTypeOf(); + expect(data.angel).toBeDefined(); + expect(data.angel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.angel).toEqualTypeOf(); + expect(data.angry).toBeDefined(); + expect(data.angry).toBeGreaterThanOrEqual(0); + expectTypeOf(data.angry).toEqualTypeOf(); + expect(data.animal).toBeDefined(); + expect(data.animal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.animal).toEqualTypeOf(); + expect(data.ant).toBeDefined(); + expect(data.ant).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ant).toEqualTypeOf(); + expect(data.apocalyptic).toBeDefined(); + expect(data.apocalyptic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.apocalyptic).toEqualTypeOf(); + expect(data.apple).toBeDefined(); + expect(data.apple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.apple).toEqualTypeOf(); + expect(data.aquarium).toBeDefined(); + expect(data.aquarium).toBeGreaterThanOrEqual(0); + expectTypeOf(data.aquarium).toEqualTypeOf(); + expect(data.arcade).toBeDefined(); + expect(data.arcade).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arcade).toEqualTypeOf(); + expect(data.arcadeMachine).toBeDefined(); + expect(data.arcadeMachine).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arcadeMachine).toEqualTypeOf(); + expect(data.archer).toBeDefined(); + expect(data.archer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.archer).toEqualTypeOf(); + expect(data.arm).toBeDefined(); + expect(data.arm).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arm).toEqualTypeOf(); + expect(data.astronaut).toBeDefined(); + expect(data.astronaut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.astronaut).toEqualTypeOf(); + expect(data.awards).toBeDefined(); + expect(data.awards).toBeGreaterThanOrEqual(0); + expectTypeOf(data.awards).toEqualTypeOf(); + expect(data.axe).toBeDefined(); + expect(data.axe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.axe).toEqualTypeOf(); + expect(data.baby).toBeDefined(); + expect(data.baby).toBeGreaterThanOrEqual(0); + expectTypeOf(data.baby).toEqualTypeOf(); + expect(data.backpack).toBeDefined(); + expect(data.backpack).toBeGreaterThanOrEqual(0); + expectTypeOf(data.backpack).toEqualTypeOf(); + expect(data.bacon).toBeDefined(); + expect(data.bacon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bacon).toEqualTypeOf(); + expect(data.bakery).toBeDefined(); + expect(data.bakery).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bakery).toEqualTypeOf(); + expect(data.baking).toBeDefined(); + expect(data.baking).toBeGreaterThanOrEqual(0); + expectTypeOf(data.baking).toEqualTypeOf(); + expect(data.balloon).toBeDefined(); + expect(data.balloon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.balloon).toEqualTypeOf(); + expect(data.banana).toBeDefined(); + expect(data.banana).toBeGreaterThanOrEqual(0); + expectTypeOf(data.banana).toEqualTypeOf(); + expect(data.barbeque).toBeDefined(); + expect(data.barbeque).toBeGreaterThanOrEqual(0); + expectTypeOf(data.barbeque).toEqualTypeOf(); + expect(data.barn).toBeDefined(); + expect(data.barn).toBeGreaterThanOrEqual(0); + expectTypeOf(data.barn).toEqualTypeOf(); + expect(data.bat).toBeDefined(); + expect(data.bat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bat).toEqualTypeOf(); + expect(data.bath).toBeDefined(); + expect(data.bath).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bath).toEqualTypeOf(); + expect(data.bats).toBeDefined(); + expect(data.bats).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bats).toEqualTypeOf(); + expect(data.battle).toBeDefined(); + expect(data.battle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.battle).toEqualTypeOf(); + expect(data.baubles).toBeDefined(); + expect(data.baubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.baubles).toEqualTypeOf(); + expect(data.beach).toBeDefined(); + expect(data.beach).toBeGreaterThanOrEqual(0); + expectTypeOf(data.beach).toEqualTypeOf(); + expect(data.beanstalk).toBeDefined(); + expect(data.beanstalk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.beanstalk).toEqualTypeOf(); + expect(data.bear).toBeDefined(); + expect(data.bear).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bear).toEqualTypeOf(); + expect(data.beard).toBeDefined(); + expect(data.beard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.beard).toEqualTypeOf(); + expect(data.bed).toBeDefined(); + expect(data.bed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bed).toEqualTypeOf(); + expect(data.bee).toBeDefined(); + expect(data.bee).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bee).toEqualTypeOf(); + expect(data.bell).toBeDefined(); + expect(data.bell).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bell).toEqualTypeOf(); + expect(data.bike).toBeDefined(); + expect(data.bike).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bike).toEqualTypeOf(); + expect(data.bikeRiding).toBeDefined(); + expect(data.bikeRiding).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bikeRiding).toEqualTypeOf(); + expect(data.bird).toBeDefined(); + expect(data.bird).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bird).toEqualTypeOf(); + expect(data.birdHouse).toBeDefined(); + expect(data.birdHouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.birdHouse).toEqualTypeOf(); + expect(data.birthday).toBeDefined(); + expect(data.birthday).toBeGreaterThanOrEqual(0); + expectTypeOf(data.birthday).toEqualTypeOf(); + expect(data.birthdayParty).toBeDefined(); + expect(data.birthdayParty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.birthdayParty).toEqualTypeOf(); + expect(data.blaze).toBeDefined(); + expect(data.blaze).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blaze).toEqualTypeOf(); + expect(data.blizzard).toBeDefined(); + expect(data.blizzard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blizzard).toEqualTypeOf(); + expect(data.block).toBeDefined(); + expect(data.block).toBeGreaterThanOrEqual(0); + expectTypeOf(data.block).toEqualTypeOf(); + expect(data.blocks).toBeDefined(); + expect(data.blocks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocks).toEqualTypeOf(); + expect(data.boardGames).toBeDefined(); + expect(data.boardGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boardGames).toEqualTypeOf(); + expect(data.boardgames).toBeDefined(); + expect(data.boardgames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boardgames).toEqualTypeOf(); + expect(data.boat).toBeDefined(); + expect(data.boat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boat).toEqualTypeOf(); + expect(data.bobsledding).toBeDefined(); + expect(data.bobsledding).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bobsledding).toEqualTypeOf(); + expect(data.bones).toBeDefined(); + expect(data.bones).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bones).toEqualTypeOf(); + expect(data.boogeyman).toBeDefined(); + expect(data.boogeyman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boogeyman).toEqualTypeOf(); + expect(data.book).toBeDefined(); + expect(data.book).toBeGreaterThanOrEqual(0); + expectTypeOf(data.book).toEqualTypeOf(); + expect(data.boot).toBeDefined(); + expect(data.boot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boot).toEqualTypeOf(); + expect(data.bottle).toBeDefined(); + expect(data.bottle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bottle).toEqualTypeOf(); + expect(data.bouncyCastle).toBeDefined(); + expect(data.bouncyCastle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bouncyCastle).toEqualTypeOf(); + expect(data.bowlingAlley).toBeDefined(); + expect(data.bowlingAlley).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowlingAlley).toEqualTypeOf(); + expect(data.box).toBeDefined(); + expect(data.box).toBeGreaterThanOrEqual(0); + expectTypeOf(data.box).toEqualTypeOf(); + expect(data.boxingRing).toBeDefined(); + expect(data.boxingRing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boxingRing).toEqualTypeOf(); + expect(data.boy).toBeDefined(); + expect(data.boy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boy).toEqualTypeOf(); + expect(data.brain).toBeDefined(); + expect(data.brain).toBeGreaterThanOrEqual(0); + expectTypeOf(data.brain).toEqualTypeOf(); + expect(data.branch).toBeDefined(); + expect(data.branch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.branch).toEqualTypeOf(); + expect(data.bread).toBeDefined(); + expect(data.bread).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bread).toEqualTypeOf(); + expect(data.breakfast).toBeDefined(); + expect(data.breakfast).toBeGreaterThanOrEqual(0); + expectTypeOf(data.breakfast).toEqualTypeOf(); + expect(data.brewingStand).toBeDefined(); + expect(data.brewingStand).toBeGreaterThanOrEqual(0); + expectTypeOf(data.brewingStand).toEqualTypeOf(); + expect(data.bridge).toBeDefined(); + expect(data.bridge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bridge).toEqualTypeOf(); + expect(data.brokenBridge).toBeDefined(); + expect(data.brokenBridge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.brokenBridge).toEqualTypeOf(); + expect(data.broomstick).toBeDefined(); + expect(data.broomstick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.broomstick).toEqualTypeOf(); + expect(data.bucket).toBeDefined(); + expect(data.bucket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bucket).toEqualTypeOf(); + expect(data.bug).toBeDefined(); + expect(data.bug).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bug).toEqualTypeOf(); + expect(data.builder).toBeDefined(); + expect(data.builder).toBeGreaterThanOrEqual(0); + expectTypeOf(data.builder).toEqualTypeOf(); + expect(data.bunny).toBeDefined(); + expect(data.bunny).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bunny).toEqualTypeOf(); + expect(data.buried).toBeDefined(); + expect(data.buried).toBeGreaterThanOrEqual(0); + expectTypeOf(data.buried).toEqualTypeOf(); + expect(data.butterflies).toBeDefined(); + expect(data.butterflies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.butterflies).toEqualTypeOf(); + expect(data.butterfly).toBeDefined(); + expect(data.butterfly).toBeGreaterThanOrEqual(0); + expectTypeOf(data.butterfly).toEqualTypeOf(); + expect(data.button).toBeDefined(); + expect(data.button).toBeGreaterThanOrEqual(0); + expectTypeOf(data.button).toEqualTypeOf(); + expect(data.cabin).toBeDefined(); + expect(data.cabin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cabin).toEqualTypeOf(); + expect(data.cake).toBeDefined(); + expect(data.cake).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cake).toEqualTypeOf(); + expect(data.camel).toBeDefined(); + expect(data.camel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.camel).toEqualTypeOf(); + expect(data.camera).toBeDefined(); + expect(data.camera).toBeGreaterThanOrEqual(0); + expectTypeOf(data.camera).toEqualTypeOf(); + expect(data.camp).toBeDefined(); + expect(data.camp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.camp).toEqualTypeOf(); + expect(data.campfire).toBeDefined(); + expect(data.campfire).toBeGreaterThanOrEqual(0); + expectTypeOf(data.campfire).toEqualTypeOf(); + expect(data.camping).toBeDefined(); + expect(data.camping).toBeGreaterThanOrEqual(0); + expectTypeOf(data.camping).toEqualTypeOf(); + expect(data.campsite).toBeDefined(); + expect(data.campsite).toBeGreaterThanOrEqual(0); + expectTypeOf(data.campsite).toEqualTypeOf(); + expect(data.candle).toBeDefined(); + expect(data.candle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candle).toEqualTypeOf(); + expect(data.candlelight).toBeDefined(); + expect(data.candlelight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candlelight).toEqualTypeOf(); + expect(data.candles).toBeDefined(); + expect(data.candles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candles).toEqualTypeOf(); + expect(data.candy).toBeDefined(); + expect(data.candy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candy).toEqualTypeOf(); + expect(data.candyBuckets).toBeDefined(); + expect(data.candyBuckets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candyBuckets).toEqualTypeOf(); + expect(data.candyCane).toBeDefined(); + expect(data.candyCane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candyCane).toEqualTypeOf(); + expect(data.cannon).toBeDefined(); + expect(data.cannon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cannon).toEqualTypeOf(); + expect(data.car).toBeDefined(); + expect(data.car).toBeGreaterThanOrEqual(0); + expectTypeOf(data.car).toEqualTypeOf(); + expect(data.caribbean).toBeDefined(); + expect(data.caribbean).toBeGreaterThanOrEqual(0); + expectTypeOf(data.caribbean).toEqualTypeOf(); + expect(data.carnival).toBeDefined(); + expect(data.carnival).toBeGreaterThanOrEqual(0); + expectTypeOf(data.carnival).toEqualTypeOf(); + expect(data.carolling).toBeDefined(); + expect(data.carolling).toBeGreaterThanOrEqual(0); + expectTypeOf(data.carolling).toEqualTypeOf(); + expect(data.cart).toBeDefined(); + expect(data.cart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cart).toEqualTypeOf(); + expect(data.cartoon).toBeDefined(); + expect(data.cartoon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cartoon).toEqualTypeOf(); + expect(data.castle).toBeDefined(); + expect(data.castle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.castle).toEqualTypeOf(); + expect(data.cat).toBeDefined(); + expect(data.cat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cat).toEqualTypeOf(); + expect(data.catapult).toBeDefined(); + expect(data.catapult).toBeGreaterThanOrEqual(0); + expectTypeOf(data.catapult).toEqualTypeOf(); + expect(data.caterpillar).toBeDefined(); + expect(data.caterpillar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.caterpillar).toEqualTypeOf(); + expect(data.cauldron).toBeDefined(); + expect(data.cauldron).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cauldron).toEqualTypeOf(); + expect(data.cave).toBeDefined(); + expect(data.cave).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cave).toEqualTypeOf(); + expect(data.celebration).toBeDefined(); + expect(data.celebration).toBeGreaterThanOrEqual(0); + expectTypeOf(data.celebration).toEqualTypeOf(); + expect(data.cellar).toBeDefined(); + expect(data.cellar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cellar).toEqualTypeOf(); + expect(data.cheese).toBeDefined(); + expect(data.cheese).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cheese).toEqualTypeOf(); + expect(data.chemistry).toBeDefined(); + expect(data.chemistry).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chemistry).toEqualTypeOf(); + expect(data.cherry).toBeDefined(); + expect(data.cherry).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cherry).toEqualTypeOf(); + expect(data.cherryBlossom).toBeDefined(); + expect(data.cherryBlossom).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cherryBlossom).toEqualTypeOf(); + expect(data.cherryBlossoms).toBeDefined(); + expect(data.cherryBlossoms).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cherryBlossoms).toEqualTypeOf(); + expect(data.chess).toBeDefined(); + expect(data.chess).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chess).toEqualTypeOf(); + expect(data.chest).toBeDefined(); + expect(data.chest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chest).toEqualTypeOf(); + expect(data.chicken).toBeDefined(); + expect(data.chicken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chicken).toEqualTypeOf(); + expect(data.chimney).toBeDefined(); + expect(data.chimney).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chimney).toEqualTypeOf(); + expect(data.chocolate).toBeDefined(); + expect(data.chocolate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chocolate).toEqualTypeOf(); + expect(data.chocolateFactory).toBeDefined(); + expect(data.chocolateFactory).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chocolateFactory).toEqualTypeOf(); + expect(data.choir).toBeDefined(); + expect(data.choir).toBeGreaterThanOrEqual(0); + expectTypeOf(data.choir).toEqualTypeOf(); + expect(data.christmasCard).toBeDefined(); + expect(data.christmasCard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasCard).toEqualTypeOf(); + expect(data.christmasDinner).toBeDefined(); + expect(data.christmasDinner).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasDinner).toEqualTypeOf(); + expect(data.christmasEve).toBeDefined(); + expect(data.christmasEve).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasEve).toEqualTypeOf(); + expect(data.christmasGift).toBeDefined(); + expect(data.christmasGift).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasGift).toEqualTypeOf(); + expect(data.christmasMorning).toBeDefined(); + expect(data.christmasMorning).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasMorning).toEqualTypeOf(); + expect(data.christmasTree).toBeDefined(); + expect(data.christmasTree).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasTree).toEqualTypeOf(); + expect(data.cinema).toBeDefined(); + expect(data.cinema).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cinema).toEqualTypeOf(); + expect(data.circus).toBeDefined(); + expect(data.circus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.circus).toEqualTypeOf(); + expect(data.clock).toBeDefined(); + expect(data.clock).toBeGreaterThanOrEqual(0); + expectTypeOf(data.clock).toEqualTypeOf(); + expect(data.cloud).toBeDefined(); + expect(data.cloud).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cloud).toEqualTypeOf(); + expect(data.clown).toBeDefined(); + expect(data.clown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.clown).toEqualTypeOf(); + expect(data.cobweb).toBeDefined(); + expect(data.cobweb).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cobweb).toEqualTypeOf(); + expect(data.coconut).toBeDefined(); + expect(data.coconut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coconut).toEqualTypeOf(); + expect(data.coffin).toBeDefined(); + expect(data.coffin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coffin).toEqualTypeOf(); + expect(data.comet).toBeDefined(); + expect(data.comet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.comet).toEqualTypeOf(); + expect(data.computer).toBeDefined(); + expect(data.computer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.computer).toEqualTypeOf(); + expect(data.cookieMountain).toBeDefined(); + expect(data.cookieMountain).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cookieMountain).toEqualTypeOf(); + expect(data.corpseBride).toBeDefined(); + expect(data.corpseBride).toBeGreaterThanOrEqual(0); + expectTypeOf(data.corpseBride).toEqualTypeOf(); + expect(data.costume).toBeDefined(); + expect(data.costume).toBeGreaterThanOrEqual(0); + expectTypeOf(data.costume).toEqualTypeOf(); + expect(data.cowboy).toBeDefined(); + expect(data.cowboy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cowboy).toEqualTypeOf(); + expect(data.crab).toBeDefined(); + expect(data.crab).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crab).toEqualTypeOf(); + expect(data.craftingTable).toBeDefined(); + expect(data.craftingTable).toBeGreaterThanOrEqual(0); + expectTypeOf(data.craftingTable).toEqualTypeOf(); + expect(data.crane).toBeDefined(); + expect(data.crane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crane).toEqualTypeOf(); + expect(data.crayon).toBeDefined(); + expect(data.crayon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crayon).toEqualTypeOf(); + expect(data.crayons).toBeDefined(); + expect(data.crayons).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crayons).toEqualTypeOf(); + expect(data.creeper).toBeDefined(); + expect(data.creeper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.creeper).toEqualTypeOf(); + expect(data.crocodile).toBeDefined(); + expect(data.crocodile).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crocodile).toEqualTypeOf(); + expect(data.crystalBall).toBeDefined(); + expect(data.crystalBall).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crystalBall).toEqualTypeOf(); + expect(data.cup).toBeDefined(); + expect(data.cup).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cup).toEqualTypeOf(); + expect(data.curtain).toBeDefined(); + expect(data.curtain).toBeGreaterThanOrEqual(0); + expectTypeOf(data.curtain).toEqualTypeOf(); + expect(data.cushion).toBeDefined(); + expect(data.cushion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cushion).toEqualTypeOf(); + expect(data.dancer).toBeDefined(); + expect(data.dancer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dancer).toEqualTypeOf(); + expect(data.darkWoods).toBeDefined(); + expect(data.darkWoods).toBeGreaterThanOrEqual(0); + expectTypeOf(data.darkWoods).toEqualTypeOf(); + expect(data.decoratedHouse).toBeDefined(); + expect(data.decoratedHouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.decoratedHouse).toEqualTypeOf(); + expect(data.demon).toBeDefined(); + expect(data.demon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.demon).toEqualTypeOf(); + expect(data.dice).toBeDefined(); + expect(data.dice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dice).toEqualTypeOf(); + expect(data.dinosaur).toBeDefined(); + expect(data.dinosaur).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dinosaur).toEqualTypeOf(); + expect(data.disco).toBeDefined(); + expect(data.disco).toBeGreaterThanOrEqual(0); + expectTypeOf(data.disco).toEqualTypeOf(); + expect(data.disguise).toBeDefined(); + expect(data.disguise).toBeGreaterThanOrEqual(0); + expectTypeOf(data.disguise).toEqualTypeOf(); + expect(data.doll).toBeDefined(); + expect(data.doll).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doll).toEqualTypeOf(); + expect(data.dollhouse).toBeDefined(); + expect(data.dollhouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dollhouse).toEqualTypeOf(); + expect(data.dolphin).toBeDefined(); + expect(data.dolphin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dolphin).toEqualTypeOf(); + expect(data.doorbell).toBeDefined(); + expect(data.doorbell).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doorbell).toEqualTypeOf(); + expect(data.doughnut).toBeDefined(); + expect(data.doughnut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doughnut).toEqualTypeOf(); + expect(data.doughnuts).toBeDefined(); + expect(data.doughnuts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doughnuts).toEqualTypeOf(); + expect(data.dracula).toBeDefined(); + expect(data.dracula).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dracula).toEqualTypeOf(); + expect(data.dragon).toBeDefined(); + expect(data.dragon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dragon).toEqualTypeOf(); + expect(data.dress).toBeDefined(); + expect(data.dress).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dress).toEqualTypeOf(); + expect(data.drill).toBeDefined(); + expect(data.drill).toBeGreaterThanOrEqual(0); + expectTypeOf(data.drill).toEqualTypeOf(); + expect(data.drink).toBeDefined(); + expect(data.drink).toBeGreaterThanOrEqual(0); + expectTypeOf(data.drink).toEqualTypeOf(); + expect(data.droid).toBeDefined(); + expect(data.droid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.droid).toEqualTypeOf(); + expect(data.drum).toBeDefined(); + expect(data.drum).toBeGreaterThanOrEqual(0); + expectTypeOf(data.drum).toEqualTypeOf(); + expect(data.dungeon).toBeDefined(); + expect(data.dungeon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dungeon).toEqualTypeOf(); + expect(data.earmuffs).toBeDefined(); + expect(data.earmuffs).toBeGreaterThanOrEqual(0); + expectTypeOf(data.earmuffs).toEqualTypeOf(); + expect(data.earth).toBeDefined(); + expect(data.earth).toBeGreaterThanOrEqual(0); + expectTypeOf(data.earth).toEqualTypeOf(); + expect(data.easterEgg).toBeDefined(); + expect(data.easterEgg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.easterEgg).toEqualTypeOf(); + expect(data.eatingCompetition).toBeDefined(); + expect(data.eatingCompetition).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eatingCompetition).toEqualTypeOf(); + expect(data.eggBasket).toBeDefined(); + expect(data.eggBasket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggBasket).toEqualTypeOf(); + expect(data.egyptain).toBeDefined(); + expect(data.egyptain).toBeGreaterThanOrEqual(0); + expectTypeOf(data.egyptain).toEqualTypeOf(); + expect(data.egyptian).toBeDefined(); + expect(data.egyptian).toBeGreaterThanOrEqual(0); + expectTypeOf(data.egyptian).toEqualTypeOf(); + expect(data.eiffelTower).toBeDefined(); + expect(data.eiffelTower).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eiffelTower).toEqualTypeOf(); + expect(data.elephant).toBeDefined(); + expect(data.elephant).toBeGreaterThanOrEqual(0); + expectTypeOf(data.elephant).toEqualTypeOf(); + expect(data.elf).toBeDefined(); + expect(data.elf).toBeGreaterThanOrEqual(0); + expectTypeOf(data.elf).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.engine).toBeDefined(); + expect(data.engine).toBeGreaterThanOrEqual(0); + expectTypeOf(data.engine).toEqualTypeOf(); + expect(data.ethereal).toBeDefined(); + expect(data.ethereal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ethereal).toEqualTypeOf(); + expect(data.evergreenTree).toBeDefined(); + expect(data.evergreenTree).toBeGreaterThanOrEqual(0); + expectTypeOf(data.evergreenTree).toEqualTypeOf(); + expect(data.evilCat).toBeDefined(); + expect(data.evilCat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.evilCat).toEqualTypeOf(); + expect(data.evilClown).toBeDefined(); + expect(data.evilClown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.evilClown).toEqualTypeOf(); + expect(data.extraterrestrial).toBeDefined(); + expect(data.extraterrestrial).toBeGreaterThanOrEqual(0); + expectTypeOf(data.extraterrestrial).toEqualTypeOf(); + expect(data.eye).toBeDefined(); + expect(data.eye).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eye).toEqualTypeOf(); + expect(data.fairy).toBeDefined(); + expect(data.fairy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fairy).toEqualTypeOf(); + expect(data.family).toBeDefined(); + expect(data.family).toBeGreaterThanOrEqual(0); + expectTypeOf(data.family).toEqualTypeOf(); + expect(data.fancy).toBeDefined(); + expect(data.fancy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fancy).toEqualTypeOf(); + expect(data.fangs).toBeDefined(); + expect(data.fangs).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fangs).toEqualTypeOf(); + expect(data.fantasy).toBeDefined(); + expect(data.fantasy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fantasy).toEqualTypeOf(); + expect(data.farm).toBeDefined(); + expect(data.farm).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farm).toEqualTypeOf(); + expect(data.farmersMarket).toBeDefined(); + expect(data.farmersMarket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farmersMarket).toEqualTypeOf(); + expect(data.feast).toBeDefined(); + expect(data.feast).toBeGreaterThanOrEqual(0); + expectTypeOf(data.feast).toEqualTypeOf(); + expect(data.feather).toBeDefined(); + expect(data.feather).toBeGreaterThanOrEqual(0); + expectTypeOf(data.feather).toEqualTypeOf(); + expect(data.fire).toBeDefined(); + expect(data.fire).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fire).toEqualTypeOf(); + expect(data.fireplace).toBeDefined(); + expect(data.fireplace).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fireplace).toEqualTypeOf(); + expect(data.firetruck).toBeDefined(); + expect(data.firetruck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.firetruck).toEqualTypeOf(); + expect(data.firework).toBeDefined(); + expect(data.firework).toBeGreaterThanOrEqual(0); + expectTypeOf(data.firework).toEqualTypeOf(); + expect(data.fireworks).toBeDefined(); + expect(data.fireworks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fireworks).toEqualTypeOf(); + expect(data.fishingRod).toBeDefined(); + expect(data.fishingRod).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fishingRod).toEqualTypeOf(); + expect(data.flag).toBeDefined(); + expect(data.flag).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flag).toEqualTypeOf(); + expect(data.flamingo).toBeDefined(); + expect(data.flamingo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flamingo).toEqualTypeOf(); + expect(data.flashlight).toBeDefined(); + expect(data.flashlight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flashlight).toEqualTypeOf(); + expect(data.floatingIsland).toBeDefined(); + expect(data.floatingIsland).toBeGreaterThanOrEqual(0); + expectTypeOf(data.floatingIsland).toEqualTypeOf(); + expect(data.flower).toBeDefined(); + expect(data.flower).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flower).toEqualTypeOf(); + expect(data.flowerPatch).toBeDefined(); + expect(data.flowerPatch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flowerPatch).toEqualTypeOf(); + expect(data.fly).toBeDefined(); + expect(data.fly).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fly).toEqualTypeOf(); + expect(data.flying).toBeDefined(); + expect(data.flying).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flying).toEqualTypeOf(); + expect(data.flyingPig).toBeDefined(); + expect(data.flyingPig).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flyingPig).toEqualTypeOf(); + expect(data.flyingSaucer).toBeDefined(); + expect(data.flyingSaucer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.flyingSaucer).toEqualTypeOf(); + expect(data.foot).toBeDefined(); + expect(data.foot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.foot).toEqualTypeOf(); + expect(data.football).toBeDefined(); + expect(data.football).toBeGreaterThanOrEqual(0); + expectTypeOf(data.football).toEqualTypeOf(); + expect(data.forge).toBeDefined(); + expect(data.forge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.forge).toEqualTypeOf(); + expect(data.fork).toBeDefined(); + expect(data.fork).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fork).toEqualTypeOf(); + expect(data.fortuneteller).toBeDefined(); + expect(data.fortuneteller).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fortuneteller).toEqualTypeOf(); + expect(data.fountain).toBeDefined(); + expect(data.fountain).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fountain).toEqualTypeOf(); + expect(data.frankenstein).toBeDefined(); + expect(data.frankenstein).toBeGreaterThanOrEqual(0); + expectTypeOf(data.frankenstein).toEqualTypeOf(); + expect(data.freezer).toBeDefined(); + expect(data.freezer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.freezer).toEqualTypeOf(); + expect(data.fridge).toBeDefined(); + expect(data.fridge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fridge).toEqualTypeOf(); + expect(data.frostyTheSnowman).toBeDefined(); + expect(data.frostyTheSnowman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.frostyTheSnowman).toEqualTypeOf(); + expect(data.frozen).toBeDefined(); + expect(data.frozen).toBeGreaterThanOrEqual(0); + expectTypeOf(data.frozen).toEqualTypeOf(); + expect(data.fullMoon).toBeDefined(); + expect(data.fullMoon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fullMoon).toEqualTypeOf(); + expect(data.futuristicHouse).toBeDefined(); + expect(data.futuristicHouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.futuristicHouse).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expect(data.game).toBeGreaterThanOrEqual(0); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.garage).toBeDefined(); + expect(data.garage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.garage).toEqualTypeOf(); + expect(data.garden).toBeDefined(); + expect(data.garden).toBeGreaterThanOrEqual(0); + expectTypeOf(data.garden).toEqualTypeOf(); + expect(data.ghast).toBeDefined(); + expect(data.ghast).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ghast).toEqualTypeOf(); + expect(data.ghost).toBeDefined(); + expect(data.ghost).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ghost).toEqualTypeOf(); + expect(data.ghostShip).toBeDefined(); + expect(data.ghostShip).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ghostShip).toEqualTypeOf(); + expect(data.ghoul).toBeDefined(); + expect(data.ghoul).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ghoul).toEqualTypeOf(); + expect(data.giantPresents).toBeDefined(); + expect(data.giantPresents).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giantPresents).toEqualTypeOf(); + expect(data.gifts).toBeDefined(); + expect(data.gifts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gifts).toEqualTypeOf(); + expect(data.gingerbread).toBeDefined(); + expect(data.gingerbread).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gingerbread).toEqualTypeOf(); + expect(data.gingerbreadHouse).toBeDefined(); + expect(data.gingerbreadHouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gingerbreadHouse).toEqualTypeOf(); + expect(data.gingerbreadMan).toBeDefined(); + expect(data.gingerbreadMan).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gingerbreadMan).toEqualTypeOf(); + expect(data.giraffe).toBeDefined(); + expect(data.giraffe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giraffe).toEqualTypeOf(); + expect(data.girl).toBeDefined(); + expect(data.girl).toBeGreaterThanOrEqual(0); + expectTypeOf(data.girl).toEqualTypeOf(); + expect(data.glasses).toBeDefined(); + expect(data.glasses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.glasses).toEqualTypeOf(); + expect(data.glove).toBeDefined(); + expect(data.glove).toBeGreaterThanOrEqual(0); + expectTypeOf(data.glove).toEqualTypeOf(); + expect(data.goat).toBeDefined(); + expect(data.goat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goat).toEqualTypeOf(); + expect(data.goblin).toBeDefined(); + expect(data.goblin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goblin).toEqualTypeOf(); + expect(data.golem).toBeDefined(); + expect(data.golem).toBeGreaterThanOrEqual(0); + expectTypeOf(data.golem).toEqualTypeOf(); + expect(data.goose).toBeDefined(); + expect(data.goose).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goose).toEqualTypeOf(); + expect(data.gothic).toBeDefined(); + expect(data.gothic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gothic).toEqualTypeOf(); + expect(data.gravestone).toBeDefined(); + expect(data.gravestone).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gravestone).toEqualTypeOf(); + expect(data.graveyard).toBeDefined(); + expect(data.graveyard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.graveyard).toEqualTypeOf(); + expect(data.greekTemple).toBeDefined(); + expect(data.greekTemple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.greekTemple).toEqualTypeOf(); + expect(data.grimReaper).toBeDefined(); + expect(data.grimReaper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grimReaper).toEqualTypeOf(); + expect(data.grinch).toBeDefined(); + expect(data.grinch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grinch).toEqualTypeOf(); + expect(data.guitar).toBeDefined(); + expect(data.guitar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.guitar).toEqualTypeOf(); + expect(data.gym).toBeDefined(); + expect(data.gym).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gym).toEqualTypeOf(); + expect(data.halloweenCostumes).toBeDefined(); + expect(data.halloweenCostumes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloweenCostumes).toEqualTypeOf(); + expect(data.halloweenParty).toBeDefined(); + expect(data.halloweenParty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloweenParty).toEqualTypeOf(); + expect(data.halloweenTreats).toBeDefined(); + expect(data.halloweenTreats).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloweenTreats).toEqualTypeOf(); + expect(data.hamburger).toBeDefined(); + expect(data.hamburger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hamburger).toEqualTypeOf(); + expect(data.hammer).toBeDefined(); + expect(data.hammer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hammer).toEqualTypeOf(); + expect(data.hamster).toBeDefined(); + expect(data.hamster).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hamster).toEqualTypeOf(); + expect(data.hand).toBeDefined(); + expect(data.hand).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hand).toEqualTypeOf(); + expect(data.happy).toBeDefined(); + expect(data.happy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.happy).toEqualTypeOf(); + expect(data.harbor).toBeDefined(); + expect(data.harbor).toBeGreaterThanOrEqual(0); + expectTypeOf(data.harbor).toEqualTypeOf(); + expect(data.haunted).toBeDefined(); + expect(data.haunted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.haunted).toEqualTypeOf(); + expect(data.hauntedForest).toBeDefined(); + expect(data.hauntedForest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hauntedForest).toEqualTypeOf(); + expect(data.hauntedHouse).toBeDefined(); + expect(data.hauntedHouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hauntedHouse).toEqualTypeOf(); + expect(data.head).toBeDefined(); + expect(data.head).toBeGreaterThanOrEqual(0); + expectTypeOf(data.head).toEqualTypeOf(); + expect(data.headlessHorseman).toBeDefined(); + expect(data.headlessHorseman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headlessHorseman).toEqualTypeOf(); + expect(data.heart).toBeDefined(); + expect(data.heart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.heart).toEqualTypeOf(); + expect(data.helicopter).toBeDefined(); + expect(data.helicopter).toBeGreaterThanOrEqual(0); + expectTypeOf(data.helicopter).toEqualTypeOf(); + expect(data.hikingTrail).toBeDefined(); + expect(data.hikingTrail).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hikingTrail).toEqualTypeOf(); + expect(data.holiday).toBeDefined(); + expect(data.holiday).toBeGreaterThanOrEqual(0); + expectTypeOf(data.holiday).toEqualTypeOf(); + expect(data.holly).toBeDefined(); + expect(data.holly).toBeGreaterThanOrEqual(0); + expectTypeOf(data.holly).toEqualTypeOf(); + expect(data.hotAirBalloon).toBeDefined(); + expect(data.hotAirBalloon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hotAirBalloon).toEqualTypeOf(); + expect(data.hotChocolate).toBeDefined(); + expect(data.hotChocolate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hotChocolate).toEqualTypeOf(); + expect(data.house).toBeDefined(); + expect(data.house).toBeGreaterThanOrEqual(0); + expectTypeOf(data.house).toEqualTypeOf(); + expect(data.howl).toBeDefined(); + expect(data.howl).toBeGreaterThanOrEqual(0); + expectTypeOf(data.howl).toEqualTypeOf(); + expect(data.hugeStocking).toBeDefined(); + expect(data.hugeStocking).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hugeStocking).toEqualTypeOf(); + expect(data.hurricane).toBeDefined(); + expect(data.hurricane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hurricane).toEqualTypeOf(); + expect(data.hypixel).toBeDefined(); + expect(data.hypixel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hypixel).toEqualTypeOf(); + expect(data.hypixelSweater).toBeDefined(); + expect(data.hypixelSweater).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hypixelSweater).toEqualTypeOf(); + expect(data.iceCream).toBeDefined(); + expect(data.iceCream).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iceCream).toEqualTypeOf(); + expect(data.iceFishing).toBeDefined(); + expect(data.iceFishing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iceFishing).toEqualTypeOf(); + expect(data.iceSkating).toBeDefined(); + expect(data.iceSkating).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iceSkating).toEqualTypeOf(); + expect(data.igloo).toBeDefined(); + expect(data.igloo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.igloo).toEqualTypeOf(); + expect(data.illusion).toBeDefined(); + expect(data.illusion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.illusion).toEqualTypeOf(); + expect(data.imp).toBeDefined(); + expect(data.imp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.imp).toEqualTypeOf(); + expect(data.industrial).toBeDefined(); + expect(data.industrial).toBeGreaterThanOrEqual(0); + expectTypeOf(data.industrial).toEqualTypeOf(); + expect(data.insect).toBeDefined(); + expect(data.insect).toBeGreaterThanOrEqual(0); + expectTypeOf(data.insect).toEqualTypeOf(); + expect(data.ironman).toBeDefined(); + expect(data.ironman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ironman).toEqualTypeOf(); + expect(data.island).toBeDefined(); + expect(data.island).toBeGreaterThanOrEqual(0); + expectTypeOf(data.island).toEqualTypeOf(); + expect(data.jackolantern).toBeDefined(); + expect(data.jackolantern).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jackolantern).toEqualTypeOf(); + expect(data.jellyfish).toBeDefined(); + expect(data.jellyfish).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jellyfish).toEqualTypeOf(); + expect(data.jetski).toBeDefined(); + expect(data.jetski).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jetski).toEqualTypeOf(); + expect(data.jewel).toBeDefined(); + expect(data.jewel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jewel).toEqualTypeOf(); + expect(data.jingleBell).toBeDefined(); + expect(data.jingleBell).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jingleBell).toEqualTypeOf(); + expect(data.jurassic).toBeDefined(); + expect(data.jurassic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.jurassic).toEqualTypeOf(); + expect(data.keyboard).toBeDefined(); + expect(data.keyboard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.keyboard).toEqualTypeOf(); + expect(data.killerWhale).toBeDefined(); + expect(data.killerWhale).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killerWhale).toEqualTypeOf(); + expect(data.king).toBeDefined(); + expect(data.king).toBeGreaterThanOrEqual(0); + expectTypeOf(data.king).toEqualTypeOf(); + expect(data.kite).toBeDefined(); + expect(data.kite).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kite).toEqualTypeOf(); + expect(data.kitten).toBeDefined(); + expect(data.kitten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kitten).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.laboratory).toBeDefined(); + expect(data.laboratory).toBeGreaterThanOrEqual(0); + expectTypeOf(data.laboratory).toEqualTypeOf(); + expect(data.ladyBug).toBeDefined(); + expect(data.ladyBug).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ladyBug).toEqualTypeOf(); + expect(data.lantern).toBeDefined(); + expect(data.lantern).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lantern).toEqualTypeOf(); + expect(data.leaf).toBeDefined(); + expect(data.leaf).toBeGreaterThanOrEqual(0); + expectTypeOf(data.leaf).toEqualTypeOf(); + expect(data.leg).toBeDefined(); + expect(data.leg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.leg).toEqualTypeOf(); + expect(data.library).toBeDefined(); + expect(data.library).toBeGreaterThanOrEqual(0); + expectTypeOf(data.library).toEqualTypeOf(); + expect(data.light).toBeDefined(); + expect(data.light).toBeGreaterThanOrEqual(0); + expectTypeOf(data.light).toEqualTypeOf(); + expect(data.lightbulb).toBeDefined(); + expect(data.lightbulb).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lightbulb).toEqualTypeOf(); + expect(data.lighthouse).toBeDefined(); + expect(data.lighthouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lighthouse).toEqualTypeOf(); + expect(data.lion).toBeDefined(); + expect(data.lion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lion).toEqualTypeOf(); + expect(data.livingDead).toBeDefined(); + expect(data.livingDead).toBeGreaterThanOrEqual(0); + expectTypeOf(data.livingDead).toEqualTypeOf(); + expect(data.llama).toBeDefined(); + expect(data.llama).toBeGreaterThanOrEqual(0); + expectTypeOf(data.llama).toEqualTypeOf(); + expect(data.lodge).toBeDefined(); + expect(data.lodge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lodge).toEqualTypeOf(); + expect(data.lunchbox).toBeDefined(); + expect(data.lunchbox).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lunchbox).toEqualTypeOf(); + expect(data.madScientist).toBeDefined(); + expect(data.madScientist).toBeGreaterThanOrEqual(0); + expectTypeOf(data.madScientist).toEqualTypeOf(); + expect(data.magic).toBeDefined(); + expect(data.magic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magic).toEqualTypeOf(); + expect(data.magicWand).toBeDefined(); + expect(data.magicWand).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magicWand).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magician).toEqualTypeOf(); + expect(data.magnet).toBeDefined(); + expect(data.magnet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magnet).toEqualTypeOf(); + expect(data.mailBox).toBeDefined(); + expect(data.mailBox).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mailBox).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expect(data.map).toBeGreaterThanOrEqual(0); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.mars).toBeDefined(); + expect(data.mars).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mars).toEqualTypeOf(); + expect(data.marshmallow).toBeDefined(); + expect(data.marshmallow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.marshmallow).toEqualTypeOf(); + expect(data.marshmallows).toBeDefined(); + expect(data.marshmallows).toBeGreaterThanOrEqual(0); + expectTypeOf(data.marshmallows).toEqualTypeOf(); + expect(data.martians).toBeDefined(); + expect(data.martians).toBeGreaterThanOrEqual(0); + expectTypeOf(data.martians).toEqualTypeOf(); + expect(data.mask).toBeDefined(); + expect(data.mask).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mask).toEqualTypeOf(); + expect(data.maze).toBeDefined(); + expect(data.maze).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maze).toEqualTypeOf(); + expect(data.meadow).toBeDefined(); + expect(data.meadow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meadow).toEqualTypeOf(); + expect(data.medieval).toBeDefined(); + expect(data.medieval).toBeGreaterThanOrEqual(0); + expectTypeOf(data.medieval).toEqualTypeOf(); + expect(data.mermaid).toBeDefined(); + expect(data.mermaid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mermaid).toEqualTypeOf(); + expect(data.meteorite).toBeDefined(); + expect(data.meteorite).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meteorite).toEqualTypeOf(); + expect(data.mice).toBeDefined(); + expect(data.mice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mice).toEqualTypeOf(); + expect(data.midnight).toBeDefined(); + expect(data.midnight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.midnight).toEqualTypeOf(); + expect(data.milk).toBeDefined(); + expect(data.milk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.milk).toEqualTypeOf(); + expect(data.milkAndCookies).toBeDefined(); + expect(data.milkAndCookies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.milkAndCookies).toEqualTypeOf(); + expect(data.mincePie).toBeDefined(); + expect(data.mincePie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mincePie).toEqualTypeOf(); + expect(data.mine).toBeDefined(); + expect(data.mine).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mine).toEqualTypeOf(); + expect(data.mistletoe).toBeDefined(); + expect(data.mistletoe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mistletoe).toEqualTypeOf(); + expect(data.modernHome).toBeDefined(); + expect(data.modernHome).toBeGreaterThanOrEqual(0); + expectTypeOf(data.modernHome).toEqualTypeOf(); + expect(data.money).toBeDefined(); + expect(data.money).toBeGreaterThanOrEqual(0); + expectTypeOf(data.money).toEqualTypeOf(); + expect(data.monkey).toBeDefined(); + expect(data.monkey).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monkey).toEqualTypeOf(); + expect(data.monster).toBeDefined(); + expect(data.monster).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monster).toEqualTypeOf(); + expect(data.monsterTruck).toBeDefined(); + expect(data.monsterTruck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monsterTruck).toEqualTypeOf(); + expect(data.monument).toBeDefined(); + expect(data.monument).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monument).toEqualTypeOf(); + expect(data.moon).toBeDefined(); + expect(data.moon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.moon).toEqualTypeOf(); + expect(data.motorbike).toBeDefined(); + expect(data.motorbike).toBeGreaterThanOrEqual(0); + expectTypeOf(data.motorbike).toEqualTypeOf(); + expect(data.mouse).toBeDefined(); + expect(data.mouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mouse).toEqualTypeOf(); + expect(data.movie).toBeDefined(); + expect(data.movie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.movie).toEqualTypeOf(); + expect(data.mummy).toBeDefined(); + expect(data.mummy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mummy).toEqualTypeOf(); + expect(data.museum).toBeDefined(); + expect(data.museum).toBeGreaterThanOrEqual(0); + expectTypeOf(data.museum).toEqualTypeOf(); + expect(data.mushroom).toBeDefined(); + expect(data.mushroom).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mushroom).toEqualTypeOf(); + expect(data.music).toBeDefined(); + expect(data.music).toBeGreaterThanOrEqual(0); + expectTypeOf(data.music).toEqualTypeOf(); + expect(data.mutant).toBeDefined(); + expect(data.mutant).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mutant).toEqualTypeOf(); + expect(data.mythical).toBeDefined(); + expect(data.mythical).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mythical).toEqualTypeOf(); + expect(data.nail).toBeDefined(); + expect(data.nail).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nail).toEqualTypeOf(); + expect(data.neon).toBeDefined(); + expect(data.neon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.neon).toEqualTypeOf(); + expect(data.nightmare).toBeDefined(); + expect(data.nightmare).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nightmare).toEqualTypeOf(); + expect(data.ninja).toBeDefined(); + expect(data.ninja).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ninja).toEqualTypeOf(); + expect(data.northPole).toBeDefined(); + expect(data.northPole).toBeGreaterThanOrEqual(0); + expectTypeOf(data.northPole).toEqualTypeOf(); + expect(data.nose).toBeDefined(); + expect(data.nose).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nose).toEqualTypeOf(); + expect(data.nostalgia).toBeDefined(); + expect(data.nostalgia).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nostalgia).toEqualTypeOf(); + expect(data.ocean).toBeDefined(); + expect(data.ocean).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ocean).toEqualTypeOf(); + expect(data.octopus).toBeDefined(); + expect(data.octopus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.octopus).toEqualTypeOf(); + expect(data.ogre).toBeDefined(); + expect(data.ogre).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ogre).toEqualTypeOf(); + expect(data.olympics).toBeDefined(); + expect(data.olympics).toBeGreaterThanOrEqual(0); + expectTypeOf(data.olympics).toEqualTypeOf(); + expect(data.orange).toBeDefined(); + expect(data.orange).toBeGreaterThanOrEqual(0); + expectTypeOf(data.orange).toEqualTypeOf(); + expect(data.oven).toBeDefined(); + expect(data.oven).toBeGreaterThanOrEqual(0); + expectTypeOf(data.oven).toEqualTypeOf(); + expect(data.owl).toBeDefined(); + expect(data.owl).toBeGreaterThanOrEqual(0); + expectTypeOf(data.owl).toEqualTypeOf(); + expect(data.package).toBeDefined(); + expect(data.package).toBeGreaterThanOrEqual(0); + expectTypeOf(data.package).toEqualTypeOf(); + expect(data.paint).toBeDefined(); + expect(data.paint).toBeGreaterThanOrEqual(0); + expectTypeOf(data.paint).toEqualTypeOf(); + expect(data.painting).toBeDefined(); + expect(data.painting).toBeGreaterThanOrEqual(0); + expectTypeOf(data.painting).toEqualTypeOf(); + expect(data.palace).toBeDefined(); + expect(data.palace).toBeGreaterThanOrEqual(0); + expectTypeOf(data.palace).toEqualTypeOf(); + expect(data.palmTree).toBeDefined(); + expect(data.palmTree).toBeGreaterThanOrEqual(0); + expectTypeOf(data.palmTree).toEqualTypeOf(); + expect(data.panda).toBeDefined(); + expect(data.panda).toBeGreaterThanOrEqual(0); + expectTypeOf(data.panda).toEqualTypeOf(); + expect(data.parachute).toBeDefined(); + expect(data.parachute).toBeGreaterThanOrEqual(0); + expectTypeOf(data.parachute).toEqualTypeOf(); + expect(data.park).toBeDefined(); + expect(data.park).toBeGreaterThanOrEqual(0); + expectTypeOf(data.park).toEqualTypeOf(); + expect(data.pastel).toBeDefined(); + expect(data.pastel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pastel).toEqualTypeOf(); + expect(data.pen).toBeDefined(); + expect(data.pen).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pen).toEqualTypeOf(); + expect(data.pencil).toBeDefined(); + expect(data.pencil).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pencil).toEqualTypeOf(); + expect(data.penguin).toBeDefined(); + expect(data.penguin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.penguin).toEqualTypeOf(); + expect(data.phantom).toBeDefined(); + expect(data.phantom).toBeGreaterThanOrEqual(0); + expectTypeOf(data.phantom).toEqualTypeOf(); + expect(data.photograph).toBeDefined(); + expect(data.photograph).toBeGreaterThanOrEqual(0); + expectTypeOf(data.photograph).toEqualTypeOf(); + expect(data.piano).toBeDefined(); + expect(data.piano).toBeGreaterThanOrEqual(0); + expectTypeOf(data.piano).toEqualTypeOf(); + expect(data.picnic).toBeDefined(); + expect(data.picnic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.picnic).toEqualTypeOf(); + expect(data.picture).toBeDefined(); + expect(data.picture).toBeGreaterThanOrEqual(0); + expectTypeOf(data.picture).toEqualTypeOf(); + expect(data.pie).toBeDefined(); + expect(data.pie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pie).toEqualTypeOf(); + expect(data.piggyBank).toBeDefined(); + expect(data.piggyBank).toBeGreaterThanOrEqual(0); + expectTypeOf(data.piggyBank).toEqualTypeOf(); + expect(data.pineapple).toBeDefined(); + expect(data.pineapple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pineapple).toEqualTypeOf(); + expect(data.pipe).toBeDefined(); + expect(data.pipe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pipe).toEqualTypeOf(); + expect(data.pirate).toBeDefined(); + expect(data.pirate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pirate).toEqualTypeOf(); + expect(data.pirates).toBeDefined(); + expect(data.pirates).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pirates).toEqualTypeOf(); + expect(data.pitchfork).toBeDefined(); + expect(data.pitchfork).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pitchfork).toEqualTypeOf(); + expect(data.pixelArt).toBeDefined(); + expect(data.pixelArt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pixelArt).toEqualTypeOf(); + expect(data.plane).toBeDefined(); + expect(data.plane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.plane).toEqualTypeOf(); + expect(data.plantPot).toBeDefined(); + expect(data.plantPot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.plantPot).toEqualTypeOf(); + expect(data.plate).toBeDefined(); + expect(data.plate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.plate).toEqualTypeOf(); + expect(data.pogoStick).toBeDefined(); + expect(data.pogoStick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pogoStick).toEqualTypeOf(); + expect(data.pogoSticks).toBeDefined(); + expect(data.pogoSticks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pogoSticks).toEqualTypeOf(); + expect(data.pond).toBeDefined(); + expect(data.pond).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pond).toEqualTypeOf(); + expect(data.pool).toBeDefined(); + expect(data.pool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pool).toEqualTypeOf(); + expect(data.poolParty).toBeDefined(); + expect(data.poolParty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.poolParty).toEqualTypeOf(); + expect(data.poolTable).toBeDefined(); + expect(data.poolTable).toBeGreaterThanOrEqual(0); + expectTypeOf(data.poolTable).toEqualTypeOf(); + expect(data.popcorn).toBeDefined(); + expect(data.popcorn).toBeGreaterThanOrEqual(0); + expectTypeOf(data.popcorn).toEqualTypeOf(); + expect(data.popsicle).toBeDefined(); + expect(data.popsicle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.popsicle).toEqualTypeOf(); + expect(data.postOffice).toBeDefined(); + expect(data.postOffice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.postOffice).toEqualTypeOf(); + expect(data.pot).toBeDefined(); + expect(data.pot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pot).toEqualTypeOf(); + expect(data.potato).toBeDefined(); + expect(data.potato).toBeGreaterThanOrEqual(0); + expectTypeOf(data.potato).toEqualTypeOf(); + expect(data.potion).toBeDefined(); + expect(data.potion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.potion).toEqualTypeOf(); + expect(data.pottedPlant).toBeDefined(); + expect(data.pottedPlant).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pottedPlant).toEqualTypeOf(); + expect(data.prehistoric).toBeDefined(); + expect(data.prehistoric).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prehistoric).toEqualTypeOf(); + expect(data.presentsPile).toBeDefined(); + expect(data.presentsPile).toBeGreaterThanOrEqual(0); + expectTypeOf(data.presentsPile).toEqualTypeOf(); + expect(data.princess).toBeDefined(); + expect(data.princess).toBeGreaterThanOrEqual(0); + expectTypeOf(data.princess).toEqualTypeOf(); + expect(data.pumpkinCarving).toBeDefined(); + expect(data.pumpkinCarving).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pumpkinCarving).toEqualTypeOf(); + expect(data.pyramid).toBeDefined(); + expect(data.pyramid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pyramid).toEqualTypeOf(); + expect(data.racecar).toBeDefined(); + expect(data.racecar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.racecar).toEqualTypeOf(); + expect(data.rainbow).toBeDefined(); + expect(data.rainbow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rainbow).toEqualTypeOf(); + expect(data.rainforest).toBeDefined(); + expect(data.rainforest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rainforest).toEqualTypeOf(); + expect(data.rat).toBeDefined(); + expect(data.rat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rat).toEqualTypeOf(); + expect(data.reindeer).toBeDefined(); + expect(data.reindeer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.reindeer).toEqualTypeOf(); + expect(data.rhino).toBeDefined(); + expect(data.rhino).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rhino).toEqualTypeOf(); + expect(data.ring).toBeDefined(); + expect(data.ring).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ring).toEqualTypeOf(); + expect(data.robot).toBeDefined(); + expect(data.robot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.robot).toEqualTypeOf(); + expect(data.robots).toBeDefined(); + expect(data.robots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.robots).toEqualTypeOf(); + expect(data.rockingChair).toBeDefined(); + expect(data.rockingChair).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rockingChair).toEqualTypeOf(); + expect(data.rollercoaster).toBeDefined(); + expect(data.rollercoaster).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rollercoaster).toEqualTypeOf(); + expect(data.roman).toBeDefined(); + expect(data.roman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.roman).toEqualTypeOf(); + expect(data.rubberDuck).toBeDefined(); + expect(data.rubberDuck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rubberDuck).toEqualTypeOf(); + expect(data.rudolph).toBeDefined(); + expect(data.rudolph).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rudolph).toEqualTypeOf(); + expect(data.rustic).toBeDefined(); + expect(data.rustic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rustic).toEqualTypeOf(); + expect(data.sackOfPresents).toBeDefined(); + expect(data.sackOfPresents).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sackOfPresents).toEqualTypeOf(); + expect(data.sad).toBeDefined(); + expect(data.sad).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sad).toEqualTypeOf(); + expect(data.safari).toBeDefined(); + expect(data.safari).toBeGreaterThanOrEqual(0); + expectTypeOf(data.safari).toEqualTypeOf(); + expect(data.sailboat).toBeDefined(); + expect(data.sailboat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sailboat).toEqualTypeOf(); + expect(data.sandcastle).toBeDefined(); + expect(data.sandcastle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sandcastle).toEqualTypeOf(); + expect(data.sandwich).toBeDefined(); + expect(data.sandwich).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sandwich).toEqualTypeOf(); + expect(data.santa).toBeDefined(); + expect(data.santa).toBeGreaterThanOrEqual(0); + expectTypeOf(data.santa).toEqualTypeOf(); + expect(data.santaClaus).toBeDefined(); + expect(data.santaClaus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.santaClaus).toEqualTypeOf(); + expect(data.santasSleigh).toBeDefined(); + expect(data.santasSleigh).toBeGreaterThanOrEqual(0); + expectTypeOf(data.santasSleigh).toEqualTypeOf(); + expect(data.santasWorkshop).toBeDefined(); + expect(data.santasWorkshop).toBeGreaterThanOrEqual(0); + expectTypeOf(data.santasWorkshop).toEqualTypeOf(); + expect(data.scarecrow).toBeDefined(); + expect(data.scarecrow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scarecrow).toEqualTypeOf(); + expect(data.scaryMovie).toBeDefined(); + expect(data.scaryMovie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scaryMovie).toEqualTypeOf(); + expect(data.school).toBeDefined(); + expect(data.school).toBeGreaterThanOrEqual(0); + expectTypeOf(data.school).toEqualTypeOf(); + expect(data.schoolBus).toBeDefined(); + expect(data.schoolBus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.schoolBus).toEqualTypeOf(); + expect(data.scifi).toBeDefined(); + expect(data.scifi).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scifi).toEqualTypeOf(); + expect(data.scientist).toBeDefined(); + expect(data.scientist).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scientist).toEqualTypeOf(); + expect(data.scissors).toBeDefined(); + expect(data.scissors).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scissors).toEqualTypeOf(); + expect(data.screw).toBeDefined(); + expect(data.screw).toBeGreaterThanOrEqual(0); + expectTypeOf(data.screw).toEqualTypeOf(); + expect(data.scythe).toBeDefined(); + expect(data.scythe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scythe).toEqualTypeOf(); + expect(data.selfPortrait).toBeDefined(); + expect(data.selfPortrait).toBeGreaterThanOrEqual(0); + expectTypeOf(data.selfPortrait).toEqualTypeOf(); + expect(data.sewer).toBeDefined(); + expect(data.sewer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sewer).toEqualTypeOf(); + expect(data.shark).toBeDefined(); + expect(data.shark).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shark).toEqualTypeOf(); + expect(data.sheep).toBeDefined(); + expect(data.sheep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sheep).toEqualTypeOf(); + expect(data.shell).toBeDefined(); + expect(data.shell).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shell).toEqualTypeOf(); + expect(data.shepherd).toBeDefined(); + expect(data.shepherd).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shepherd).toEqualTypeOf(); + expect(data.shipwreck).toBeDefined(); + expect(data.shipwreck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shipwreck).toEqualTypeOf(); + expect(data.shoe).toBeDefined(); + expect(data.shoe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shoe).toEqualTypeOf(); + expect(data.shopping).toBeDefined(); + expect(data.shopping).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shopping).toEqualTypeOf(); + expect(data.shovel).toBeDefined(); + expect(data.shovel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shovel).toEqualTypeOf(); + expect(data.skateboard).toBeDefined(); + expect(data.skateboard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skateboard).toEqualTypeOf(); + expect(data.skatepark).toBeDefined(); + expect(data.skatepark).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skatepark).toEqualTypeOf(); + expect(data.skatingRink).toBeDefined(); + expect(data.skatingRink).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skatingRink).toEqualTypeOf(); + expect(data.skeleton).toBeDefined(); + expect(data.skeleton).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skeleton).toEqualTypeOf(); + expect(data.skeletonJockey).toBeDefined(); + expect(data.skeletonJockey).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skeletonJockey).toEqualTypeOf(); + expect(data.skiCabin).toBeDefined(); + expect(data.skiCabin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skiCabin).toEqualTypeOf(); + expect(data.skull).toBeDefined(); + expect(data.skull).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skull).toEqualTypeOf(); + expect(data.skydiver).toBeDefined(); + expect(data.skydiver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skydiver).toEqualTypeOf(); + expect(data.sled).toBeDefined(); + expect(data.sled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sled).toEqualTypeOf(); + expect(data.slenderman).toBeDefined(); + expect(data.slenderman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slenderman).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.snail).toBeDefined(); + expect(data.snail).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snail).toEqualTypeOf(); + expect(data.snake).toBeDefined(); + expect(data.snake).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snake).toEqualTypeOf(); + expect(data.snowAngel).toBeDefined(); + expect(data.snowAngel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowAngel).toEqualTypeOf(); + expect(data.snowFort).toBeDefined(); + expect(data.snowFort).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowFort).toEqualTypeOf(); + expect(data.snowGlobe).toBeDefined(); + expect(data.snowGlobe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowGlobe).toEqualTypeOf(); + expect(data.snowballFight).toBeDefined(); + expect(data.snowballFight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowballFight).toEqualTypeOf(); + expect(data.snowflake).toBeDefined(); + expect(data.snowflake).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowflake).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.snowyForest).toBeDefined(); + expect(data.snowyForest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.snowyForest).toEqualTypeOf(); + expect(data.solarPanels).toBeDefined(); + expect(data.solarPanels).toBeGreaterThanOrEqual(0); + expectTypeOf(data.solarPanels).toEqualTypeOf(); + expect(data.solarSystem).toBeDefined(); + expect(data.solarSystem).toBeGreaterThanOrEqual(0); + expectTypeOf(data.solarSystem).toEqualTypeOf(); + expect(data.soldier).toBeDefined(); + expect(data.soldier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soldier).toEqualTypeOf(); + expect(data.sorcerer).toBeDefined(); + expect(data.sorcerer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sorcerer).toEqualTypeOf(); + expect(data.soup).toBeDefined(); + expect(data.soup).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soup).toEqualTypeOf(); + expect(data.space).toBeDefined(); + expect(data.space).toBeGreaterThanOrEqual(0); + expectTypeOf(data.space).toEqualTypeOf(); + expect(data.spaceship).toBeDefined(); + expect(data.spaceship).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spaceship).toEqualTypeOf(); + expect(data.spellbook).toBeDefined(); + expect(data.spellbook).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spellbook).toEqualTypeOf(); + expect(data.spider).toBeDefined(); + expect(data.spider).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spider).toEqualTypeOf(); + expect(data.spiderWeb).toBeDefined(); + expect(data.spiderWeb).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spiderWeb).toEqualTypeOf(); + expect(data.spirit).toBeDefined(); + expect(data.spirit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spirit).toEqualTypeOf(); + expect(data.spirits).toBeDefined(); + expect(data.spirits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spirits).toEqualTypeOf(); + expect(data.sponge).toBeDefined(); + expect(data.sponge).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sponge).toEqualTypeOf(); + expect(data.spookyTree).toBeDefined(); + expect(data.spookyTree).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spookyTree).toEqualTypeOf(); + expect(data.spring).toBeDefined(); + expect(data.spring).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spring).toEqualTypeOf(); + expect(data.spy).toBeDefined(); + expect(data.spy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spy).toEqualTypeOf(); + expect(data.stadium).toBeDefined(); + expect(data.stadium).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stadium).toEqualTypeOf(); + expect(data.stamp).toBeDefined(); + expect(data.stamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stamp).toEqualTypeOf(); + expect(data.star).toBeDefined(); + expect(data.star).toBeGreaterThanOrEqual(0); + expectTypeOf(data.star).toEqualTypeOf(); + expect(data.starryNight).toBeDefined(); + expect(data.starryNight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.starryNight).toEqualTypeOf(); + expect(data.steamLocomotive).toBeDefined(); + expect(data.steamLocomotive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.steamLocomotive).toEqualTypeOf(); + expect(data.steamPunk).toBeDefined(); + expect(data.steamPunk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.steamPunk).toEqualTypeOf(); + expect(data.steampunk).toBeDefined(); + expect(data.steampunk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.steampunk).toEqualTypeOf(); + expect(data.stick).toBeDefined(); + expect(data.stick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stick).toEqualTypeOf(); + expect(data.stocking).toBeDefined(); + expect(data.stocking).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stocking).toEqualTypeOf(); + expect(data.sun).toBeDefined(); + expect(data.sun).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sun).toEqualTypeOf(); + expect(data.sunset).toBeDefined(); + expect(data.sunset).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sunset).toEqualTypeOf(); + expect(data.superHero).toBeDefined(); + expect(data.superHero).toBeGreaterThanOrEqual(0); + expectTypeOf(data.superHero).toEqualTypeOf(); + expect(data.superhero).toBeDefined(); + expect(data.superhero).toBeGreaterThanOrEqual(0); + expectTypeOf(data.superhero).toEqualTypeOf(); + expect(data.supernatural).toBeDefined(); + expect(data.supernatural).toBeGreaterThanOrEqual(0); + expectTypeOf(data.supernatural).toEqualTypeOf(); + expect(data.surfboard).toBeDefined(); + expect(data.surfboard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.surfboard).toEqualTypeOf(); + expect(data.surprise).toBeDefined(); + expect(data.surprise).toBeGreaterThanOrEqual(0); + expectTypeOf(data.surprise).toEqualTypeOf(); + expect(data.surreal).toBeDefined(); + expect(data.surreal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.surreal).toEqualTypeOf(); + expect(data.sushi).toBeDefined(); + expect(data.sushi).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sushi).toEqualTypeOf(); + expect(data.swamp).toBeDefined(); + expect(data.swamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swamp).toEqualTypeOf(); + expect(data.sweet).toBeDefined(); + expect(data.sweet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sweet).toEqualTypeOf(); + expect(data.sweets).toBeDefined(); + expect(data.sweets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sweets).toEqualTypeOf(); + expect(data.swing).toBeDefined(); + expect(data.swing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swing).toEqualTypeOf(); + expect(data.sword).toBeDefined(); + expect(data.sword).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sword).toEqualTypeOf(); + expect(data.talentShow).toBeDefined(); + expect(data.talentShow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.talentShow).toEqualTypeOf(); + expect(data.tank).toBeDefined(); + expect(data.tank).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tank).toEqualTypeOf(); + expect(data.tarantula).toBeDefined(); + expect(data.tarantula).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tarantula).toEqualTypeOf(); + expect(data.teddyBear).toBeDefined(); + expect(data.teddyBear).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teddyBear).toEqualTypeOf(); + expect(data.temple).toBeDefined(); + expect(data.temple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.temple).toEqualTypeOf(); + expect(data.tennis).toBeDefined(); + expect(data.tennis).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tennis).toEqualTypeOf(); + expect(data.tent).toBeDefined(); + expect(data.tent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tent).toEqualTypeOf(); + expect(data.test).toBeDefined(); + expect(data.test).toBeGreaterThanOrEqual(0); + expectTypeOf(data.test).toEqualTypeOf(); + expect(data.tests).toBeDefined(); + expect(data.tests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tests).toEqualTypeOf(); + expect(data.theBestToyEver).toBeDefined(); + expect(data.theBestToyEver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theBestToyEver).toEqualTypeOf(); + expect(data.theFuture).toBeDefined(); + expect(data.theFuture).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theFuture).toEqualTypeOf(); + expect(data.theGrinch).toBeDefined(); + expect(data.theGrinch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theGrinch).toEqualTypeOf(); + expect(data.theater).toBeDefined(); + expect(data.theater).toBeGreaterThanOrEqual(0); + expectTypeOf(data.theater).toEqualTypeOf(); + expect(data.themePark).toBeDefined(); + expect(data.themePark).toBeGreaterThanOrEqual(0); + expectTypeOf(data.themePark).toEqualTypeOf(); + expect(data.throne).toBeDefined(); + expect(data.throne).toBeGreaterThanOrEqual(0); + expectTypeOf(data.throne).toEqualTypeOf(); + expect(data.thunderAndLightning).toBeDefined(); + expect(data.thunderAndLightning).toBeGreaterThanOrEqual(0); + expectTypeOf(data.thunderAndLightning).toEqualTypeOf(); + expect(data.ticket).toBeDefined(); + expect(data.ticket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ticket).toEqualTypeOf(); + expect(data.tiger).toBeDefined(); + expect(data.tiger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tiger).toEqualTypeOf(); + expect(data.tomb).toBeDefined(); + expect(data.tomb).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tomb).toEqualTypeOf(); + expect(data.tombstone).toBeDefined(); + expect(data.tombstone).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tombstone).toEqualTypeOf(); + expect(data.tooth).toBeDefined(); + expect(data.tooth).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tooth).toEqualTypeOf(); + expect(data.toothpaste).toBeDefined(); + expect(data.toothpaste).toBeGreaterThanOrEqual(0); + expectTypeOf(data.toothpaste).toEqualTypeOf(); + expect(data.topHat).toBeDefined(); + expect(data.topHat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.topHat).toEqualTypeOf(); + expect(data.torch).toBeDefined(); + expect(data.torch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.torch).toEqualTypeOf(); + expect(data.tornado).toBeDefined(); + expect(data.tornado).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tornado).toEqualTypeOf(); + expect(data.tower).toBeDefined(); + expect(data.tower).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tower).toEqualTypeOf(); + expect(data.towerOfPisa).toBeDefined(); + expect(data.towerOfPisa).toBeGreaterThanOrEqual(0); + expectTypeOf(data.towerOfPisa).toEqualTypeOf(); + expect(data.toyBox).toBeDefined(); + expect(data.toyBox).toBeGreaterThanOrEqual(0); + expectTypeOf(data.toyBox).toEqualTypeOf(); + expect(data.toyFactory).toBeDefined(); + expect(data.toyFactory).toBeGreaterThanOrEqual(0); + expectTypeOf(data.toyFactory).toEqualTypeOf(); + expect(data.toys).toBeDefined(); + expect(data.toys).toBeGreaterThanOrEqual(0); + expectTypeOf(data.toys).toEqualTypeOf(); + expect(data.tractor).toBeDefined(); + expect(data.tractor).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tractor).toEqualTypeOf(); + expect(data.train).toBeDefined(); + expect(data.train).toBeGreaterThanOrEqual(0); + expectTypeOf(data.train).toEqualTypeOf(); + expect(data.trainStation).toBeDefined(); + expect(data.trainStation).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trainStation).toEqualTypeOf(); + expect(data.trainstation).toBeDefined(); + expect(data.trainstation).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trainstation).toEqualTypeOf(); + expect(data.trampoline).toBeDefined(); + expect(data.trampoline).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trampoline).toEqualTypeOf(); + expect(data.treasure).toBeDefined(); + expect(data.treasure).toBeGreaterThanOrEqual(0); + expectTypeOf(data.treasure).toEqualTypeOf(); + expect(data.treasureChest).toBeDefined(); + expect(data.treasureChest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.treasureChest).toEqualTypeOf(); + expect(data.treehouse).toBeDefined(); + expect(data.treehouse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.treehouse).toEqualTypeOf(); + expect(data.trickortreating).toBeDefined(); + expect(data.trickortreating).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trickortreating).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeGreaterThanOrEqual(0); + expectTypeOf(data.troll).toEqualTypeOf(); + expect(data.truck).toBeDefined(); + expect(data.truck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.truck).toEqualTypeOf(); + expect(data.turkey).toBeDefined(); + expect(data.turkey).toBeGreaterThanOrEqual(0); + expectTypeOf(data.turkey).toEqualTypeOf(); + expect(data.turtle).toBeDefined(); + expect(data.turtle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.turtle).toEqualTypeOf(); + expect(data.usa).toBeDefined(); + expect(data.usa).toBeGreaterThanOrEqual(0); + expectTypeOf(data.usa).toEqualTypeOf(); + expect(data.umbrella).toBeDefined(); + expect(data.umbrella).toBeGreaterThanOrEqual(0); + expectTypeOf(data.umbrella).toEqualTypeOf(); + expect(data.undead).toBeDefined(); + expect(data.undead).toBeGreaterThanOrEqual(0); + expectTypeOf(data.undead).toEqualTypeOf(); + expect(data.underTheSea).toBeDefined(); + expect(data.underTheSea).toBeGreaterThanOrEqual(0); + expectTypeOf(data.underTheSea).toEqualTypeOf(); + expect(data.underground).toBeDefined(); + expect(data.underground).toBeGreaterThanOrEqual(0); + expectTypeOf(data.underground).toEqualTypeOf(); + expect(data.unicorn).toBeDefined(); + expect(data.unicorn).toBeGreaterThanOrEqual(0); + expectTypeOf(data.unicorn).toEqualTypeOf(); + expect(data.vampire).toBeDefined(); + expect(data.vampire).toBeGreaterThanOrEqual(0); + expectTypeOf(data.vampire).toEqualTypeOf(); + expect(data.vegetableGarden).toBeDefined(); + expect(data.vegetableGarden).toBeGreaterThanOrEqual(0); + expectTypeOf(data.vegetableGarden).toEqualTypeOf(); + expect(data.vehicle).toBeDefined(); + expect(data.vehicle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.vehicle).toEqualTypeOf(); + expect(data.vendingMachine).toBeDefined(); + expect(data.vendingMachine).toBeGreaterThanOrEqual(0); + expectTypeOf(data.vendingMachine).toEqualTypeOf(); + expect(data.videoGame).toBeDefined(); + expect(data.videoGame).toBeGreaterThanOrEqual(0); + expectTypeOf(data.videoGame).toEqualTypeOf(); + expect(data.viking).toBeDefined(); + expect(data.viking).toBeGreaterThanOrEqual(0); + expectTypeOf(data.viking).toEqualTypeOf(); + expect(data.volcano).toBeDefined(); + expect(data.volcano).toBeGreaterThanOrEqual(0); + expectTypeOf(data.volcano).toEqualTypeOf(); + expect(data.volcanoEruption).toBeDefined(); + expect(data.volcanoEruption).toBeGreaterThanOrEqual(0); + expectTypeOf(data.volcanoEruption).toEqualTypeOf(); + expect(data.volleyballCourt).toBeDefined(); + expect(data.volleyballCourt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.volleyballCourt).toEqualTypeOf(); + expect(data.wallet).toBeDefined(); + expect(data.wallet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wallet).toEqualTypeOf(); + expect(data.warlock).toBeDefined(); + expect(data.warlock).toBeGreaterThanOrEqual(0); + expectTypeOf(data.warlock).toEqualTypeOf(); + expect(data.watch).toBeDefined(); + expect(data.watch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.watch).toEqualTypeOf(); + expect(data.waterBucket).toBeDefined(); + expect(data.waterBucket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.waterBucket).toEqualTypeOf(); + expect(data.waterfall).toBeDefined(); + expect(data.waterfall).toBeGreaterThanOrEqual(0); + expectTypeOf(data.waterfall).toEqualTypeOf(); + expect(data.web).toBeDefined(); + expect(data.web).toBeGreaterThanOrEqual(0); + expectTypeOf(data.web).toEqualTypeOf(); + expect(data.weightlifting).toBeDefined(); + expect(data.weightlifting).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weightlifting).toEqualTypeOf(); + expect(data.werewolf).toBeDefined(); + expect(data.werewolf).toBeGreaterThanOrEqual(0); + expectTypeOf(data.werewolf).toEqualTypeOf(); + expect(data.western).toBeDefined(); + expect(data.western).toBeGreaterThanOrEqual(0); + expectTypeOf(data.western).toEqualTypeOf(); + expect(data.whale).toBeDefined(); + expect(data.whale).toBeGreaterThanOrEqual(0); + expectTypeOf(data.whale).toEqualTypeOf(); + expect(data.wheel).toBeDefined(); + expect(data.wheel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wheel).toEqualTypeOf(); + expect(data.wickedWitch).toBeDefined(); + expect(data.wickedWitch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wickedWitch).toEqualTypeOf(); + expect(data.windmill).toBeDefined(); + expect(data.windmill).toBeGreaterThanOrEqual(0); + expectTypeOf(data.windmill).toEqualTypeOf(); + expect(data.winterSuit).toBeDefined(); + expect(data.winterSuit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winterSuit).toEqualTypeOf(); + expect(data.wisemen).toBeDefined(); + expect(data.wisemen).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wisemen).toEqualTypeOf(); + expect(data.wish).toBeDefined(); + expect(data.wish).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wish).toEqualTypeOf(); + expect(data.witch).toBeDefined(); + expect(data.witch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witch).toEqualTypeOf(); + expect(data.witchHut).toBeDefined(); + expect(data.witchHut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witchHut).toEqualTypeOf(); + expect(data.witchcraft).toBeDefined(); + expect(data.witchcraft).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witchcraft).toEqualTypeOf(); + expect(data.witchesHat).toBeDefined(); + expect(data.witchesHat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witchesHat).toEqualTypeOf(); + expect(data.wizard).toBeDefined(); + expect(data.wizard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wizard).toEqualTypeOf(); + expect(data.wolves).toBeDefined(); + expect(data.wolves).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wolves).toEqualTypeOf(); + expect(data.wonderland).toBeDefined(); + expect(data.wonderland).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wonderland).toEqualTypeOf(); + expect(data.world).toBeDefined(); + expect(data.world).toBeGreaterThanOrEqual(0); + expectTypeOf(data.world).toEqualTypeOf(); + expect(data.worm).toBeDefined(); + expect(data.worm).toBeGreaterThanOrEqual(0); + expectTypeOf(data.worm).toEqualTypeOf(); + expect(data.wreath).toBeDefined(); + expect(data.wreath).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wreath).toEqualTypeOf(); + expect(data.yuleLog).toBeDefined(); + expect(data.yuleLog).toBeGreaterThanOrEqual(0); + expectTypeOf(data.yuleLog).toEqualTypeOf(); + expect(data.zebra).toBeDefined(); + expect(data.zebra).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zebra).toEqualTypeOf(); + expect(data.zombie).toBeDefined(); + expect(data.zombie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombie).toEqualTypeOf(); + expect(data.zombieApocalypse).toBeDefined(); + expect(data.zombieApocalypse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieApocalypse).toEqualTypeOf(); + expect(data.zombiePigman).toBeDefined(); + expect(data.zombiePigman).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombiePigman).toEqualTypeOf(); + expect(data.zombies).toBeDefined(); + expect(data.zombies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombies).toEqualTypeOf(); + expect(data.zoo).toBeDefined(); + expect(data.zoo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zoo).toEqualTypeOf(); + expect(data.null).toBeDefined(); + expect(data.null).toBeGreaterThanOrEqual(0); + expectTypeOf(data.null).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.ts b/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.ts new file mode 100644 index 000000000..b2b7701bf --- /dev/null +++ b/src/Structures/MiniGames/BuildBattle/BuildBattleVotes.ts @@ -0,0 +1,1246 @@ +class BuildBattleVotes { + abandoned: number; + abandonedMansion: number; + adventCalendar: number; + airplane: number; + aladdin: number; + alien: number; + alienInvasion: number; + anchor: number; + ancient: number; + angel: number; + angry: number; + animal: number; + ant: number; + apocalyptic: number; + apple: number; + aquarium: number; + arcade: number; + arcadeMachine: number; + archer: number; + arm: number; + astronaut: number; + awards: number; + axe: number; + baby: number; + backpack: number; + bacon: number; + bakery: number; + baking: number; + balloon: number; + banana: number; + barbeque: number; + barn: number; + bat: number; + bath: number; + bats: number; + battle: number; + baubles: number; + beach: number; + beanstalk: number; + bear: number; + beard: number; + bed: number; + bee: number; + bell: number; + bike: number; + bikeRiding: number; + bird: number; + birdHouse: number; + birthday: number; + birthdayParty: number; + blaze: number; + blizzard: number; + block: number; + blocks: number; + boardGames: number; + boardgames: number; + boat: number; + bobsledding: number; + bones: number; + boogeyman: number; + book: number; + boot: number; + bottle: number; + bouncyCastle: number; + bowlingAlley: number; + box: number; + boxingRing: number; + boy: number; + brain: number; + branch: number; + bread: number; + breakfast: number; + brewingStand: number; + bridge: number; + brokenBridge: number; + broomstick: number; + bucket: number; + bug: number; + builder: number; + bunny: number; + buried: number; + butterflies: number; + butterfly: number; + button: number; + cabin: number; + cake: number; + camel: number; + camera: number; + camp: number; + campfire: number; + camping: number; + campsite: number; + candle: number; + candlelight: number; + candles: number; + candy: number; + candyBuckets: number; + candyCane: number; + cannon: number; + car: number; + caribbean: number; + carnival: number; + carolling: number; + cart: number; + cartoon: number; + castle: number; + cat: number; + catapult: number; + caterpillar: number; + cauldron: number; + cave: number; + celebration: number; + cellar: number; + cheese: number; + chemistry: number; + cherry: number; + cherryBlossom: number; + cherryBlossoms: number; + chess: number; + chest: number; + chicken: number; + chimney: number; + chocolate: number; + chocolateFactory: number; + choir: number; + christmasCard: number; + christmasDinner: number; + christmasEve: number; + christmasGift: number; + christmasMorning: number; + christmasTree: number; + cinema: number; + circus: number; + clock: number; + cloud: number; + clown: number; + cobweb: number; + coconut: number; + coffin: number; + comet: number; + computer: number; + cookieMountain: number; + corpseBride: number; + costume: number; + cowboy: number; + crab: number; + craftingTable: number; + crane: number; + crayon: number; + crayons: number; + creeper: number; + crocodile: number; + crystalBall: number; + cup: number; + curtain: number; + cushion: number; + dancer: number; + darkWoods: number; + decoratedHouse: number; + demon: number; + dice: number; + dinosaur: number; + disco: number; + disguise: number; + doll: number; + dollhouse: number; + dolphin: number; + doorbell: number; + doughnut: number; + doughnuts: number; + dracula: number; + dragon: number; + dress: number; + drill: number; + drink: number; + droid: number; + drum: number; + dungeon: number; + earmuffs: number; + earth: number; + easterEgg: number; + eatingCompetition: number; + eggBasket: number; + egyptain: number; + egyptian: number; + eiffelTower: number; + elephant: number; + elf: number; + enderman: number; + engine: number; + ethereal: number; + evergreenTree: number; + evilCat: number; + evilClown: number; + extraterrestrial: number; + eye: number; + fairy: number; + family: number; + fancy: number; + fangs: number; + fantasy: number; + farm: number; + farmersMarket: number; + feast: number; + feather: number; + fire: number; + fireplace: number; + firetruck: number; + firework: number; + fireworks: number; + fishingRod: number; + flag: number; + flamingo: number; + flashlight: number; + floatingIsland: number; + flower: number; + flowerPatch: number; + fly: number; + flying: number; + flyingPig: number; + flyingSaucer: number; + foot: number; + football: number; + forge: number; + fork: number; + fortuneteller: number; + fountain: number; + frankenstein: number; + freezer: number; + fridge: number; + frostyTheSnowman: number; + frozen: number; + fullMoon: number; + futuristicHouse: number; + game: number; + garage: number; + garden: number; + ghast: number; + ghost: number; + ghostShip: number; + ghoul: number; + giantPresents: number; + gifts: number; + gingerbread: number; + gingerbreadHouse: number; + gingerbreadMan: number; + giraffe: number; + girl: number; + glasses: number; + glove: number; + goat: number; + goblin: number; + golem: number; + goose: number; + gothic: number; + gravestone: number; + graveyard: number; + greekTemple: number; + grimReaper: number; + grinch: number; + guitar: number; + gym: number; + halloweenCostumes: number; + halloweenParty: number; + halloweenTreats: number; + hamburger: number; + hammer: number; + hamster: number; + hand: number; + happy: number; + harbor: number; + haunted: number; + hauntedForest: number; + hauntedHouse: number; + head: number; + headlessHorseman: number; + heart: number; + helicopter: number; + hikingTrail: number; + holiday: number; + holly: number; + hotAirBalloon: number; + hotChocolate: number; + house: number; + howl: number; + hugeStocking: number; + hurricane: number; + hypixel: number; + hypixelSweater: number; + iceCream: number; + iceFishing: number; + iceSkating: number; + igloo: number; + illusion: number; + imp: number; + industrial: number; + insect: number; + ironman: number; + island: number; + jackolantern: number; + jellyfish: number; + jetski: number; + jewel: number; + jingleBell: number; + jurassic: number; + keyboard: number; + killerWhale: number; + king: number; + kite: number; + kitten: number; + knight: number; + laboratory: number; + ladyBug: number; + lantern: number; + leaf: number; + leg: number; + library: number; + light: number; + lightbulb: number; + lighthouse: number; + lion: number; + livingDead: number; + llama: number; + lodge: number; + lunchbox: number; + madScientist: number; + magic: number; + magicWand: number; + magician: number; + magnet: number; + mailBox: number; + map: number; + mars: number; + marshmallow: number; + marshmallows: number; + martians: number; + mask: number; + maze: number; + meadow: number; + medieval: number; + mermaid: number; + meteorite: number; + mice: number; + midnight: number; + milk: number; + milkAndCookies: number; + mincePie: number; + mine: number; + mistletoe: number; + modernHome: number; + money: number; + monkey: number; + monster: number; + monsterTruck: number; + monument: number; + moon: number; + motorbike: number; + mouse: number; + movie: number; + mummy: number; + museum: number; + mushroom: number; + music: number; + mutant: number; + mythical: number; + nail: number; + neon: number; + nightmare: number; + ninja: number; + northPole: number; + nose: number; + nostalgia: number; + ocean: number; + octopus: number; + ogre: number; + olympics: number; + orange: number; + oven: number; + owl: number; + package: number; + paint: number; + painting: number; + palace: number; + palmTree: number; + panda: number; + parachute: number; + park: number; + pastel: number; + pen: number; + pencil: number; + penguin: number; + phantom: number; + photograph: number; + piano: number; + picnic: number; + picture: number; + pie: number; + piggyBank: number; + pineapple: number; + pipe: number; + pirate: number; + pirates: number; + pitchfork: number; + pixelArt: number; + plane: number; + plantPot: number; + plate: number; + pogoStick: number; + pogoSticks: number; + pond: number; + pool: number; + poolParty: number; + poolTable: number; + popcorn: number; + popsicle: number; + postOffice: number; + pot: number; + potato: number; + potion: number; + pottedPlant: number; + prehistoric: number; + presentsPile: number; + princess: number; + pumpkinCarving: number; + pyramid: number; + racecar: number; + rainbow: number; + rainforest: number; + rat: number; + reindeer: number; + rhino: number; + ring: number; + robot: number; + robots: number; + rockingChair: number; + rollercoaster: number; + roman: number; + rubberDuck: number; + rudolph: number; + rustic: number; + sackOfPresents: number; + sad: number; + safari: number; + sailboat: number; + sandcastle: number; + sandwich: number; + santa: number; + santaClaus: number; + santasSleigh: number; + santasWorkshop: number; + scarecrow: number; + scaryMovie: number; + school: number; + schoolBus: number; + scifi: number; + scientist: number; + scissors: number; + screw: number; + scythe: number; + selfPortrait: number; + sewer: number; + shark: number; + sheep: number; + shell: number; + shepherd: number; + shipwreck: number; + shoe: number; + shopping: number; + shovel: number; + skateboard: number; + skatepark: number; + skatingRink: number; + skeleton: number; + skeletonJockey: number; + skiCabin: number; + skull: number; + skydiver: number; + sled: number; + slenderman: number; + slime: number; + snail: number; + snake: number; + snowAngel: number; + snowFort: number; + snowGlobe: number; + snowballFight: number; + snowflake: number; + snowman: number; + snowyForest: number; + solarPanels: number; + solarSystem: number; + soldier: number; + sorcerer: number; + soup: number; + space: number; + spaceship: number; + spellbook: number; + spider: number; + spiderWeb: number; + spirit: number; + spirits: number; + sponge: number; + spookyTree: number; + spring: number; + spy: number; + stadium: number; + stamp: number; + star: number; + starryNight: number; + steamLocomotive: number; + steamPunk: number; + steampunk: number; + stick: number; + stocking: number; + sun: number; + sunset: number; + superHero: number; + superhero: number; + supernatural: number; + surfboard: number; + surprise: number; + surreal: number; + sushi: number; + swamp: number; + sweet: number; + sweets: number; + swing: number; + sword: number; + talentShow: number; + tank: number; + tarantula: number; + teddyBear: number; + temple: number; + tennis: number; + tent: number; + test: number; + tests: number; + theBestToyEver: number; + theFuture: number; + theGrinch: number; + theater: number; + themePark: number; + throne: number; + thunderAndLightning: number; + ticket: number; + tiger: number; + tomb: number; + tombstone: number; + tooth: number; + toothpaste: number; + topHat: number; + torch: number; + tornado: number; + tower: number; + towerOfPisa: number; + toyBox: number; + toyFactory: number; + toys: number; + tractor: number; + train: number; + trainStation: number; + trainstation: number; + trampoline: number; + treasure: number; + treasureChest: number; + treehouse: number; + trickortreating: number; + troll: number; + truck: number; + turkey: number; + turtle: number; + usa: number; + umbrella: number; + undead: number; + underTheSea: number; + underground: number; + unicorn: number; + vampire: number; + vegetableGarden: number; + vehicle: number; + vendingMachine: number; + videoGame: number; + viking: number; + volcano: number; + volcanoEruption: number; + volleyballCourt: number; + wallet: number; + warlock: number; + watch: number; + waterBucket: number; + waterfall: number; + web: number; + weightlifting: number; + werewolf: number; + western: number; + whale: number; + wheel: number; + wickedWitch: number; + windmill: number; + winterSuit: number; + wisemen: number; + wish: number; + witch: number; + witchHut: number; + witchcraft: number; + witchesHat: number; + wizard: number; + wolves: number; + wonderland: number; + world: number; + worm: number; + wreath: number; + yuleLog: number; + zebra: number; + zombie: number; + zombieApocalypse: number; + zombiePigman: number; + zombies: number; + zoo: number; + null: number; + constructor(data: Record) { + this.abandoned = data?.votes_Abandoned || 0; + this.abandonedMansion = data?.['votes_Abandoned Mansion'] || 0; + this.adventCalendar = data?.['votes_Advent Calendar'] || 0; + this.airplane = data?.votes_Airplane || 0; + this.aladdin = data?.votes_Aladdin || 0; + this.alien = data?.votes_Alien || 0; + this.alienInvasion = data?.['votes_Alien Invasion'] || 0; + this.anchor = data?.votes_Anchor || 0; + this.ancient = data?.votes_Ancient || 0; + this.angel = data?.votes_Angel || 0; + this.angry = data?.votes_Angry || 0; + this.animal = data?.votes_Animal || 0; + this.ant = data?.votes_Ant || 0; + this.apocalyptic = data?.votes_Apocalyptic || 0; + this.apple = data?.votes_Apple || 0; + this.aquarium = data?.votes_Aquarium || 0; + this.arcade = data?.votes_Arcade || 0; + this.arcadeMachine = data?.['votes_Arcade Machine'] || 0; + this.archer = data?.votes_Archer || 0; + this.arm = data?.votes_Arm || 0; + this.astronaut = data?.votes_Astronaut || 0; + this.awards = data?.votes_Awards || 0; + this.axe = data?.votes_Axe || 0; + this.baby = data?.votes_Baby || 0; + this.backpack = data?.votes_Backpack || 0; + this.bacon = data?.votes_Bacon || 0; + this.bakery = data?.votes_Bakery || 0; + this.baking = data?.votes_Baking || 0; + this.balloon = data?.votes_Balloon || 0; + this.banana = data?.votes_Banana || 0; + this.barbeque = data?.votes_Barbeque || 0; + this.barn = data?.votes_Barn || 0; + this.bat = data?.votes_Bat || 0; + this.bath = data?.votes_Bath || 0; + this.bats = data?.votes_Bats || 0; + this.battle = data?.votes_Battle || 0; + this.baubles = data?.votes_Baubles || 0; + this.beach = data?.votes_Beach || 0; + this.beanstalk = data?.votes_Beanstalk || 0; + this.bear = data?.votes_Bear || 0; + this.beard = data?.votes_Beard || 0; + this.bed = data?.votes_Bed || 0; + this.bee = data?.votes_Bee || 0; + this.bell = data?.votes_Bell || 0; + this.bike = data?.votes_Bike || 0; + this.bikeRiding = data?.['votes_Bike Riding'] || 0; + this.bird = data?.votes_Bird || 0; + this.birdHouse = data?.['votes_Bird House'] || 0; + this.birthday = data?.votes_Birthday || 0; + this.birthdayParty = data?.['votes_Birthday Party'] || 0; + this.blaze = data?.votes_Blaze || 0; + this.blizzard = data?.votes_Blizzard || 0; + this.block = data?.votes_Block || 0; + this.blocks = data?.votes_Blocks || 0; + this.boardGames = data?.['votes_Board Games'] || 0; + this.boardgames = data?.votes_Boardgames || 0; + this.boat = data?.votes_Boat || 0; + this.bobsledding = data?.votes_Bobsledding || 0; + this.bones = data?.votes_Bones || 0; + this.boogeyman = data?.votes_Boogeyman || 0; + this.book = data?.votes_Book || 0; + this.boot = data?.votes_Boot || 0; + this.bottle = data?.votes_Bottle || 0; + this.bouncyCastle = data?.['votes_Bouncy Castle'] || 0; + this.bowlingAlley = data?.['votes_Bowling Alley'] || 0; + this.box = data?.votes_Box || 0; + this.boxingRing = data?.['votes_Boxing Ring'] || 0; + this.boy = data?.votes_Boy || 0; + this.brain = data?.votes_Brain || 0; + this.branch = data?.votes_Branch || 0; + this.bread = data?.votes_Bread || 0; + this.breakfast = data?.votes_Breakfast || 0; + this.brewingStand = data?.['votes_Brewing Stand'] || 0; + this.bridge = data?.votes_Bridge || 0; + this.brokenBridge = data?.['votes_Broken Bridge'] || 0; + this.broomstick = data?.votes_Broomstick || 0; + this.bucket = data?.votes_Bucket || 0; + this.bug = data?.votes_Bug || 0; + this.builder = data?.votes_Builder || 0; + this.bunny = data?.votes_Bunny || 0; + this.buried = data?.votes_Buried || 0; + this.butterflies = data?.votes_Butterflies || 0; + this.butterfly = data?.votes_Butterfly || 0; + this.button = data?.votes_Button || 0; + this.cabin = data?.votes_Cabin || 0; + this.cake = data?.votes_Cake || 0; + this.camel = data?.votes_Camel || 0; + this.camera = data?.votes_Camera || 0; + this.camp = data?.votes_Camp || 0; + this.campfire = data?.votes_Campfire || 0; + this.camping = data?.votes_Camping || 0; + this.campsite = data?.votes_Campsite || 0; + this.candle = data?.votes_Candle || 0; + this.candlelight = data?.votes_Candlelight || 0; + this.candles = data?.votes_Candles || 0; + this.candy = data?.votes_Candy || 0; + this.candyBuckets = data?.['votes_Candy Buckets'] || 0; + this.candyCane = data?.['votes_Candy Cane'] || 0; + this.cannon = data?.votes_Cannon || 0; + this.car = data?.votes_Car || 0; + this.caribbean = data?.votes_Caribbean || 0; + this.carnival = data?.votes_Carnival || 0; + this.carolling = data?.votes_Carolling || 0; + this.cart = data?.votes_Cart || 0; + this.cartoon = data?.votes_Cartoon || 0; + this.castle = data?.votes_Castle || 0; + this.cat = data?.votes_Cat || 0; + this.catapult = data?.votes_Catapult || 0; + this.caterpillar = data?.votes_Caterpillar || 0; + this.cauldron = data?.votes_Cauldron || 0; + this.cave = data?.votes_Cave || 0; + this.celebration = data?.votes_Celebration || 0; + this.cellar = data?.votes_Cellar || 0; + this.cheese = data?.votes_Cheese || 0; + this.chemistry = data?.votes_Chemistry || 0; + this.cherry = data?.votes_Cherry || 0; + this.cherryBlossom = data?.['votes_Cherry Blossom'] || 0; + this.cherryBlossoms = data?.['votes_Cherry Blossoms'] || 0; + this.chess = data?.votes_Chess || 0; + this.chest = data?.votes_Chest || 0; + this.chicken = data?.votes_Chicken || 0; + this.chimney = data?.votes_Chimney || 0; + this.chocolate = data?.votes_Chocolate || 0; + this.chocolateFactory = data?.['votes_Chocolate Factory'] || 0; + this.choir = data?.votes_Choir || 0; + this.christmasCard = data?.['votes_Christmas Card'] || 0; + this.christmasDinner = data?.['votes_Christmas Dinner'] || 0; + this.christmasEve = data?.['votes_Christmas Eve'] || 0; + this.christmasGift = data?.['votes_Christmas Gift'] || 0; + this.christmasMorning = data?.['votes_Christmas Morning'] || 0; + this.christmasTree = data?.['votes_Christmas Tree'] || 0; + this.cinema = data?.votes_Cinema || 0; + this.circus = data?.votes_Circus || 0; + this.clock = data?.votes_Clock || 0; + this.cloud = data?.votes_Cloud || 0; + this.clown = data?.votes_Clown || 0; + this.cobweb = data?.votes_Cobweb || 0; + this.coconut = data?.votes_Coconut || 0; + this.coffin = data?.votes_Coffin || 0; + this.comet = data?.votes_Comet || 0; + this.computer = data?.votes_Computer || 0; + this.cookieMountain = data?.['votes_Cookie Mountain'] || 0; + this.corpseBride = data?.['votes_Corpse Bride'] || 0; + this.costume = data?.votes_Costume || 0; + this.cowboy = data?.votes_Cowboy || 0; + this.crab = data?.votes_Crab || 0; + this.craftingTable = data?.['votes_Crafting Table'] || 0; + this.crane = data?.votes_Crane || 0; + this.crayon = data?.votes_Crayon || 0; + this.crayons = data?.votes_Crayons || 0; + this.creeper = data?.votes_Creeper || 0; + this.crocodile = data?.votes_Crocodile || 0; + this.crystalBall = data?.['votes_Crystal Ball'] || 0; + this.cup = data?.votes_Cup || 0; + this.curtain = data?.votes_Curtain || 0; + this.cushion = data?.votes_Cushion || 0; + this.dancer = data?.votes_Dancer || 0; + this.darkWoods = data?.['votes_Dark woods'] || 0; + this.decoratedHouse = data?.['votes_Decorated House'] || 0; + this.demon = data?.votes_Demon || 0; + this.dice = data?.votes_Dice || 0; + this.dinosaur = data?.votes_Dinosaur || 0; + this.disco = data?.votes_Disco || 0; + this.disguise = data?.votes_Disguise || 0; + this.doll = data?.votes_Doll || 0; + this.dollhouse = data?.votes_Dollhouse || 0; + this.dolphin = data?.votes_Dolphin || 0; + this.doorbell = data?.votes_Doorbell || 0; + this.doughnut = data?.votes_Doughnut || 0; + this.doughnuts = data?.votes_Doughnuts || 0; + this.dracula = data?.votes_Dracula || 0; + this.dragon = data?.votes_Dragon || 0; + this.dress = data?.votes_Dress || 0; + this.drill = data?.votes_Drill || 0; + this.drink = data?.votes_Drink || 0; + this.droid = data?.votes_Droid || 0; + this.drum = data?.votes_Drum || 0; + this.dungeon = data?.votes_Dungeon || 0; + this.earmuffs = data?.votes_Earmuffs || 0; + this.earth = data?.votes_Earth || 0; + this.easterEgg = data?.['votes_Easter Egg'] || 0; + this.eatingCompetition = data?.['votes_Eating Competition'] || 0; + this.eggBasket = data?.['votes_Egg Basket'] || 0; + this.egyptain = data?.votes_Egyptain || 0; + this.egyptian = data?.votes_Egyptian || 0; + this.eiffelTower = data?.['votes_Eiffel tower'] || 0; + this.elephant = data?.votes_Elephant || 0; + this.elf = data?.votes_Elf || 0; + this.enderman = data?.votes_Enderman || 0; + this.engine = data?.votes_Engine || 0; + this.ethereal = data?.votes_Ethereal || 0; + this.evergreenTree = data?.['votes_Evergreen Tree'] || 0; + this.evilCat = data?.['votes_Evil Cat'] || 0; + this.evilClown = data?.['votes_Evil Clown'] || 0; + this.extraterrestrial = data?.votes_Extraterrestrial || 0; + this.eye = data?.votes_Eye || 0; + this.fairy = data?.votes_Fairy || 0; + this.family = data?.votes_Family || 0; + this.fancy = data?.votes_Fancy || 0; + this.fangs = data?.votes_Fangs || 0; + this.fantasy = data?.votes_Fantasy || 0; + this.farm = data?.votes_Farm || 0; + this.farmersMarket = data?.["votes_Farmer's Market"] || 0; + this.feast = data?.votes_Feast || 0; + this.feather = data?.votes_Feather || 0; + this.fire = data?.votes_Fire || 0; + this.fireplace = data?.votes_Fireplace || 0; + this.firetruck = data?.votes_Firetruck || 0; + this.firework = data?.votes_Firework || 0; + this.fireworks = data?.votes_Fireworks || 0; + this.fishingRod = data?.['votes_Fishing Rod'] || 0; + this.flag = data?.votes_Flag || 0; + this.flamingo = data?.votes_Flamingo || 0; + this.flashlight = data?.votes_Flashlight || 0; + this.floatingIsland = data?.['votes_Floating Island'] || 0; + this.flower = data?.votes_Flower || 0; + this.flowerPatch = data?.['votes_Flower Patch'] || 0; + this.fly = data?.votes_Fly || 0; + this.flying = data?.votes_Flying || 0; + this.flyingPig = data?.['votes_Flying Pig'] || 0; + this.flyingSaucer = data?.['votes_Flying Saucer'] || 0; + this.foot = data?.votes_Foot || 0; + this.football = data?.votes_Football || 0; + this.forge = data?.votes_Forge || 0; + this.fork = data?.votes_Fork || 0; + this.fortuneteller = data?.votes_Fortuneteller || 0; + this.fountain = data?.votes_Fountain || 0; + this.frankenstein = data?.votes_Frankenstein || 0; + this.freezer = data?.votes_Freezer || 0; + this.fridge = data?.votes_Fridge || 0; + this.frostyTheSnowman = data?.['votes_Frosty the Snowman'] || 0; + this.frozen = data?.votes_Frozen || 0; + this.fullMoon = data?.['votes_Full Moon'] || 0; + this.futuristicHouse = data?.['votes_Futuristic House'] || 0; + this.game = data?.votes_Game || 0; + this.garage = data?.votes_Garage || 0; + this.garden = data?.votes_Garden || 0; + this.ghast = data?.votes_Ghast || 0; + this.ghost = data?.votes_Ghost || 0; + this.ghostShip = data?.['votes_Ghost Ship'] || 0; + this.ghoul = data?.votes_Ghoul || 0; + this.giantPresents = data?.['votes_Giant Presents'] || 0; + this.gifts = data?.votes_Gifts || 0; + this.gingerbread = data?.votes_Gingerbread || 0; + this.gingerbreadHouse = data?.['votes_Gingerbread House'] || 0; + this.gingerbreadMan = data?.['votes_Gingerbread Man'] || 0; + this.giraffe = data?.votes_Giraffe || 0; + this.girl = data?.votes_Girl || 0; + this.glasses = data?.votes_Glasses || 0; + this.glove = data?.votes_Glove || 0; + this.goat = data?.votes_Goat || 0; + this.goblin = data?.votes_Goblin || 0; + this.golem = data?.votes_Golem || 0; + this.goose = data?.votes_Goose || 0; + this.gothic = data?.votes_Gothic || 0; + this.gravestone = data?.votes_Gravestone || 0; + this.graveyard = data?.votes_Graveyard || 0; + this.greekTemple = data?.['votes_Greek Temple'] || 0; + this.grimReaper = data?.['votes_Grim Reaper'] || 0; + this.grinch = data?.votes_Grinch || 0; + this.guitar = data?.votes_Guitar || 0; + this.gym = data?.votes_Gym || 0; + this.halloweenCostumes = data?.['votes_Halloween Costumes'] || 0; + this.halloweenParty = data?.['votes_Halloween Party'] || 0; + this.halloweenTreats = data?.['votes_Halloween Treats'] || 0; + this.hamburger = data?.votes_Hamburger || 0; + this.hammer = data?.votes_Hammer || 0; + this.hamster = data?.votes_Hamster || 0; + this.hand = data?.votes_Hand || 0; + this.happy = data?.votes_Happy || 0; + this.harbor = data?.votes_Harbor || 0; + this.haunted = data?.votes_Haunted || 0; + this.hauntedForest = data?.['votes_Haunted Forest'] || 0; + this.hauntedHouse = data?.['votes_Haunted House'] || 0; + this.head = data?.votes_Head || 0; + this.headlessHorseman = data?.['votes_Headless Horseman'] || 0; + this.heart = data?.votes_Heart || 0; + this.helicopter = data?.votes_Helicopter || 0; + this.hikingTrail = data?.['votes_Hiking Trail'] || 0; + this.holiday = data?.votes_Holiday || 0; + this.holly = data?.votes_Holly || 0; + this.hotAirBalloon = data?.['votes_Hot Air Balloon'] || 0; + this.hotChocolate = data?.['votes_Hot Chocolate'] || 0; + this.house = data?.votes_House || 0; + this.howl = data?.votes_Howl || 0; + this.hugeStocking = data?.['votes_Huge Stocking'] || 0; + this.hurricane = data?.votes_Hurricane || 0; + this.hypixel = data?.votes_Hypixel || 0; + this.hypixelSweater = data?.['votes_Hypixel Sweater'] || 0; + this.iceCream = data?.['votes_Ice Cream'] || 0; + this.iceFishing = data?.['votes_Ice Fishing'] || 0; + this.iceSkating = data?.['votes_Ice Skating'] || 0; + this.igloo = data?.votes_Igloo || 0; + this.illusion = data?.votes_Illusion || 0; + this.imp = data?.votes_Imp || 0; + this.industrial = data?.votes_Industrial || 0; + this.insect = data?.votes_Insect || 0; + this.ironman = data?.votes_Ironman || 0; + this.island = data?.votes_Island || 0; + this.jackolantern = data?.['votes_Jack-O-Lantern'] || 0; + this.jellyfish = data?.votes_Jellyfish || 0; + this.jetski = data?.votes_Jetski || 0; + this.jewel = data?.votes_Jewel || 0; + this.jingleBell = data?.['votes_Jingle Bell'] || 0; + this.jurassic = data?.votes_Jurassic || 0; + this.keyboard = data?.votes_Keyboard || 0; + this.killerWhale = data?.['votes_Killer Whale'] || 0; + this.king = data?.votes_King || 0; + this.kite = data?.votes_Kite || 0; + this.kitten = data?.votes_Kitten || 0; + this.knight = data?.votes_Knight || 0; + this.laboratory = data?.votes_Laboratory || 0; + this.ladyBug = data?.['votes_Lady Bug'] || 0; + this.lantern = data?.votes_Lantern || 0; + this.leaf = data?.votes_Leaf || 0; + this.leg = data?.votes_Leg || 0; + this.library = data?.votes_Library || 0; + this.light = data?.votes_Light || 0; + this.lightbulb = data?.votes_Lightbulb || 0; + this.lighthouse = data?.votes_Lighthouse || 0; + this.lion = data?.votes_Lion || 0; + this.livingDead = data?.['votes_Living dead'] || 0; + this.llama = data?.votes_Llama || 0; + this.lodge = data?.votes_Lodge || 0; + this.lunchbox = data?.votes_Lunchbox || 0; + this.madScientist = data?.['votes_Mad Scientist'] || 0; + this.magic = data?.votes_Magic || 0; + this.magicWand = data?.['votes_Magic Wand'] || 0; + this.magician = data?.votes_Magician || 0; + this.magnet = data?.votes_Magnet || 0; + this.mailBox = data?.['votes_Mail Box'] || 0; + this.map = data?.votes_Map || 0; + this.mars = data?.votes_Mars || 0; + this.marshmallow = data?.votes_Marshmallow || 0; + this.marshmallows = data?.votes_Marshmallows || 0; + this.martians = data?.votes_Martians || 0; + this.mask = data?.votes_Mask || 0; + this.maze = data?.votes_Maze || 0; + this.meadow = data?.votes_Meadow || 0; + this.medieval = data?.votes_Medieval || 0; + this.mermaid = data?.votes_Mermaid || 0; + this.meteorite = data?.votes_Meteorite || 0; + this.mice = data?.votes_Mice || 0; + this.midnight = data?.votes_Midnight || 0; + this.milk = data?.votes_Milk || 0; + this.milkAndCookies = data?.['votes_Milk and Cookies'] || 0; + this.mincePie = data?.['votes_Mince Pie'] || 0; + this.mine = data?.votes_Mine || 0; + this.mistletoe = data?.votes_Mistletoe || 0; + this.modernHome = data?.['votes_Modern Home'] || 0; + this.money = data?.votes_Money || 0; + this.monkey = data?.votes_Monkey || 0; + this.monster = data?.votes_Monster || 0; + this.monsterTruck = data?.['votes_Monster Truck'] || 0; + this.monument = data?.votes_Monument || 0; + this.moon = data?.votes_Moon || 0; + this.motorbike = data?.votes_Motorbike || 0; + this.mouse = data?.votes_Mouse || 0; + this.movie = data?.votes_Movie || 0; + this.mummy = data?.votes_Mummy || 0; + this.museum = data?.votes_Museum || 0; + this.mushroom = data?.votes_Mushroom || 0; + this.music = data?.votes_Music || 0; + this.mutant = data?.votes_Mutant || 0; + this.mythical = data?.votes_Mythical || 0; + this.nail = data?.votes_Nail || 0; + this.neon = data?.votes_Neon || 0; + this.nightmare = data?.votes_Nightmare || 0; + this.ninja = data?.votes_Ninja || 0; + this.northPole = data?.['votes_North Pole'] || 0; + this.nose = data?.votes_Nose || 0; + this.nostalgia = data?.votes_Nostalgia || 0; + this.ocean = data?.votes_Ocean || 0; + this.octopus = data?.votes_Octopus || 0; + this.ogre = data?.votes_Ogre || 0; + this.olympics = data?.votes_Olympics || 0; + this.orange = data?.votes_Orange || 0; + this.oven = data?.votes_Oven || 0; + this.owl = data?.votes_Owl || 0; + this.package = data?.votes_Package || 0; + this.paint = data?.votes_Paint || 0; + this.painting = data?.votes_Painting || 0; + this.palace = data?.votes_Palace || 0; + this.palmTree = data?.['votes_Palm Tree'] || 0; + this.panda = data?.votes_Panda || 0; + this.parachute = data?.votes_Parachute || 0; + this.park = data?.votes_Park || 0; + this.pastel = data?.votes_Pastel || 0; + this.pen = data?.votes_Pen || 0; + this.pencil = data?.votes_Pencil || 0; + this.penguin = data?.votes_Penguin || 0; + this.phantom = data?.votes_Phantom || 0; + this.photograph = data?.votes_Photograph || 0; + this.piano = data?.votes_Piano || 0; + this.picnic = data?.votes_Picnic || 0; + this.picture = data?.votes_Picture || 0; + this.pie = data?.votes_Pie || 0; + this.piggyBank = data?.['votes_Piggy Bank'] || 0; + this.pineapple = data?.votes_Pineapple || 0; + this.pipe = data?.votes_Pipe || 0; + this.pirate = data?.votes_Pirate || 0; + this.pirates = data?.votes_Pirates || 0; + this.pitchfork = data?.votes_Pitchfork || 0; + this.pixelArt = data?.['votes_Pixel Art'] || 0; + this.plane = data?.votes_Plane || 0; + this.plantPot = data?.['votes_Plant Pot'] || 0; + this.plate = data?.votes_Plate || 0; + this.pogoStick = data?.['votes_Pogo Stick'] || 0; + this.pogoSticks = data?.['votes_Pogo Sticks'] || 0; + this.pond = data?.votes_Pond || 0; + this.pool = data?.votes_Pool || 0; + this.poolParty = data?.['votes_Pool Party'] || 0; + this.poolTable = data?.['votes_Pool Table'] || 0; + this.popcorn = data?.votes_Popcorn || 0; + this.popsicle = data?.votes_Popsicle || 0; + this.postOffice = data?.['votes_Post Office'] || 0; + this.pot = data?.votes_Pot || 0; + this.potato = data?.votes_Potato || 0; + this.potion = data?.votes_Potion || 0; + this.pottedPlant = data?.['votes_Potted Plant'] || 0; + this.prehistoric = data?.votes_Prehistoric || 0; + this.presentsPile = data?.['votes_Presents Pile'] || 0; + this.princess = data?.votes_Princess || 0; + this.pumpkinCarving = data?.['votes_Pumpkin Carving'] || 0; + this.pyramid = data?.votes_Pyramid || 0; + this.racecar = data?.votes_Racecar || 0; + this.rainbow = data?.votes_Rainbow || 0; + this.rainforest = data?.votes_Rainforest || 0; + this.rat = data?.votes_Rat || 0; + this.reindeer = data?.votes_Reindeer || 0; + this.rhino = data?.votes_Rhino || 0; + this.ring = data?.votes_Ring || 0; + this.robot = data?.votes_Robot || 0; + this.robots = data?.votes_Robots || 0; + this.rockingChair = data?.['votes_Rocking Chair'] || 0; + this.rollercoaster = data?.votes_Rollercoaster || 0; + this.roman = data?.votes_Roman || 0; + this.rubberDuck = data?.['votes_Rubber Duck'] || 0; + this.rudolph = data?.votes_Rudolph || 0; + this.rustic = data?.votes_Rustic || 0; + this.sackOfPresents = data?.['votes_Sack of Presents'] || 0; + this.sad = data?.votes_Sad || 0; + this.safari = data?.votes_Safari || 0; + this.sailboat = data?.votes_Sailboat || 0; + this.sandcastle = data?.votes_Sandcastle || 0; + this.sandwich = data?.votes_Sandwich || 0; + this.santa = data?.votes_Santa || 0; + this.santaClaus = data?.['votes_Santa Claus'] || 0; + this.santasSleigh = data?.["votes_Santa's Sleigh"] || 0; + this.santasWorkshop = data?.["votes_Santa's Workshop"] || 0; + this.scarecrow = data?.votes_Scarecrow || 0; + this.scaryMovie = data?.['votes_Scary Movie'] || 0; + this.school = data?.votes_School || 0; + this.schoolBus = data?.['votes_School Bus'] || 0; + this.scifi = data?.['votes_Sci-fi'] || 0; + this.scientist = data?.votes_Scientist || 0; + this.scissors = data?.votes_Scissors || 0; + this.screw = data?.votes_Screw || 0; + this.scythe = data?.votes_Scythe || 0; + this.selfPortrait = data?.['votes_Self Portrait'] || 0; + this.sewer = data?.votes_Sewer || 0; + this.shark = data?.votes_Shark || 0; + this.sheep = data?.votes_Sheep || 0; + this.shell = data?.votes_Shell || 0; + this.shepherd = data?.votes_Shepherd || 0; + this.shipwreck = data?.votes_Shipwreck || 0; + this.shoe = data?.votes_Shoe || 0; + this.shopping = data?.votes_Shopping || 0; + this.shovel = data?.votes_Shovel || 0; + this.skateboard = data?.votes_Skateboard || 0; + this.skatepark = data?.votes_Skatepark || 0; + this.skatingRink = data?.['votes_Skating Rink'] || 0; + this.skeleton = data?.votes_Skeleton || 0; + this.skeletonJockey = data?.['votes_Skeleton Jockey'] || 0; + this.skiCabin = data?.['votes_Ski Cabin'] || 0; + this.skull = data?.votes_Skull || 0; + this.skydiver = data?.votes_Skydiver || 0; + this.sled = data?.votes_Sled || 0; + this.slenderman = data?.votes_Slenderman || 0; + this.slime = data?.votes_Slime || 0; + this.snail = data?.votes_Snail || 0; + this.snake = data?.votes_Snake || 0; + this.snowAngel = data?.['votes_Snow Angel'] || 0; + this.snowFort = data?.['votes_Snow Fort'] || 0; + this.snowGlobe = data?.['votes_Snow Globe'] || 0; + this.snowballFight = data?.['votes_Snowball Fight'] || 0; + this.snowflake = data?.votes_Snowflake || 0; + this.snowman = data?.votes_Snowman || 0; + this.snowyForest = data?.['votes_Snowy Forest'] || 0; + this.solarPanels = data?.['votes_Solar Panels'] || 0; + this.solarSystem = data?.['votes_Solar System'] || 0; + this.soldier = data?.votes_Soldier || 0; + this.sorcerer = data?.votes_Sorcerer || 0; + this.soup = data?.votes_Soup || 0; + this.space = data?.votes_Space || 0; + this.spaceship = data?.votes_Spaceship || 0; + this.spellbook = data?.votes_Spellbook || 0; + this.spider = data?.votes_Spider || 0; + this.spiderWeb = data?.['votes_Spider Web'] || 0; + this.spirit = data?.votes_Spirit || 0; + this.spirits = data?.votes_Spirits || 0; + this.sponge = data?.votes_Sponge || 0; + this.spookyTree = data?.['votes_Spooky Tree'] || 0; + this.spring = data?.votes_Spring || 0; + this.spy = data?.votes_Spy || 0; + this.stadium = data?.votes_Stadium || 0; + this.stamp = data?.votes_Stamp || 0; + this.star = data?.votes_Star || 0; + this.starryNight = data?.['votes_Starry Night'] || 0; + this.steamLocomotive = data?.['votes_Steam Locomotive'] || 0; + this.steamPunk = data?.['votes_Steam Punk'] || 0; + this.steampunk = data?.votes_Steampunk || 0; + this.stick = data?.votes_Stick || 0; + this.stocking = data?.votes_Stocking || 0; + this.sun = data?.votes_Sun || 0; + this.sunset = data?.votes_Sunset || 0; + this.superHero = data?.['votes_Super Hero'] || 0; + this.superhero = data?.votes_Superhero || 0; + this.supernatural = data?.votes_Supernatural || 0; + this.surfboard = data?.votes_Surfboard || 0; + this.surprise = data?.votes_Surprise || 0; + this.surreal = data?.votes_Surreal || 0; + this.sushi = data?.votes_Sushi || 0; + this.swamp = data?.votes_Swamp || 0; + this.sweet = data?.votes_Sweet || 0; + this.sweets = data?.votes_Sweets || 0; + this.swing = data?.votes_Swing || 0; + this.sword = data?.votes_Sword || 0; + this.talentShow = data?.['votes_Talent Show'] || 0; + this.tank = data?.votes_Tank || 0; + this.tarantula = data?.votes_Tarantula || 0; + this.teddyBear = data?.['votes_Teddy Bear'] || 0; + this.temple = data?.votes_Temple || 0; + this.tennis = data?.votes_Tennis || 0; + this.tent = data?.votes_Tent || 0; + this.test = data?.votes_Test || 0; + this.tests = data?.votes_Tests || 0; + this.theBestToyEver = data?.['votes_The Best Toy Ever'] || 0; + this.theFuture = data?.['votes_The Future'] || 0; + this.theGrinch = data?.['votes_The Grinch'] || 0; + this.theater = data?.votes_Theater || 0; + this.themePark = data?.['votes_Theme Park'] || 0; + this.throne = data?.votes_Throne || 0; + this.thunderAndLightning = data?.['votes_Thunder and Lightning'] || 0; + this.ticket = data?.votes_Ticket || 0; + this.tiger = data?.votes_Tiger || 0; + this.tomb = data?.votes_Tomb || 0; + this.tombstone = data?.votes_Tombstone || 0; + this.tooth = data?.votes_Tooth || 0; + this.toothpaste = data?.votes_Toothpaste || 0; + this.topHat = data?.['votes_Top Hat'] || 0; + this.torch = data?.votes_Torch || 0; + this.tornado = data?.votes_Tornado || 0; + this.tower = data?.votes_Tower || 0; + this.towerOfPisa = data?.['votes_Tower of Pisa'] || 0; + this.toyBox = data?.['votes_Toy Box'] || 0; + this.toyFactory = data?.['votes_Toy Factory'] || 0; + this.toys = data?.votes_Toys || 0; + this.tractor = data?.votes_Tractor || 0; + this.train = data?.votes_Train || 0; + this.trainStation = data?.['votes_Train Station'] || 0; + this.trainstation = data?.votes_Trainstation || 0; + this.trampoline = data?.votes_Trampoline || 0; + this.treasure = data?.votes_Treasure || 0; + this.treasureChest = data?.['votes_Treasure Chest'] || 0; + this.treehouse = data?.votes_Treehouse || 0; + this.trickortreating = data?.['votes_Trick-or-Treating'] || 0; + this.troll = data?.votes_Troll || 0; + this.truck = data?.votes_Truck || 0; + this.turkey = data?.votes_Turkey || 0; + this.turtle = data?.votes_Turtle || 0; + this.usa = data?.votes_USA || 0; + this.umbrella = data?.votes_Umbrella || 0; + this.undead = data?.votes_Undead || 0; + this.underTheSea = data?.['votes_Under the Sea'] || 0; + this.underground = data?.votes_Underground || 0; + this.unicorn = data?.votes_Unicorn || 0; + this.vampire = data?.votes_Vampire || 0; + this.vegetableGarden = data?.['votes_Vegetable Garden'] || 0; + this.vehicle = data?.votes_Vehicle || 0; + this.vendingMachine = data?.['votes_Vending Machine'] || 0; + this.videoGame = data?.['votes_Video Game'] || 0; + this.viking = data?.votes_Viking || 0; + this.volcano = data?.votes_Volcano || 0; + this.volcanoEruption = data?.['votes_Volcano Eruption'] || 0; + this.volleyballCourt = data?.['votes_Volleyball Court'] || 0; + this.wallet = data?.votes_Wallet || 0; + this.warlock = data?.votes_Warlock || 0; + this.watch = data?.votes_Watch || 0; + this.waterBucket = data?.['votes_Water Bucket'] || 0; + this.waterfall = data?.votes_Waterfall || 0; + this.web = data?.votes_Web || 0; + this.weightlifting = data?.votes_Weightlifting || 0; + this.werewolf = data?.votes_Werewolf || 0; + this.western = data?.votes_Western || 0; + this.whale = data?.votes_Whale || 0; + this.wheel = data?.votes_Wheel || 0; + this.wickedWitch = data?.['votes_Wicked Witch'] || 0; + this.windmill = data?.votes_Windmill || 0; + this.winterSuit = data?.['votes_Winter Suit'] || 0; + this.wisemen = data?.votes_Wisemen || 0; + this.wish = data?.votes_Wish || 0; + this.witch = data?.votes_Witch || 0; + this.witchHut = data?.['votes_Witch Hut'] || 0; + this.witchcraft = data?.votes_Witchcraft || 0; + this.witchesHat = data?.['votes_Witches Hat'] || 0; + this.wizard = data?.votes_Wizard || 0; + this.wolves = data?.votes_Wolves || 0; + this.wonderland = data?.votes_Wonderland || 0; + this.world = data?.votes_World || 0; + this.worm = data?.votes_Worm || 0; + this.wreath = data?.votes_Wreath || 0; + this.yuleLog = data?.['votes_Yule Log'] || 0; + this.zebra = data?.votes_Zebra || 0; + this.zombie = data?.votes_Zombie || 0; + this.zombieApocalypse = data?.['votes_Zombie Apocalypse'] || 0; + this.zombiePigman = data?.['votes_Zombie Pigman'] || 0; + this.zombies = data?.votes_Zombies || 0; + this.zoo = data?.votes_Zoo || 0; + this.null = data?.votes_null || 0; + } +} + +export default BuildBattleVotes; diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.test.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.test.ts new file mode 100644 index 000000000..af6d3c254 --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.test.ts @@ -0,0 +1,179 @@ +import CopsAndCrims from './CopsAndCrims.js'; +import CopsAndCrimsGamemode from './CopsAndCrimsGamemode.js'; +import CopsAndCrimsGun from './CopsAndCrimsGun.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('CopsAndCrims', () => { + const data = new CopsAndCrims({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(CopsAndCrims); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.criminalKills).toBeDefined(); + expect(data.criminalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.criminalKills).toEqualTypeOf(); + expect(data.copKills).toBeDefined(); + expect(data.copKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.copKills).toEqualTypeOf(); + expect(data.headShotKills).toBeDefined(); + expect(data.headShotKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headShotKills).toEqualTypeOf(); + expect(data.grenadeKills).toBeDefined(); + expect(data.grenadeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grenadeKills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.winsOnTemple).toBeDefined(); + expect(data.winsOnTemple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnTemple).toEqualTypeOf(); + expect(data.winsOnCarrier).toBeDefined(); + expect(data.winsOnCarrier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnCarrier).toEqualTypeOf(); + expect(data.winsOnAtomic).toBeDefined(); + expect(data.winsOnAtomic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnAtomic).toEqualTypeOf(); + expect(data.winsOnAlleyway).toBeDefined(); + expect(data.winsOnAlleyway).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnAlleyway).toEqualTypeOf(); + expect(data.winsOnSandstorm).toBeDefined(); + expect(data.winsOnSandstorm).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnSandstorm).toEqualTypeOf(); + expect(data.winsOnReserve).toBeDefined(); + expect(data.winsOnReserve).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnReserve).toEqualTypeOf(); + expect(data.winsOnOvergrown).toBeDefined(); + expect(data.winsOnOvergrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnOvergrown).toEqualTypeOf(); + expect(data.winsOnBazaar).toBeDefined(); + expect(data.winsOnBazaar).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnBazaar).toEqualTypeOf(); + expect(data.winsOnJunction).toBeDefined(); + expect(data.winsOnJunction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnJunction).toEqualTypeOf(); + expect(data.winsOnDerailed).toBeDefined(); + expect(data.winsOnDerailed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnDerailed).toEqualTypeOf(); + expect(data.winsOnCastle).toBeDefined(); + expect(data.winsOnCastle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnCastle).toEqualTypeOf(); + expect(data.winsOnRuins).toBeDefined(); + expect(data.winsOnRuins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnRuins).toEqualTypeOf(); + expect(data.winsOnRiviera).toBeDefined(); + expect(data.winsOnRiviera).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnRiviera).toEqualTypeOf(); + expect(data.winsOnHarbor).toBeDefined(); + expect(data.winsOnHarbor).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnHarbor).toEqualTypeOf(); + expect(data.winsOnAtomicV1).toBeDefined(); + expect(data.winsOnAtomicV1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnAtomicV1).toEqualTypeOf(); + expect(data.winsOnAtomicV2).toBeDefined(); + expect(data.winsOnAtomicV2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnAtomicV2).toEqualTypeOf(); + expect(data.winsOnMelonFactory).toBeDefined(); + expect(data.winsOnMelonFactory).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnMelonFactory).toEqualTypeOf(); + expect(data.winsOnMelonFactoryV2).toBeDefined(); + expect(data.winsOnMelonFactoryV2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winsOnMelonFactoryV2).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.roundWins).toBeDefined(); + expect(data.roundWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.roundWins).toEqualTypeOf(); + expect(data.bombsPlanted).toBeDefined(); + expect(data.bombsPlanted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bombsPlanted).toEqualTypeOf(); + expect(data.bombsDefused).toBeDefined(); + expect(data.bombsDefused).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bombsDefused).toEqualTypeOf(); + expect(data.shotsFired).toBeDefined(); + expect(data.shotsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shotsFired).toEqualTypeOf(); + expect(data.showPrefixInLobby).toBeDefined(); + expectTypeOf(data.showPrefixInLobby).toEqualTypeOf(); + expect(data.selectedLobbyPrefix).toBeDefined(); + expectTypeOf(data.selectedLobbyPrefix).toEqualTypeOf(); + expect(data.lobbyPrefixColor).toBeDefined(); + expectTypeOf(data.lobbyPrefixColor).toEqualTypeOf(); + expect(data.showHints).toBeDefined(); + expectTypeOf(data.showHints).toEqualTypeOf(); + expect(data.showKillsInPrefix).toBeDefined(); + expectTypeOf(data.showKillsInPrefix).toEqualTypeOf(); + expect(data.score).toBeDefined(); + expect(data.score).toBeGreaterThanOrEqual(0); + expectTypeOf(data.score).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.activeGlyph).toBeDefined(); + expectTypeOf(data.activeGlyph).toEqualTypeOf(); + expect(data.activeScheme).toBeDefined(); + expectTypeOf(data.activeScheme).toEqualTypeOf(); + expect(data.activeEmblem).toBeDefined(); + expectTypeOf(data.activeEmblem).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.smg).toBeDefined(); + expect(data.smg).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.smg).toEqualTypeOf(); + expect(data.rifle).toBeDefined(); + expect(data.rifle).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.rifle).toEqualTypeOf(); + expect(data.carbine).toBeDefined(); + expect(data.carbine).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.carbine).toEqualTypeOf(); + expect(data.magnum).toBeDefined(); + expect(data.magnum).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.magnum).toEqualTypeOf(); + expect(data.shotgun).toBeDefined(); + expect(data.shotgun).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.shotgun).toEqualTypeOf(); + expect(data.sniper).toBeDefined(); + expect(data.sniper).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.sniper).toEqualTypeOf(); + expect(data.scopedRifle).toBeDefined(); + expect(data.scopedRifle).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.scopedRifle).toEqualTypeOf(); + expect(data.handgun).toBeDefined(); + expect(data.handgun).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.handgun).toEqualTypeOf(); + expect(data.autoShotgun).toBeDefined(); + expect(data.autoShotgun).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.autoShotgun).toEqualTypeOf(); + expect(data.bullpup).toBeDefined(); + expect(data.bullpup).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.bullpup).toEqualTypeOf(); + expect(data.knife).toBeDefined(); + expect(data.knife).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data.knife).toEqualTypeOf(); + expect(data.deathmatch).toBeDefined(); + expect(data.deathmatch).toBeInstanceOf(CopsAndCrimsGamemode); + expectTypeOf(data.deathmatch).toEqualTypeOf(); + expect(data.gungame).toBeDefined(); + expect(data.gungame).toBeInstanceOf(CopsAndCrimsGamemode); + expectTypeOf(data.gungame).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.ts new file mode 100644 index 000000000..64a0581f8 --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrims.ts @@ -0,0 +1,128 @@ +import CopsAndCrimsGamemode from './CopsAndCrimsGamemode.js'; +import CopsAndCrimsGun from './CopsAndCrimsGun.js'; +import Divide from '../../../Utils/Divide.js'; + +class CopsAndCrims { + coins: number; + kills: number; + criminalKills: number; + copKills: number; + headShotKills: number; + grenadeKills: number; + assists: number; + deaths: number; + KDR: number; + winsOnTemple: number; + winsOnCarrier: number; + winsOnAtomic: number; + winsOnAlleyway: number; + winsOnSandstorm: number; + winsOnReserve: number; + winsOnOvergrown: number; + winsOnBazaar: number; + winsOnJunction: number; + winsOnDerailed: number; + winsOnCastle: number; + winsOnRuins: number; + winsOnRiviera: number; + winsOnHarbor: number; + winsOnAtomicV1: number; + winsOnAtomicV2: number; + winsOnMelonFactory: number; + winsOnMelonFactoryV2: number; + wins: number; + gamesPlayed: number; + losses: number; + WLR: number; + roundWins: number; + bombsPlanted: number; + bombsDefused: number; + shotsFired: number; + showPrefixInLobby: boolean; + selectedLobbyPrefix: string; + lobbyPrefixColor: string; + showHints: boolean; + showKillsInPrefix: boolean; + score: number; + level: number; + activeGlyph: string; + activeScheme: string; + activeEmblem: string; + packages: string[]; + smg: CopsAndCrimsGun; + rifle: CopsAndCrimsGun; + carbine: CopsAndCrimsGun; + magnum: CopsAndCrimsGun; + shotgun: CopsAndCrimsGun; + sniper: CopsAndCrimsGun; + scopedRifle: CopsAndCrimsGun; + handgun: CopsAndCrimsGun; + autoShotgun: CopsAndCrimsGun; + bullpup: CopsAndCrimsGun; + knife: CopsAndCrimsGun; + deathmatch: CopsAndCrimsGamemode; + gungame: CopsAndCrimsGamemode; + constructor(data: Record) { + this.coins = data?.coins || 0; + this.kills = data?.kills || 0; + this.criminalKills = data?.criminal_kills || 0; + this.copKills = data?.cop_kills || 0; + this.headShotKills = data?.headshot_kills || 0; + this.grenadeKills = data?.grenade_kills || 0; + this.assists = data?.assists || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.winsOnTemple = data?.game_wins_temple || 0; + this.winsOnCarrier = data?.game_wins_carrier || 0; + this.winsOnAtomic = data?.game_wins_atomic || 0; + this.winsOnAlleyway = data?.game_wins_alleyway || 0; + this.winsOnSandstorm = data?.game_wins_sandstorm || 0; + this.winsOnReserve = data?.game_wins_reserve || 0; + this.winsOnOvergrown = data?.game_wins_overgrown || 0; + this.winsOnBazaar = data?.game_wins_bazaar || 0; + this.winsOnJunction = data?.game_wins_junction || 0; + this.winsOnDerailed = data?.game_wins_derailed || 0; + this.winsOnCastle = data?.game_wins_castle || 0; + this.winsOnRuins = data?.game_wins_ruins || 0; + this.winsOnRiviera = data?.game_wins_riviera || 0; + this.winsOnHarbor = data?.game_wins_harbor || 0; + this.winsOnAtomicV1 = data?.['game_wins_atomic v1'] || 0; + this.winsOnAtomicV2 = data?.['game_wins_atomic v2'] || 0; + this.winsOnMelonFactory = data?.['game_wins_melon factory'] || 0; + this.winsOnMelonFactoryV2 = data?.['game_wins_melon factory v2'] || 0; + this.wins = data?.game_wins || 0; + this.gamesPlayed = data?.game_plays || 0; + this.losses = this.gamesPlayed - this.wins; + this.WLR = Divide(this.wins, this.losses); + this.roundWins = data?.round_wins || 0; + this.bombsPlanted = data?.bombs_planted || 0; + this.bombsDefused = data?.bombs_defused || 0; + this.shotsFired = data?.shots_fired || 0; + this.showPrefixInLobby = data?.show_lobby_prefix || true; + this.selectedLobbyPrefix = data?.selected_lobby_prefix || ''; + this.lobbyPrefixColor = data?.lobbyPrefixColor || ''; + this.showHints = data?.setting_hints || true; + this.showKillsInPrefix = data?.show_kills_in_prefix || true; + this.score = data?.score || 0; + this.level = data?.level || 0; + this.activeGlyph = data?.active_glyph || 'None'; + this.activeScheme = data?.active_scheme || 'None'; + this.activeEmblem = data?.active_emblem || 'None'; + this.packages = data?.packages || []; + this.smg = new CopsAndCrimsGun(data, 'smg'); + this.rifle = new CopsAndCrimsGun(data, 'rifle'); + this.carbine = new CopsAndCrimsGun(data, 'carbine'); + this.magnum = new CopsAndCrimsGun(data, 'magnum'); + this.shotgun = new CopsAndCrimsGun(data, 'shotgun'); + this.sniper = new CopsAndCrimsGun(data, 'sniper'); + this.scopedRifle = new CopsAndCrimsGun(data, 'scoped_rifle'); + this.handgun = new CopsAndCrimsGun(data, 'handgun'); + this.autoShotgun = new CopsAndCrimsGun(data, 'auto_shotgun'); + this.bullpup = new CopsAndCrimsGun(data, 'bullpup'); + this.knife = new CopsAndCrimsGun(data, 'knife'); + this.deathmatch = new CopsAndCrimsGamemode(data, 'deathmatch'); + this.gungame = new CopsAndCrimsGamemode(data, 'gungame'); + } +} + +export default CopsAndCrims; diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.test.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.test.ts new file mode 100644 index 000000000..7beb3915c --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.test.ts @@ -0,0 +1,39 @@ +import CopsAndCrimsGamemode from './CopsAndCrimsGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('CopsAndCrimsGamemode', () => { + const data = new CopsAndCrimsGamemode({ stats: 'meow' }, 'deathmatch'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(CopsAndCrimsGamemode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.criminalKills).toBeDefined(); + expect(data.criminalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.criminalKills).toEqualTypeOf(); + expect(data.copKills).toBeDefined(); + expect(data.copKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.copKills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.ts new file mode 100644 index 000000000..c92a3a395 --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.ts @@ -0,0 +1,29 @@ +import Divide from '../../../Utils/Divide.js'; +import type { CopsAndCrimsGamemodes } from '../../../Types/Player.js'; + +class CopsAndCrimsGamemode { + kills: number; + criminalKills: number; + copKills: number; + assists: number; + deaths: number; + KDR: number; + wins: number; + gamesPlayed: number; + losses: number; + WLR: number; + constructor(data: Record, mode: CopsAndCrimsGamemodes) { + this.kills = data?.[`kills_${mode}`] || 0; + this.criminalKills = data?.[`criminal_kills_${mode}`] || 0; + this.copKills = data?.[`cop_kills_${mode}`] || 0; + this.assists = data?.[`assists_${mode}`] || 0; + this.deaths = data?.[`deaths_${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`game_wins_${mode}`] || 0; + this.gamesPlayed = data?.[`game_plays_${mode}`] || 0; + this.losses = this.gamesPlayed - this.wins; + this.WLR = Divide(this.wins, this.losses); + } +} + +export default CopsAndCrimsGamemode; diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.test.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.test.ts new file mode 100644 index 000000000..2636c957d --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.test.ts @@ -0,0 +1,30 @@ +import CopsAndCrimsGun from './CopsAndCrimsGun.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CopsAndCrimsGuns } from '../../../Types/Player.js'; + +test('CopsAndCrimsGun', () => { + const data = new CopsAndCrimsGun({ stats: 'meow' }, 'auto_shotgun'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(CopsAndCrimsGun); + expectTypeOf(data).toEqualTypeOf(); + expect(data.gunName).toBeDefined(); + expectTypeOf(data.gunName).toEqualTypeOf(); + expect(data.damageIncrease).toBeDefined(); + expect(data.damageIncrease).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageIncrease).toEqualTypeOf(); + expect(data.recoilReduction).toBeDefined(); + expect(data.recoilReduction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.recoilReduction).toEqualTypeOf(); + expect(data.reloadSpeedReduction).toBeDefined(); + expect(data.reloadSpeedReduction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.reloadSpeedReduction).toEqualTypeOf(); + expect(data.costReduction).toBeDefined(); + expect(data.costReduction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.costReduction).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.headShots).toBeDefined(); + expect(data.headShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headShots).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.ts b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.ts new file mode 100644 index 000000000..686255cd4 --- /dev/null +++ b/src/Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.ts @@ -0,0 +1,22 @@ +import type { CopsAndCrimsGuns } from '../../../Types/Player.js'; + +class CopsAndCrimsGun { + gunName: CopsAndCrimsGuns; + damageIncrease: number; + recoilReduction: number; + reloadSpeedReduction: number; + costReduction: number; + kills: number; + headShots: number; + constructor(data: Record, gunName: CopsAndCrimsGuns) { + this.gunName = gunName; + this.damageIncrease = data?.[`${gunName}_damage_increase`] || 0; + this.recoilReduction = data?.[`${gunName}_recoil_reduction`] || 0; + this.reloadSpeedReduction = data?.[`${gunName}_reload_speed_reduction`] || 0; + this.costReduction = data?.[`${gunName}_cost_reduction`] || 0; + this.kills = data?.[`${gunName}Kills`] || data?.[`${gunName}_kills`] || 0; + this.headShots = data?.[`${gunName}Headshots`] || 0; + } +} + +export default CopsAndCrimsGun; diff --git a/src/Structures/MiniGames/Duels/Duels.test.ts b/src/Structures/MiniGames/Duels/Duels.test.ts new file mode 100644 index 000000000..c9cab0797 --- /dev/null +++ b/src/Structures/MiniGames/Duels/Duels.test.ts @@ -0,0 +1,119 @@ +import Duels from './Duels.js'; +import DuelsBridge from './DuelsBridge.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsMegaWalls from './DuelsMegaWalls.js'; +import DuelsOP from './DuelsOP.js'; +import DuelsSkyWars from './DuelsSkyWars.js'; +import DuelsUHC from './DuelsUHC.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Duels', () => { + const data = new Duels({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Duels); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.ping).toBeDefined(); + expect(data.ping).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ping).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); + expect(data.uhc).toBeDefined(); + expect(data.uhc).toBeInstanceOf(DuelsUHC); + expectTypeOf(data.uhc).toEqualTypeOf(); + expect(data.skywars).toBeDefined(); + expect(data.skywars).toBeInstanceOf(DuelsSkyWars); + expectTypeOf(data.skywars).toEqualTypeOf(); + expect(data.megawalls).toBeDefined(); + expect(data.megawalls).toBeInstanceOf(DuelsMegaWalls); + expectTypeOf(data.megawalls).toEqualTypeOf(); + expect(data.blitz).toBeDefined(); + expect(data.blitz).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.blitz).toEqualTypeOf(); + expect(data.op).toBeDefined(); + expect(data.op).toBeInstanceOf(DuelsOP); + expectTypeOf(data.op).toEqualTypeOf(); + expect(data.classic).toBeDefined(); + expect(data.classic).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.classic).toEqualTypeOf(); + expect(data.bow).toBeDefined(); + expect(data.bow).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.bow).toEqualTypeOf(); + expect(data.noDebuff).toBeDefined(); + expect(data.noDebuff).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.noDebuff).toEqualTypeOf(); + expect(data.combo).toBeDefined(); + expect(data.combo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.combo).toEqualTypeOf(); + expect(data.bowSpleef).toBeDefined(); + expect(data.bowSpleef).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.bowSpleef).toEqualTypeOf(); + expect(data.sumo).toBeDefined(); + expect(data.sumo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.sumo).toEqualTypeOf(); + expect(data.bridge).toBeDefined(); + expect(data.bridge).toBeInstanceOf(DuelsBridge); + expectTypeOf(data.bridge).toEqualTypeOf(); + expect(data.parkour).toBeDefined(); + expect(data.parkour).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.parkour).toEqualTypeOf(); + expect(data.arena).toBeDefined(); + expect(data.arena).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.arena).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/Duels.ts b/src/Structures/MiniGames/Duels/Duels.ts new file mode 100644 index 000000000..7a737c3a2 --- /dev/null +++ b/src/Structures/MiniGames/Duels/Duels.ts @@ -0,0 +1,95 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsBridge from './DuelsBridge.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsMegaWalls from './DuelsMegaWalls.js'; +import DuelsOP from './DuelsOP.js'; +import DuelsSkyWars from './DuelsSkyWars.js'; +import DuelsUHC from './DuelsUHC.js'; +import Romanize from '../../../Utils/Romanize.js'; +import { duelsDivisions } from '../../../Utils/Constants.js'; +import type { DuelsModes } from '../../../Types/Player.js'; + +export function getTitle(data: Record, mode: 'all_modes' | DuelsModes): string { + for (const div of duelsDivisions.slice().reverse()) { + const prestige = data?.[`${mode}_${div.key}_title_prestige`]; + if (prestige) return `${div.name} ${Romanize(prestige)}`; + } + return ''; +} + +class Duels { + tokens: number; + title: string | null; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + winStreak: number; + bestWinStreak: number; + ping: number; + blocksPlaced: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + healthRegenerated: number; + goldenApplesEaten: number; + uhc: DuelsUHC; + skywars: DuelsSkyWars; + megawalls: DuelsMegaWalls; + blitz: DuelsGamemode; + op: DuelsOP; + classic: DuelsGamemode; + bow: DuelsGamemode; + noDebuff: DuelsGamemode; + combo: DuelsGamemode; + bowSpleef: DuelsGamemode; + sumo: DuelsGamemode; + bridge: DuelsBridge; + parkour: DuelsGamemode; + arena: DuelsGamemode; + constructor(data: Record) { + this.tokens = data?.coins || data?.tokens || 0; + this.title = getTitle(data, 'all_modes'); + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = data?.games_played_duels || 0; + this.winStreak = data?.current_winstreak || 0; + this.bestWinStreak = data?.best_overall_winstreak || 0; + this.ping = data?.pingPreference || 0; + this.blocksPlaced = data?.blocks_placed || 0; + this.swings = data?.melee_swings || 0; + this.hits = data?.melee_hits || 0; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = data?.bow_shots || 0; + this.bowHits = data?.bow_hits || 0; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.healthRegenerated = data?.health_regenerated || 0; + this.goldenApplesEaten = data?.golden_apples_eaten || 0; + this.uhc = new DuelsUHC(data); + this.skywars = new DuelsSkyWars(data); + this.megawalls = new DuelsMegaWalls(data); + this.blitz = new DuelsGamemode(data, 'blitz_duel', getTitle(data, 'blitz')); + this.op = new DuelsOP(data); + this.classic = new DuelsGamemode(data, 'classic_duel', getTitle(data, 'classic')); + this.bow = new DuelsGamemode(data, 'bow_duel', getTitle(data, 'bow')); + this.noDebuff = new DuelsGamemode(data, 'potion_duel', getTitle(data, 'no_debuff')); + this.combo = new DuelsGamemode(data, 'combo_duel', getTitle(data, 'combo')); + this.bowSpleef = new DuelsGamemode(data, 'bowspleef_duel', getTitle(data, 'tnt_games')); + this.sumo = new DuelsGamemode(data, 'sumo_duel', getTitle(data, 'sumo')); + this.bridge = new DuelsBridge(data); + this.parkour = new DuelsGamemode(data, 'parkour_eight', getTitle(data, 'parkour')); + this.arena = new DuelsGamemode(data, 'duel_arena'); + } +} + +export default Duels; diff --git a/src/Structures/MiniGames/Duels/DuelsBridge.test.ts b/src/Structures/MiniGames/Duels/DuelsBridge.test.ts new file mode 100644 index 000000000..a005ba221 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsBridge.test.ts @@ -0,0 +1,87 @@ +import DuelsBridge from './DuelsBridge.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsBridge', () => { + const data = new DuelsBridge({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsBridge); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.threes).toBeDefined(); + expect(data.threes).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.threes).toEqualTypeOf(); + expect(data.fours).toBeDefined(); + expect(data.fours).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.fours).toEqualTypeOf(); + expect(data['2v2v2v2']).toBeDefined(); + expect(data['2v2v2v2']).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data['2v2v2v2']).toEqualTypeOf(); + expect(data['3v3v3v3']).toBeDefined(); + expect(data['3v3v3v3']).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data['3v3v3v3']).toEqualTypeOf(); + expect(data.ctf).toBeDefined(); + expect(data.ctf).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.ctf).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsBridge.ts b/src/Structures/MiniGames/Duels/DuelsBridge.ts new file mode 100644 index 000000000..d911fd32e --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsBridge.ts @@ -0,0 +1,146 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { getTitle } from './Duels.js'; + +class DuelsBridge { + title: string; + winStreak: number; + bestWinStreak: number; + solo: DuelsGamemode; + doubles: DuelsGamemode; + threes: DuelsGamemode; + fours: DuelsGamemode; + '2v2v2v2': DuelsGamemode; + '3v3v3v3': DuelsGamemode; + ctf: DuelsGamemode; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record) { + this.title = getTitle(data, 'bridge'); + this.winStreak = data?.current_bridge_winstreak || 0; + this.bestWinStreak = data?.best_bridge_winstreak || 0; + this.solo = new DuelsGamemode(data, 'bridge_duel', this.title); + this.doubles = new DuelsGamemode(data, 'bridge_doubles', this.title); + this.threes = new DuelsGamemode(data, 'bridge_threes', this.title); + this.fours = new DuelsGamemode(data, 'bridge_fours', this.title); + this['2v2v2v2'] = new DuelsGamemode(data, '2v2v2v2', this.title); + this['3v3v3v3'] = new DuelsGamemode(data, '3v3v3v3', this.title); + this.ctf = new DuelsGamemode(data, 'capture_threes', this.title); + this.kills = + this.solo.kills + + this.doubles.kills + + this.threes.kills + + this.fours.kills + + this['2v2v2v2'].kills + + this['3v3v3v3'].kills + + this.ctf.kills; + this.deaths = + this.solo.deaths + + this.doubles.deaths + + this.threes.deaths + + this.fours.deaths + + this['2v2v2v2'].deaths + + this['3v3v3v3'].deaths + + this.ctf.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = + this.solo.wins + + this.doubles.wins + + this.threes.wins + + this.fours.wins + + this['2v2v2v2'].wins + + this['3v3v3v3'].wins + + this.ctf.wins; + this.losses = + this.solo.losses + + this.doubles.losses + + this.threes.losses + + this.fours.losses + + this['2v2v2v2'].losses + + this['3v3v3v3'].losses + + this.ctf.losses; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = + this.solo.playedGames + + this.doubles.playedGames + + this.threes.playedGames + + this.fours.playedGames + + this['2v2v2v2'].playedGames + + this['3v3v3v3'].playedGames + + this.ctf.playedGames; + this.swings = + this.solo.swings + + this.doubles.swings + + this.threes.swings + + this.fours.swings + + this['2v2v2v2'].swings + + this['3v3v3v3'].swings + + this.ctf.swings; + this.hits = + this.solo.hits + + this.doubles.hits + + this.threes.hits + + this.fours.hits + + this['2v2v2v2'].hits + + this['3v3v3v3'].hits + + this.ctf.hits; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = + this.solo.bowShots + + this.doubles.bowShots + + this.threes?.bowShots + + this.fours?.bowShots + + this['2v2v2v2'].bowShots + + this['3v3v3v3'].bowShots + + this.ctf.bowShots; + this.bowHits = + this.solo.bowHits + + this.doubles.bowHits + + this.threes.bowHits + + this.fours.bowHits + + this['2v2v2v2'].bowHits + + this['3v3v3v3'].bowHits + + this.ctf.bowHits; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.blocksPlaced = + this.solo.blocksPlaced + + this.doubles.blocksPlaced + + this.threes.blocksPlaced + + this.fours.blocksPlaced + + this['2v2v2v2'].blocksPlaced + + this['3v3v3v3'].blocksPlaced + + this.ctf.blocksPlaced; + this.healthRegenerated = + this.solo.healthRegenerated + + this.doubles.healthRegenerated + + this.threes.healthRegenerated + + this.fours.healthRegenerated + + this['2v2v2v2'].healthRegenerated + + this['3v3v3v3'].healthRegenerated + + this.ctf.healthRegenerated; + this.goldenApplesEaten = + this.solo.goldenApplesEaten + + this.doubles.goldenApplesEaten + + this.threes.goldenApplesEaten + + this.fours.goldenApplesEaten + + this['2v2v2v2'].goldenApplesEaten + + this['3v3v3v3'].goldenApplesEaten + + this.ctf.goldenApplesEaten; + } +} + +export default DuelsBridge; diff --git a/src/Structures/MiniGames/Duels/DuelsGamemode.test.ts b/src/Structures/MiniGames/Duels/DuelsGamemode.test.ts new file mode 100644 index 000000000..4461a879e --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsGamemode.test.ts @@ -0,0 +1,65 @@ +import DuelsGamemode from './DuelsGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsGamemode', () => { + const data = new DuelsGamemode({ stats: 'meow' }, '2v2v2v2'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsGamemode.ts b/src/Structures/MiniGames/Duels/DuelsGamemode.ts new file mode 100644 index 000000000..3eb797829 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsGamemode.ts @@ -0,0 +1,47 @@ +import Divide from '../../../Utils/Divide.js'; +import type { DuelsModes } from '../../../Types/Player.js'; + +class DuelsGamemode { + title: string; + winStreak: number; + bestWinStreak: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record, mode: DuelsModes, title: string = '') { + this.title = title; + this.winStreak = data?.[`current_winstreak_mode_${mode}`] || 0; + this.bestWinStreak = data?.[`best_winstreak_mode_${mode}`] || 0; + this.kills = data?.[`${mode}_kills`] || 0; + this.deaths = data?.[`${mode}_deaths`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`${mode}_wins`] || 0; + this.losses = data?.[`${mode}_losses`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = data?.[`${mode}_rounds_played`] || 0; + this.swings = data?.[`${mode}_melee_swings`] || 0; + this.hits = data?.[`${mode}_melee_hits`] || 0; + this.meleeAccuracy = Divide(this.swings, this.hits); + this.bowShots = data?.[`${mode}_bow_shots`] || 0; + this.bowHits = data?.[`${mode}_bow_hits`] || 0; + this.bowAccuracy = Divide(this.bowShots, this.bowHits); + this.blocksPlaced = data?.[`${mode}_blocks_placed`] || 0; + this.healthRegenerated = data?.[`${mode}_health_regenerated`] || 0; + this.goldenApplesEaten = data?.[`${mode}_golden_apples_eaten`] || 0; + } +} + +export default DuelsGamemode; diff --git a/src/Structures/MiniGames/Duels/DuelsMegaWalls.test.ts b/src/Structures/MiniGames/Duels/DuelsMegaWalls.test.ts new file mode 100644 index 000000000..e69b88811 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsMegaWalls.test.ts @@ -0,0 +1,72 @@ +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsMegaWalls from './DuelsMegaWalls.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsMegaWalls', () => { + const data = new DuelsMegaWalls({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsMegaWalls); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsMegaWalls.ts b/src/Structures/MiniGames/Duels/DuelsMegaWalls.ts new file mode 100644 index 000000000..c05350615 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsMegaWalls.ts @@ -0,0 +1,52 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { getTitle } from './Duels.js'; + +class DuelsMegaWalls { + title: string; + winStreak: number; + bestWinStreak: number; + solo: DuelsGamemode; + doubles: DuelsGamemode; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record) { + this.title = getTitle(data, 'mega_walls'); + this.winStreak = data?.current_mega_walls_winstreak || 0; + this.bestWinStreak = data?.best_mega_walls_winstreak || 0; + this.solo = new DuelsGamemode(data, 'mw_duel', this.title); + this.doubles = new DuelsGamemode(data, 'mw_doubles', this.title); + this.kills = this.solo.kills + this.doubles.kills; + this.deaths = this.solo.deaths + this.doubles.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = this.solo.wins + this.doubles.wins; + this.losses = this.solo.losses + this.doubles.losses; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = this.solo.playedGames + this.doubles.playedGames; + this.swings = this.solo.swings + this.doubles.swings; + this.hits = this.solo.hits + this.doubles.hits; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = this.solo.bowShots + this.doubles.bowShots; + this.bowHits = this.solo.bowHits + this.doubles.bowHits; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; + this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; + this.goldenApplesEaten = this.solo.goldenApplesEaten + this.doubles.goldenApplesEaten; + } +} + +export default DuelsMegaWalls; diff --git a/src/Structures/MiniGames/Duels/DuelsOP.test.ts b/src/Structures/MiniGames/Duels/DuelsOP.test.ts new file mode 100644 index 000000000..0d6523adc --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsOP.test.ts @@ -0,0 +1,72 @@ +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsOP from './DuelsOP.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsOP', () => { + const data = new DuelsOP({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsOP); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsOP.ts b/src/Structures/MiniGames/Duels/DuelsOP.ts new file mode 100644 index 000000000..9198c4fde --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsOP.ts @@ -0,0 +1,52 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { getTitle } from './Duels.js'; + +class DuelsOP { + title: string; + winStreak: number; + bestWinStreak: number; + solo: DuelsGamemode; + doubles: DuelsGamemode; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record) { + this.title = getTitle(data, 'op'); + this.winStreak = data?.current_op_winstreak || 0; + this.bestWinStreak = data?.best_op_winstreak || 0; + this.solo = new DuelsGamemode(data, 'op_duel', this.title); + this.doubles = new DuelsGamemode(data, 'op_doubles', this.title); + this.kills = this.solo.kills + this.doubles.kills; + this.deaths = this.solo.deaths + this.doubles.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = this.solo.wins + this.doubles.wins; + this.losses = this.solo.losses + this.doubles.losses; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = this.solo.playedGames + this.doubles.playedGames; + this.swings = this.solo.swings + this.doubles.swings; + this.hits = this.solo.hits + this.doubles.hits; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = this.solo.bowShots + this.doubles.bowShots; + this.bowHits = this.solo.bowHits + this.doubles.bowHits; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; + this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; + this.goldenApplesEaten = this.solo.goldenApplesEaten + this.doubles.goldenApplesEaten; + } +} + +export default DuelsOP; diff --git a/src/Structures/MiniGames/Duels/DuelsSkyWars.test.ts b/src/Structures/MiniGames/Duels/DuelsSkyWars.test.ts new file mode 100644 index 000000000..db1260fda --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsSkyWars.test.ts @@ -0,0 +1,72 @@ +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsSkyWars from './DuelsSkyWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsSkyWars', () => { + const data = new DuelsSkyWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsSkyWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsSkyWars.ts b/src/Structures/MiniGames/Duels/DuelsSkyWars.ts new file mode 100644 index 000000000..82bf6be9d --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsSkyWars.ts @@ -0,0 +1,52 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { getTitle } from './Duels.js'; + +class DuelsSkyWars { + title: string; + winStreak: number; + bestWinStreak: number; + solo: DuelsGamemode; + doubles: DuelsGamemode; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record) { + this.title = getTitle(data, 'sw'); + this.winStreak = data?.current_sw_winstreak || 0; + this.bestWinStreak = data?.best_sw_winstreak || 0; + this.solo = new DuelsGamemode(data, 'sw_duel', this.title); + this.doubles = new DuelsGamemode(data, 'sw_doubles', this.title); + this.kills = this.solo.kills + this.doubles.kills; + this.deaths = this.solo.deaths + this.doubles.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = this.solo.wins + this.doubles.wins; + this.losses = this.solo.losses + this.doubles.losses; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = this.solo.playedGames + this.doubles.playedGames; + this.swings = this.solo.swings + this.doubles.swings; + this.hits = this.solo.hits + this.doubles.hits; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = this.solo.bowShots + this.doubles.bowShots; + this.bowHits = this.solo.bowHits + this.doubles.bowHits; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; + this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; + this.goldenApplesEaten = this.solo.goldenApplesEaten + this.doubles.goldenApplesEaten; + } +} + +export default DuelsSkyWars; diff --git a/src/Structures/MiniGames/Duels/DuelsUHC.test.ts b/src/Structures/MiniGames/Duels/DuelsUHC.test.ts new file mode 100644 index 000000000..7fcd1c565 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsUHC.test.ts @@ -0,0 +1,78 @@ +import DuelsGamemode from './DuelsGamemode.js'; +import DuelsUHC from './DuelsUHC.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('DuelsUHC', () => { + const data = new DuelsUHC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(DuelsUHC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.bestWinStreak).toBeDefined(); + expect(data.bestWinStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestWinStreak).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.fours).toBeDefined(); + expect(data.fours).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.fours).toEqualTypeOf(); + expect(data.deathmatch).toBeDefined(); + expect(data.deathmatch).toBeInstanceOf(DuelsGamemode); + expectTypeOf(data.deathmatch).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.swings).toBeDefined(); + expect(data.swings).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swings).toEqualTypeOf(); + expect(data.hits).toBeDefined(); + expect(data.hits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hits).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.bowShots).toBeDefined(); + expect(data.bowShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowShots).toEqualTypeOf(); + expect(data.bowHits).toBeDefined(); + expect(data.bowHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowHits).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.healthRegenerated).toBeDefined(); + expect(data.healthRegenerated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.healthRegenerated).toEqualTypeOf(); + expect(data.goldenApplesEaten).toBeDefined(); + expect(data.goldenApplesEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenApplesEaten).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Duels/DuelsUHC.ts b/src/Structures/MiniGames/Duels/DuelsUHC.ts new file mode 100644 index 000000000..133ae2808 --- /dev/null +++ b/src/Structures/MiniGames/Duels/DuelsUHC.ts @@ -0,0 +1,66 @@ +import Divide from '../../../Utils/Divide.js'; +import DuelsGamemode from './DuelsGamemode.js'; +import { getTitle } from './Duels.js'; + +class DuelsUHC { + title: string; + winStreak: number; + bestWinStreak: number; + solo: DuelsGamemode; + doubles: DuelsGamemode; + fours: DuelsGamemode; + deathmatch: DuelsGamemode; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + swings: number; + hits: number; + meleeAccuracy: number; + bowShots: number; + bowHits: number; + bowAccuracy: number; + blocksPlaced: number; + healthRegenerated: number; + goldenApplesEaten: number; + constructor(data: Record) { + this.title = getTitle(data, 'uhc'); + this.winStreak = data?.current_uhc_winstreak || 0; + this.bestWinStreak = data?.best_uhc_winstreak || 0; + this.solo = new DuelsGamemode(data, 'uhc_duel', this.title); + this.doubles = new DuelsGamemode(data, 'uhc_doubles', this.title); + this.fours = new DuelsGamemode(data, 'uhc_four', this.title); + this.deathmatch = new DuelsGamemode(data, 'uhc_meetup', this.title); + this.kills = this.solo.kills + this.doubles.kills + this.fours.kills + this.deathmatch.kills; + this.deaths = this.solo.deaths + this.doubles.deaths + this.fours.deaths + this.deathmatch.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = this.solo.wins + this.doubles.wins + this.fours.wins + this.deathmatch.wins; + this.losses = this.solo.losses + this.doubles.losses + this.fours.losses + this.deathmatch.losses; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = + this.solo.playedGames + this.doubles.playedGames + this.fours.playedGames + this.deathmatch.playedGames; + this.swings = this.solo.swings + this.doubles.swings + this.fours.swings + this.deathmatch.swings; + this.hits = this.solo.hits + this.doubles.hits + this.fours.hits + this.deathmatch.hits; + this.meleeAccuracy = Divide(this.hits, this.swings); + this.bowShots = this.solo.bowShots + this.doubles.bowShots + this.fours.bowShots + this.deathmatch.bowShots; + this.bowHits = this.solo.bowHits + this.doubles.bowHits + this.fours.bowHits + this.deathmatch.bowHits; + this.bowAccuracy = Divide(this.bowHits, this.bowShots); + this.blocksPlaced = + this.solo.blocksPlaced + this.doubles.blocksPlaced + this.fours.blocksPlaced + this.deathmatch.blocksPlaced; + this.healthRegenerated = + this.solo.healthRegenerated + + this.doubles.healthRegenerated + + this.fours.healthRegenerated + + this.deathmatch.healthRegenerated; + this.goldenApplesEaten = + this.solo.goldenApplesEaten + + this.doubles.goldenApplesEaten + + this.fours.goldenApplesEaten + + this.deathmatch.goldenApplesEaten; + } +} + +export default DuelsUHC; diff --git a/src/Structures/MiniGames/MegaWalls/MegaWalls.test.ts b/src/Structures/MiniGames/MegaWalls/MegaWalls.test.ts new file mode 100644 index 000000000..b920ef1dc --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWalls.test.ts @@ -0,0 +1,158 @@ +import MegaWalls from './MegaWalls.js'; +import MegaWallsKitStats from './MegaWallsKitStats.js'; +import MegaWallsModeStats from './MegaWallsModeStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { MegaWallsKits } from '../../../Types/Player.js'; + +test('MegaWalls', () => { + const data = new MegaWalls({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MegaWalls); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selectedClass).toBeDefined(); + expectTypeOf(data.selectedClass).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.finalKills).toBeDefined(); + expect(data.finalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalKills).toEqualTypeOf(); + expect(data.finalAssists).toBeDefined(); + expect(data.finalAssists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalAssists).toEqualTypeOf(); + expect(data.finalDeaths).toBeDefined(); + expect(data.finalDeaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalDeaths).toEqualTypeOf(); + expect(data.FKDR).toBeDefined(); + expect(data.FKDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.FKDR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.witherDamage).toBeDefined(); + expect(data.witherDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherDamage).toEqualTypeOf(); + expect(data.defenderKills).toBeDefined(); + expect(data.defenderKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.defenderKills).toEqualTypeOf(); + expect(data.walked).toBeDefined(); + expect(data.walked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.walked).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.meleeKills).toBeDefined(); + expect(data.meleeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeKills).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); + expect(data.faceOff).toBeDefined(); + expect(data.faceOff).toBeInstanceOf(MegaWallsModeStats); + expectTypeOf(data.faceOff).toEqualTypeOf(); + expect(data.casualBrawl).toBeDefined(); + expect(data.casualBrawl).toBeInstanceOf(MegaWallsModeStats); + expectTypeOf(data.casualBrawl).toEqualTypeOf(); + expect(data.cow).toBeDefined(); + expect(data.cow).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.cow).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.shark).toBeDefined(); + expect(data.shark).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.shark).toEqualTypeOf(); + expect(data.arcanist).toBeDefined(); + expect(data.arcanist).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.arcanist).toEqualTypeOf(); + expect(data.deadlord).toBeDefined(); + expect(data.deadlord).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.deadlord).toEqualTypeOf(); + expect(data.golem).toBeDefined(); + expect(data.golem).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.golem).toEqualTypeOf(); + expect(data.herobrine).toBeDefined(); + expect(data.herobrine).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.herobrine).toEqualTypeOf(); + expect(data.pigman).toBeDefined(); + expect(data.pigman).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.pigman).toEqualTypeOf(); + expect(data.zombie).toBeDefined(); + expect(data.zombie).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.zombie).toEqualTypeOf(); + expect(data.blaze).toBeDefined(); + expect(data.blaze).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.blaze).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.shaman).toBeDefined(); + expect(data.shaman).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.shaman).toEqualTypeOf(); + expect(data.squid).toBeDefined(); + expect(data.squid).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.squid).toEqualTypeOf(); + expect(data.creeper).toBeDefined(); + expect(data.creeper).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.creeper).toEqualTypeOf(); + expect(data.pirate).toBeDefined(); + expect(data.pirate).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.pirate).toEqualTypeOf(); + expect(data.sheep).toBeDefined(); + expect(data.sheep).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.sheep).toEqualTypeOf(); + expect(data.skeleton).toBeDefined(); + expect(data.skeleton).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.skeleton).toEqualTypeOf(); + expect(data.spider).toBeDefined(); + expect(data.spider).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.spider).toEqualTypeOf(); + expect(data.werewolf).toBeDefined(); + expect(data.werewolf).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.werewolf).toEqualTypeOf(); + expect(data.angel).toBeDefined(); + expect(data.angel).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.angel).toEqualTypeOf(); + expect(data.assassin).toBeDefined(); + expect(data.assassin).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.assassin).toEqualTypeOf(); + expect(data.automaton).toBeDefined(); + expect(data.automaton).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.automaton).toEqualTypeOf(); + expect(data.moleman).toBeDefined(); + expect(data.moleman).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.moleman).toEqualTypeOf(); + expect(data.phoenix).toBeDefined(); + expect(data.phoenix).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.phoenix).toEqualTypeOf(); + expect(data.renegade).toBeDefined(); + expect(data.renegade).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.renegade).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data.snowman).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MegaWalls/MegaWalls.ts b/src/Structures/MiniGames/MegaWalls/MegaWalls.ts new file mode 100644 index 000000000..cd206ec64 --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWalls.ts @@ -0,0 +1,109 @@ +import Divide from '../../../Utils/Divide.js'; +import MegaWallsKitStats from './MegaWallsKitStats.js'; +import MegaWallsModeStats from './MegaWallsModeStats.js'; +import type { MegaWallsKits } from '../../../Types/Player.js'; + +class MegaWalls { + selectedClass: MegaWallsKits | 'None'; + coins: number; + kills: number; + assists: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + finalKills: number; + finalAssists: number; + finalDeaths: number; + FKDR: number; + playedGames: number; + witherDamage: number; + defenderKills: number; + walked: number; + blocksPlaced: number; + blocksBroken: number; + meleeKills: number; + damageDealt: number; + faceOff: MegaWallsModeStats; + casualBrawl: MegaWallsModeStats; + cow: MegaWallsKitStats; + hunter: MegaWallsKitStats; + shark: MegaWallsKitStats; + arcanist: MegaWallsKitStats; + deadlord: MegaWallsKitStats; + golem: MegaWallsKitStats; + herobrine: MegaWallsKitStats; + pigman: MegaWallsKitStats; + zombie: MegaWallsKitStats; + blaze: MegaWallsKitStats; + enderman: MegaWallsKitStats; + shaman: MegaWallsKitStats; + squid: MegaWallsKitStats; + creeper: MegaWallsKitStats; + pirate: MegaWallsKitStats; + sheep: MegaWallsKitStats; + skeleton: MegaWallsKitStats; + spider: MegaWallsKitStats; + werewolf: MegaWallsKitStats; + angel: MegaWallsKitStats; + assassin: MegaWallsKitStats; + automaton: MegaWallsKitStats; + moleman: MegaWallsKitStats; + phoenix: MegaWallsKitStats; + renegade: MegaWallsKitStats; + snowman: MegaWallsKitStats; + constructor(data: Record) { + this.selectedClass = data?.chosen_class || 'None'; + this.coins = data?.coins || data?.tokens || 0; + this.kills = data?.kills || 0; + this.assists = data?.assists || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.finalKills = (data?.final_kills || 0) + (data?.finalkills || 0); + this.finalAssists = (data?.final_assists || 0) + (data?.finalassists || 0); + this.finalDeaths = (data?.final_deaths || 0) + (data?.finalDeaths || 0); + this.FKDR = Divide(this.finalKills, this.finalDeaths); + this.playedGames = data?.games_played || 0; + this.witherDamage = (data?.wither_damage || 0) + (data?.witherDamager || 0); + this.defenderKills = data?.defender_kills || 0; + this.walked = data?.meters_walked || 0; + this.blocksPlaced = data?.blocks_placed || 0; + this.blocksBroken = data?.blocks_broken || 0; + this.meleeKills = data?.kills_melee || 0; + this.damageDealt = data?.damage_dealt || 0; + this.faceOff = new MegaWallsModeStats(data, 'face_off'); + this.casualBrawl = new MegaWallsModeStats(data, 'gvg'); + this.cow = new MegaWallsKitStats(data, 'cow'); + this.hunter = new MegaWallsKitStats(data, 'hunter'); + this.shark = new MegaWallsKitStats(data, 'shark'); + this.arcanist = new MegaWallsKitStats(data, 'arcanist'); + this.deadlord = new MegaWallsKitStats(data, 'deadlord'); + this.golem = new MegaWallsKitStats(data, 'golem'); + this.herobrine = new MegaWallsKitStats(data, 'herobrine'); + this.pigman = new MegaWallsKitStats(data, 'pigman'); + this.zombie = new MegaWallsKitStats(data, 'zombie'); + this.blaze = new MegaWallsKitStats(data, 'blaze'); + this.enderman = new MegaWallsKitStats(data, 'enderman'); + this.shaman = new MegaWallsKitStats(data, 'shaman'); + this.squid = new MegaWallsKitStats(data, 'squid'); + this.creeper = new MegaWallsKitStats(data, 'creeper'); + this.pirate = new MegaWallsKitStats(data, 'pirate'); + this.sheep = new MegaWallsKitStats(data, 'sheep'); + this.skeleton = new MegaWallsKitStats(data, 'skeleton'); + this.spider = new MegaWallsKitStats(data, 'spider'); + this.werewolf = new MegaWallsKitStats(data, 'werewolf'); + this.angel = new MegaWallsKitStats(data, 'angel'); + this.assassin = new MegaWallsKitStats(data, 'assassin'); + this.automaton = new MegaWallsKitStats(data, 'automaton'); + this.moleman = new MegaWallsKitStats(data, 'moleman'); + this.phoenix = new MegaWallsKitStats(data, 'phoenix'); + this.renegade = new MegaWallsKitStats(data, 'renegade'); + this.snowman = new MegaWallsKitStats(data, 'snowman'); + } +} + +export default MegaWalls; diff --git a/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.test.ts b/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.test.ts new file mode 100644 index 000000000..20743c3f4 --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.test.ts @@ -0,0 +1,73 @@ +import MegaWallsKitStats from './MegaWallsKitStats.js'; +import MegaWallsModeStats from './MegaWallsModeStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MegaWallsKitStats', () => { + const data = new MegaWallsKitStats({ stats: 'meow' }, 'angel'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MegaWallsKitStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.finalKills).toBeDefined(); + expect(data.finalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalKills).toEqualTypeOf(); + expect(data.finalAssists).toBeDefined(); + expect(data.finalAssists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalAssists).toEqualTypeOf(); + expect(data.finalDeaths).toBeDefined(); + expect(data.finalDeaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalDeaths).toEqualTypeOf(); + expect(data.FKDR).toBeDefined(); + expect(data.FKDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.FKDR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.witherDamage).toBeDefined(); + expect(data.witherDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherDamage).toEqualTypeOf(); + expect(data.defenderKills).toBeDefined(); + expect(data.defenderKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.defenderKills).toEqualTypeOf(); + expect(data.walked).toBeDefined(); + expect(data.walked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.walked).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.meleeKills).toBeDefined(); + expect(data.meleeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeKills).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); + expect(data.faceOff).toBeDefined(); + expect(data.faceOff).toBeInstanceOf(MegaWallsModeStats); + expectTypeOf(data.faceOff).toEqualTypeOf(); + expect(data.casualBrawl).toBeDefined(); + expect(data.casualBrawl).toBeInstanceOf(MegaWallsModeStats); + expectTypeOf(data.casualBrawl).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.ts b/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.ts new file mode 100644 index 000000000..d611ea8f1 --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWallsKitStats.ts @@ -0,0 +1,52 @@ +import Divide from '../../../Utils/Divide.js'; +import MegaWallsModeStats from './MegaWallsModeStats.js'; +import type { MegaWallsKits } from '../../../Types/Player.js'; + +class MegaWallsKitStats { + kills: number; + assists: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + finalKills: number; + finalAssists: number; + finalDeaths: number; + FKDR: number; + playedGames: number; + witherDamage: number; + defenderKills: number; + walked: number; + blocksPlaced: number; + blocksBroken: number; + meleeKills: number; + damageDealt: number; + faceOff: MegaWallsModeStats; + casualBrawl: MegaWallsModeStats; + constructor(data: Record, kit: MegaWallsKits) { + this.kills = data?.[`${kit}_kills`] || 0; + this.assists = data?.[`${kit}_assists`] || 0; + this.deaths = data?.[`${kit}_deaths`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`${kit}_wins`] || 0; + this.losses = data?.[`${kit}_losses`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.finalKills = data?.[`${kit}_final_kills`] || 0; + this.finalAssists = data?.[`${kit}_final_assists`] || 0; + this.finalDeaths = data?.[`${kit}_final_deaths`] || 0; + this.FKDR = Divide(this.finalKills, this.finalDeaths); + this.playedGames = data?.[`${kit}_games_played`] || 0; + this.witherDamage = data?.[`${kit}_wither_damage`] || 0; + this.defenderKills = data?.[`${kit}_defender_kills`] || 0; + this.walked = data?.[`${kit}_meters_walked`] || 0; + this.blocksPlaced = data?.[`${kit}_blocks_placed`] || 0; + this.blocksBroken = data?.[`${kit}_blocks_broken`] || 0; + this.meleeKills = data?.[`${kit}_kills_melee`] || 0; + this.damageDealt = data?.[`${kit}_damage_dealt`] || 0; + this.faceOff = new MegaWallsModeStats(data, 'face_off', kit); + this.casualBrawl = new MegaWallsModeStats(data, 'gvg', kit); + } +} + +export default MegaWallsKitStats; diff --git a/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.test.ts b/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.test.ts new file mode 100644 index 000000000..340a0e0f7 --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.test.ts @@ -0,0 +1,66 @@ +import MegaWallsModeStats from './MegaWallsModeStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MegaWallsModeStats', () => { + const data = new MegaWallsModeStats({ stats: 'meow' }, 'face_off', 'angel'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MegaWallsModeStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.finalKills).toBeDefined(); + expect(data.finalKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalKills).toEqualTypeOf(); + expect(data.finalAssists).toBeDefined(); + expect(data.finalAssists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalAssists).toEqualTypeOf(); + expect(data.finalDeaths).toBeDefined(); + expect(data.finalDeaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.finalDeaths).toEqualTypeOf(); + expect(data.FKDR).toBeDefined(); + expect(data.FKDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.FKDR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.witherDamage).toBeDefined(); + expect(data.witherDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherDamage).toEqualTypeOf(); + expect(data.defenderKills).toBeDefined(); + expect(data.defenderKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.defenderKills).toEqualTypeOf(); + expect(data.walked).toBeDefined(); + expect(data.walked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.walked).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.meleeKills).toBeDefined(); + expect(data.meleeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeKills).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.ts b/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.ts new file mode 100644 index 000000000..de25d22e2 --- /dev/null +++ b/src/Structures/MiniGames/MegaWalls/MegaWallsModeStats.ts @@ -0,0 +1,48 @@ +import Divide from '../../../Utils/Divide.js'; +import type { MegaWallsKits, MegaWallsModes } from '../../../Types/Player.js'; + +class MegaWallsModeStats { + kills: number; + assists: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + finalKills: number; + finalAssists: number; + finalDeaths: number; + FKDR: number; + playedGames: number; + witherDamage: number; + defenderKills: number; + walked: number; + blocksPlaced: number; + blocksBroken: number; + meleeKills: number; + damageDealt: number; + constructor(data: Record, mode: MegaWallsModes, kit?: MegaWallsKits) { + const kitName = kit ? `${kit}_` : ''; + this.kills = data?.[`${kitName}kills_${mode}`] || 0; + this.assists = data?.[`${kitName}assists_${mode}`] || 0; + this.deaths = data?.[`${kitName}deaths_${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`${kitName}wins_${mode}`] || 0; + this.losses = data?.[`${kitName}losses_${mode}`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.finalKills = data?.[`${kitName}final_kills_${mode}`] || 0; + this.finalAssists = data?.[`${kitName}final_assists_${mode}`] || 0; + this.finalDeaths = data?.[`${kitName}final_deaths_${mode}`] || 0; + this.FKDR = Divide(this.finalKills, this.finalDeaths); + this.playedGames = data?.[`${kitName}games_played_${mode}`] || 0; + this.witherDamage = data?.[`${kitName}wither_damage_${mode}`] || 0; + this.defenderKills = data?.[`${kitName}defender_kills_${mode}`] || 0; + this.walked = data?.[`${kitName}meters_walked_${mode}`] || 0; + this.blocksPlaced = data?.[`${kitName}blocks_placed_${mode}`] || 0; + this.blocksBroken = data?.[`${kitName}blocks_broken_${mode}`] || 0; + this.meleeKills = data?.[`${kitName}kills_melee_${mode}`] || 0; + this.damageDealt = data?.[`${kitName}damage_dealt_${mode}`] || 0; + } +} + +export default MegaWallsModeStats; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMystery.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMystery.test.ts new file mode 100644 index 000000000..0f7543db1 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMystery.test.ts @@ -0,0 +1,292 @@ +import Emblem from '../Shared/Emblem/Emblem.js'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import MurderMystery from './MurderMystery.js'; +import MurderMysteryDescent from './MurderMysteryDescent.js'; +import MurderMysteryFavorites from './MurderMysteryFavorites.js'; +import MurderMysteryGamemode from './MurderMysteryGamemode.js'; +import MurderMysteryKnifeSkinPrestige from './MurderMysteryKnifeSkinPrestige.js'; +import MurderMysteryMap from './MurderMysteryMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + MurderMysteryAnimatedHat, + MurderMysteryDeathCry, + MurderMysteryDescentMode, + MurderMysteryEmblemIcon, + MurderMysteryGesture, + MurderMysteryGravestone, + MurderMysteryItem, + MurderMysteryKillNote, + MurderMysteryKnifeSkin, + MurderMysteryLastWords, + MurderMysteryMapName, + MurderMysteryProjectileTrail, + MurderMysteryRole, + MurderMysteryVictoryDance, + ShopSort +} from '../../../Types/Player.js'; + +test('MurderMystery', () => { + const data = new MurderMystery({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMystery); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeAnimatedHat).toBeDefined(); + expectTypeOf(data.activeAnimatedHat).toEqualTypeOf(); + expect(data.activeDeathCry).toBeDefined(); + expectTypeOf(data.activeDeathCry).toEqualTypeOf(); + expect(data.activeGesture).toBeDefined(); + expectTypeOf(data.activeGesture).toEqualTypeOf(); + expect(data.activeGravestone).toBeDefined(); + expectTypeOf(data.activeGravestone).toEqualTypeOf(); + expect(data.activeKillNote).toBeDefined(); + expectTypeOf(data.activeKillNote).toEqualTypeOf(); + expect(data.activeKnifeSkin).toBeDefined(); + expectTypeOf(data.activeKnifeSkin).toEqualTypeOf(); + expect(data.activeLastWords).toBeDefined(); + expectTypeOf(data.activeLastWords).toEqualTypeOf(); + expect(data.activeProjectileTrail).toBeDefined(); + expectTypeOf(data.activeProjectileTrail).toEqualTypeOf(); + expect(data.activeVictoryDance).toBeDefined(); + expectTypeOf(data.activeVictoryDance).toEqualTypeOf(); + expect(data.alphaWins).toBeDefined(); + expect(data.alphaWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.alphaWins).toEqualTypeOf(); + expect(data.bowKills).toBeDefined(); + expect(data.bowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowKills).toEqualTypeOf(); + expect(data.chestHistoryNew).toBeDefined(); + expectTypeOf(data.chestHistoryNew).toEqualTypeOf(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.tokensPickedUp).toBeDefined(); + expect(data.tokensPickedUp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokensPickedUp).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.descent).toBeDefined(); + expect(data.descent).toBeInstanceOf(MurderMysteryDescent); + expectTypeOf(data.descent).toEqualTypeOf(); + expect(data.detectiveWins).toBeDefined(); + expect(data.detectiveWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.detectiveWins).toEqualTypeOf(); + expect(data.doEmblemsInGame).toBeDefined(); + expectTypeOf(data.doEmblemsInGame).toEqualTypeOf(); + expect(data.doHeartbeatSounds).toBeDefined(); + expectTypeOf(data.doHeartbeatSounds).toEqualTypeOf(); + expect(data.doHints).toBeDefined(); + expectTypeOf(data.doHints).toEqualTypeOf(); + expect(data.emblem).toBeDefined(); + expectTypeOf(data.emblem).toEqualTypeOf>(); + expect(data.favoriteDescentMode).toBeDefined(); + expectTypeOf(data.favoriteDescentMode).toEqualTypeOf(); + expect(data.favorites).toBeDefined(); + expect(data.favorites).toBeInstanceOf(MurderMysteryFavorites); + expectTypeOf(data.favorites).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeGreaterThanOrEqual(0); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.grantedChests).toBeDefined(); + expect(data.grantedChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grantedChests).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.knifeSkinPrestiges).toBeDefined(); + expect(data.knifeSkinPrestiges).toBeInstanceOf(MurderMysteryKnifeSkinPrestige); + expectTypeOf(data.knifeSkinPrestiges).toEqualTypeOf(); + expect(data.leaderboardSettings).toBeDefined(); + expectTypeOf(data.leaderboardSettings).toEqualTypeOf>(); + expect(data.knifeKills).toBeDefined(); + expect(data.knifeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.knifeKills).toEqualTypeOf(); + expect(data.lastOneAlive).toBeDefined(); + expect(data.lastOneAlive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastOneAlive).toEqualTypeOf(); + expect(data.longestTimeAsSurvivorSeconds).toBeDefined(); + expect(data.longestTimeAsSurvivorSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestTimeAsSurvivorSeconds).toEqualTypeOf(); + expect(data.mapsConsumablesUsed).toBeDefined(); + expectTypeOf(data.mapsConsumablesUsed).toEqualTypeOf(); + expect(data.mapsMurdererTrapKills).toBeDefined(); + expectTypeOf(data.mapsMurdererTrapKills).toEqualTypeOf(); + expect(data.chestHistory).toBeDefined(); + expectTypeOf(data.chestHistory).toEqualTypeOf(); + expect(data.chests).toBeDefined(); + expect(data.chests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chests).toEqualTypeOf(); + expect(data.christmasChests).toBeDefined(); + expect(data.christmasChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasChests).toEqualTypeOf(); + expect(data.easterChests).toBeDefined(); + expect(data.easterChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.easterChests).toEqualTypeOf(); + expect(data.goldenChests).toBeDefined(); + expect(data.goldenChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenChests).toEqualTypeOf(); + expect(data.halloweenChests).toBeDefined(); + expect(data.halloweenChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloweenChests).toEqualTypeOf(); + expect(data.lunarChests).toBeDefined(); + expect(data.lunarChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lunarChests).toEqualTypeOf(); + expect(data.merryChests).toBeDefined(); + expect(data.merryChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.merryChests).toEqualTypeOf(); + expect(data.murdererWins).toBeDefined(); + expect(data.murdererWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murdererWins).toEqualTypeOf(); + expect(data.books).toBeDefined(); + expectTypeOf(data.books).toEqualTypeOf(); + expect(data.quickestDetectiveWinTimeSeconds).toBeDefined(); + expect(data.quickestDetectiveWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestDetectiveWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestMurdererWinTimeSeconds).toBeDefined(); + expect(data.quickestMurdererWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestMurdererWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestShowdownWinTimeSeconds).toBeDefined(); + expect(data.quickestShowdownWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestShowdownWinTimeSeconds).toEqualTypeOf(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.shopSortEnableOwnedFirst).toBeDefined(); + expectTypeOf(data.shopSortEnableOwnedFirst).toEqualTypeOf(); + expect(data.showdownPotg).toBeDefined(); + expect(data.showdownPotg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.showdownPotg).toEqualTypeOf(); + expect(data.showQueueBook).toBeDefined(); + expectTypeOf(data.showQueueBook).toEqualTypeOf(); + expect(data.spookyOpenAch).toBeDefined(); + expect(data.spookyOpenAch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spookyOpenAch).toEqualTypeOf(); + expect(data.suicides).toBeDefined(); + expect(data.suicides).toBeGreaterThanOrEqual(0); + expectTypeOf(data.suicides).toEqualTypeOf(); + expect(data.survivorWins).toBeDefined(); + expect(data.survivorWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.survivorWins).toEqualTypeOf(); + expect(data.thrownKnifeKills).toBeDefined(); + expect(data.thrownKnifeKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.thrownKnifeKills).toEqualTypeOf(); + expect(data.totalTimeSurvivedSeconds).toBeDefined(); + expect(data.totalTimeSurvivedSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalTimeSurvivedSeconds).toEqualTypeOf(); + expect(data.trapKills).toBeDefined(); + expect(data.trapKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trapKills).toEqualTypeOf(); + expect(data.wasHero).toBeDefined(); + expect(data.wasHero).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wasHero).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.openedChests).toBeDefined(); + expect(data.openedChests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedChests).toEqualTypeOf(); + expect(data.openedCommons).toBeDefined(); + expect(data.openedCommons).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedCommons).toEqualTypeOf(); + expect(data.openedEpics).toBeDefined(); + expect(data.openedEpics).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedEpics).toEqualTypeOf(); + expect(data.openedLegendaries).toBeDefined(); + expect(data.openedLegendaries).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedLegendaries).toEqualTypeOf(); + expect(data.openedRares).toBeDefined(); + expect(data.openedRares).toBeGreaterThanOrEqual(0); + expectTypeOf(data.openedRares).toEqualTypeOf(); + expect(data.ancientTomb).toBeDefined(); + expect(data.ancientTomb).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.ancientTomb).toEqualTypeOf(); + expect(data.aquarium).toBeDefined(); + expect(data.aquarium).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.aquarium).toEqualTypeOf(); + expect(data.archives).toBeDefined(); + expect(data.archives).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.archives).toEqualTypeOf(); + expect(data.archivesTopFloor).toBeDefined(); + expect(data.archivesTopFloor).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.archivesTopFloor).toEqualTypeOf(); + expect(data.cattleridgeFarm).toBeDefined(); + expect(data.cattleridgeFarm).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.cattleridgeFarm).toEqualTypeOf(); + expect(data.cruiseShip).toBeDefined(); + expect(data.cruiseShip).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.cruiseShip).toEqualTypeOf(); + expect(data.darkfall).toBeDefined(); + expect(data.darkfall).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.darkfall).toEqualTypeOf(); + expect(data.easterWorld).toBeDefined(); + expect(data.easterWorld).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.easterWorld).toEqualTypeOf(); + expect(data.goldRush).toBeDefined(); + expect(data.goldRush).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.goldRush).toEqualTypeOf(); + expect(data.headquarters).toBeDefined(); + expect(data.headquarters).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.headquarters).toEqualTypeOf(); + expect(data.hollywood).toBeDefined(); + expect(data.hollywood).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.hollywood).toEqualTypeOf(); + expect(data.hypixelWorld).toBeDefined(); + expect(data.hypixelWorld).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.hypixelWorld).toEqualTypeOf(); + expect(data.library).toBeDefined(); + expect(data.library).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.library).toEqualTypeOf(); + expect(data.mountain).toBeDefined(); + expect(data.mountain).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.mountain).toEqualTypeOf(); + expect(data.sanPeratico).toBeDefined(); + expect(data.sanPeratico).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.sanPeratico).toEqualTypeOf(); + expect(data.sanPeraticoV2).toBeDefined(); + expect(data.sanPeraticoV2).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.sanPeraticoV2).toEqualTypeOf(); + expect(data.skywayPier).toBeDefined(); + expect(data.skywayPier).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.skywayPier).toEqualTypeOf(); + expect(data.snowfall).toBeDefined(); + expect(data.snowfall).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.snowfall).toEqualTypeOf(); + expect(data.snowglobe).toBeDefined(); + expect(data.snowglobe).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.snowglobe).toEqualTypeOf(); + expect(data.spookyMansion).toBeDefined(); + expect(data.spookyMansion).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.spookyMansion).toEqualTypeOf(); + expect(data.subway).toBeDefined(); + expect(data.subway).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.subway).toEqualTypeOf(); + expect(data.towerfall).toBeDefined(); + expect(data.towerfall).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.towerfall).toEqualTypeOf(); + expect(data.transport).toBeDefined(); + expect(data.transport).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.transport).toEqualTypeOf(); + expect(data.villa).toBeDefined(); + expect(data.villa).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.villa).toEqualTypeOf(); + expect(data.widowsDen).toBeDefined(); + expect(data.widowsDen).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data.widowsDen).toEqualTypeOf(); + expect(data.assassins).toBeDefined(); + expect(data.assassins).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.assassins).toEqualTypeOf(); + expect(data.classic).toBeDefined(); + expect(data.classic).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.classic).toEqualTypeOf(); + expect(data.doubleUp).toBeDefined(); + expect(data.doubleUp).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.doubleUp).toEqualTypeOf(); + expect(data.hardcode).toBeDefined(); + expect(data.hardcode).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.hardcode).toEqualTypeOf(); + expect(data.infection).toBeDefined(); + expect(data.infection).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.infection).toEqualTypeOf(); + expect(data.showdown).toBeDefined(); + expect(data.showdown).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.showdown).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMystery.ts b/src/Structures/MiniGames/MurderMystery/MurderMystery.ts new file mode 100644 index 000000000..052c4ce00 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMystery.ts @@ -0,0 +1,219 @@ +import Emblem from '../Shared/Emblem/Emblem.js'; +import LeaderboardSettings from '../Shared/LeaderboardSettings.js'; +import MurderMysteryDescent from './MurderMysteryDescent.js'; +import MurderMysteryFavorites from './MurderMysteryFavorites.js'; +import MurderMysteryGamemode from './MurderMysteryGamemode.js'; +import MurderMysteryKnifeSkinPrestige from './MurderMysteryKnifeSkinPrestige.js'; +import MurderMysteryMap from './MurderMysteryMap.js'; +import type { + MurderMysteryAnimatedHat, + MurderMysteryDeathCry, + MurderMysteryDescentMode, + MurderMysteryEmblemIcon, + MurderMysteryGesture, + MurderMysteryGravestone, + MurderMysteryItem, + MurderMysteryKillNote, + MurderMysteryKnifeSkin, + MurderMysteryLastWords, + MurderMysteryMapName, + MurderMysteryProjectileTrail, + MurderMysteryRole, + MurderMysteryVictoryDance, + ShopSort +} from '../../../Types/Player.js'; + +class MurderMystery { + activeAnimatedHat: MurderMysteryAnimatedHat | 'UNKNOWN'; + activeDeathCry: MurderMysteryDeathCry | 'UNKNOWN'; + activeGesture: MurderMysteryGesture | 'UNKNOWN'; + activeGravestone: MurderMysteryGravestone | 'UNKNOWN'; + activeKillNote: MurderMysteryKillNote | 'UNKNOWN'; + activeKnifeSkin: MurderMysteryKnifeSkin | 'UNKNOWN'; + activeLastWords: MurderMysteryLastWords | 'UNKNOWN'; + activeProjectileTrail: MurderMysteryProjectileTrail | 'UNKNOWN'; + activeVictoryDance: MurderMysteryVictoryDance | 'UNKNOWN'; + alphaWins: number; + bowKills: number; + chestHistoryNew: MurderMysteryItem[]; + tokens: number; + tokensPickedUp: number; + deaths: number; + descent: MurderMysteryDescent; + detectiveWins: number; + doEmblemsInGame: boolean; + doHeartbeatSounds: boolean; + doHints: boolean; + emblem: Emblem; + favoriteDescentMode: MurderMysteryDescentMode | 'UNKNOWN'; + favorites: MurderMysteryFavorites; + games: number; + grantedChests: number; + kills: number; + knifeSkinPrestiges: MurderMysteryKnifeSkinPrestige; + leaderboardSettings: LeaderboardSettings<'UNKNOWN'>; + knifeKills: number; + lastOneAlive: number; + longestTimeAsSurvivorSeconds: number; + mapsConsumablesUsed: MurderMysteryMapName[]; + mapsMurdererTrapKills: MurderMysteryMapName[]; + chestHistory: MurderMysteryItem[]; + chests: number; + christmasChests: number; + easterChests: number; + goldenChests: number; + halloweenChests: number; + lunarChests: number; + merryChests: number; + murdererWins: number; + books: MurderMysteryRole[]; + quickestDetectiveWinTimeSeconds: number; + quickestMurdererWinTimeSeconds: number; + quickestShowdownWinTimeSeconds: number; + shopSort: ShopSort | 'UNKNOWN'; + shopSortEnableOwnedFirst: boolean; + showdownPotg: number; + showQueueBook: boolean; + spookyOpenAch: number; + suicides: number; + survivorWins: number; + thrownKnifeKills: number; + totalTimeSurvivedSeconds: number; + trapKills: number; + wasHero: number; + wins: number; + openedChests: number; + openedCommons: number; + openedEpics: number; + openedLegendaries: number; + openedRares: number; + ancientTomb: MurderMysteryMap; + aquarium: MurderMysteryMap; + archives: MurderMysteryMap; + archivesTopFloor: MurderMysteryMap; + cattleridgeFarm: MurderMysteryMap; + cruiseShip: MurderMysteryMap; + darkfall: MurderMysteryMap; + easterWorld: MurderMysteryMap; + goldRush: MurderMysteryMap; + headquarters: MurderMysteryMap; + hollywood: MurderMysteryMap; + hypixelWorld: MurderMysteryMap; + library: MurderMysteryMap; + mountain: MurderMysteryMap; + sanPeratico: MurderMysteryMap; + sanPeraticoV2: MurderMysteryMap; + skywayPier: MurderMysteryMap; + snowfall: MurderMysteryMap; + snowglobe: MurderMysteryMap; + spookyMansion: MurderMysteryMap; + subway: MurderMysteryMap; + towerfall: MurderMysteryMap; + transport: MurderMysteryMap; + villa: MurderMysteryMap; + widowsDen: MurderMysteryMap; + assassins: MurderMysteryGamemode; + classic: MurderMysteryGamemode; + doubleUp: MurderMysteryGamemode; + hardcode: MurderMysteryGamemode; + infection: MurderMysteryGamemode; + showdown: MurderMysteryGamemode; + constructor(data: Record) { + this.activeAnimatedHat = data?.active_animated_hat || 'UNKNOWN'; + this.activeDeathCry = data?.active_deathcry || 'UNKNOWN'; + this.activeGesture = data?.active_gesture || 'UNKNOWN'; + this.activeGravestone = data?.active_gravestone || 'UNKNOWN'; + this.activeKillNote = data?.active_kill_note || 'UNKNOWN'; + this.activeKnifeSkin = data?.active_knife_skin || 'UNKNOWN'; + this.activeLastWords = data?.active_last_words || 'UNKNOWN'; + this.activeProjectileTrail = data?.active_projectile_trail || data?.activeProjectileTrail || 'UNKNOWN'; + this.activeVictoryDance = data?.active_victory_dance || 'UNKNOWN'; + this.alphaWins = data?.alpha_wins || 0; + this.bowKills = data?.bow_kills || 0; + this.chestHistoryNew = data?.chest_history_new || []; + this.tokens = data?.coins || 0; + this.tokensPickedUp = data?.coins_pickedup || 0; + this.deaths = data?.deaths || 0; + this.descent = new MurderMysteryDescent(data?.descent || {}); + this.detectiveWins = data?.detective_wins || 0; + this.doEmblemsInGame = data?.doEmblemsInGame || false; + this.doHeartbeatSounds = data?.doHeartbeatSounds || false; + this.doHints = data?.doHints || false; + this.emblem = new Emblem(data?.emblem || {}); + this.favoriteDescentMode = data?.favoriteDescentMode || 'UNKNOWN'; + this.favorites = new MurderMysteryFavorites(data?.favorites || {}); + this.games = data?.games || 0; + this.grantedChests = data?.granted_chests || 0; + this.kills = data?.kills || 0; + this.knifeSkinPrestiges = new MurderMysteryKnifeSkinPrestige(data?.knifeSkinPrestiges || {}); + this.leaderboardSettings = new LeaderboardSettings<'UNKNOWN'>(data?.leaderboardSettings || {}); + this.knifeKills = data?.knife_kills || 0; + this.lastOneAlive = data?.last_one_alive || 0; + this.longestTimeAsSurvivorSeconds = data?.longest_time_as_survivor_seconds || 0; + this.mapsConsumablesUsed = data?.mapsConsumablesUsed || []; + this.mapsMurdererTrapKills = data?.mapsMurdererTrapKills || []; + this.chestHistory = data?.mm_chest_history || []; + this.chests = data?.mm_chests || 0; + this.christmasChests = data?.mm_christmas_chests || 0; + this.easterChests = data?.mm_easter_chests || 0; + this.goldenChests = data?.mm_golden_chests || 0; + this.halloweenChests = data?.mm_halloween_chests || 0; + this.lunarChests = data?.mm_lunar_chests || 0; + this.merryChests = data?.mm_merry_chests || 0; + this.murdererWins = data?.murderer_wins || 0; + this.books = data?.murdermystery_books || []; + this.quickestDetectiveWinTimeSeconds = data?.quickest_detective_win_time_seconds || 0; + this.quickestMurdererWinTimeSeconds = data?.quickest_murderer_win_time_seconds || 0; + this.quickestShowdownWinTimeSeconds = data?.quickest_showdown_win_time_seconds || 0; + this.shopSort = data?.shop_sort || false; + this.shopSortEnableOwnedFirst = data?.shop_sort_enable_owned_first || false; + this.showdownPotg = data?.showdown_potg || 0; + this.showQueueBook = data?.showqueuebook || true; + this.spookyOpenAch = data?.spooky_open_ach || 0; + this.suicides = data?.suicides || 0; + this.survivorWins = data?.survivor_wins || 0; + this.thrownKnifeKills = data?.thrown_knife_kills || 0; + this.totalTimeSurvivedSeconds = data?.total_time_survived_seconds || 0; + this.trapKills = data?.trap_kills || 0; + this.wasHero = data?.was_hero || 0; + this.wins = data?.wins || 0; + this.openedChests = data?.MurderMystery_openedChests || 0; + this.openedCommons = data?.MurderMystery_openedCommons || 0; + this.openedEpics = data?.MurderMystery_openedEpics || 0; + this.openedLegendaries = data?.MurderMystery_openedLegendaries || 0; + this.openedRares = data?.MurderMystery_openedRares || 0; + this.ancientTomb = new MurderMysteryMap(data, 'ancient_tomb'); + this.aquarium = new MurderMysteryMap(data, 'aquarium'); + this.archives = new MurderMysteryMap(data, 'archives'); + this.archivesTopFloor = new MurderMysteryMap(data, 'archives_top_floor'); + this.cattleridgeFarm = new MurderMysteryMap(data, 'cattleridge_farm'); + this.cruiseShip = new MurderMysteryMap(data, 'cruise_ship'); + this.darkfall = new MurderMysteryMap(data, 'darkfall'); + this.easterWorld = new MurderMysteryMap(data, 'easter_world'); + this.goldRush = new MurderMysteryMap(data, 'gold_rush'); + this.headquarters = new MurderMysteryMap(data, 'headquarters'); + this.hollywood = new MurderMysteryMap(data, 'hollywood'); + this.hypixelWorld = new MurderMysteryMap(data, 'hypixel_world'); + this.library = new MurderMysteryMap(data, 'library'); + this.mountain = new MurderMysteryMap(data, 'mountain'); + this.sanPeratico = new MurderMysteryMap(data, 'san_peratico'); + this.sanPeraticoV2 = new MurderMysteryMap(data, 'san_peratico_v2'); + this.skywayPier = new MurderMysteryMap(data, 'skyway_pier'); + this.snowfall = new MurderMysteryMap(data, 'snowfall'); + this.snowglobe = new MurderMysteryMap(data, 'snowglobe'); + this.spookyMansion = new MurderMysteryMap(data, 'spooky_mansion'); + this.subway = new MurderMysteryMap(data, 'subway'); + this.towerfall = new MurderMysteryMap(data, 'towerfall'); + this.transport = new MurderMysteryMap(data, 'transport'); + this.villa = new MurderMysteryMap(data, 'villa'); + this.widowsDen = new MurderMysteryMap(data, "widow's_den"); + this.assassins = new MurderMysteryGamemode(data, 'MURDER_ASSASSINS'); + this.classic = new MurderMysteryGamemode(data, 'MURDER_CLASSIC'); + this.doubleUp = new MurderMysteryGamemode(data, 'MURDER_DOUBLE_UP'); + this.hardcode = new MurderMysteryGamemode(data, 'MURDER_HARDCORE'); + this.infection = new MurderMysteryGamemode(data, 'MURDER_INFECTION'); + this.showdown = new MurderMysteryGamemode(data, 'MURDER_SHOWDOWN'); + } +} + +export default MurderMystery; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.test.ts new file mode 100644 index 000000000..d27aa1714 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.test.ts @@ -0,0 +1,163 @@ +import MurderMysteryDescent from './MurderMysteryDescent.js'; +import MurderMysteryDescentItem from './MurderMysteryDescentItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MurderMysteryDescent', () => { + const data = new MurderMysteryDescent({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryDescent); + expectTypeOf(data).toEqualTypeOf(); + expect(data.Armed).toBeDefined(); + expect(data.Armed).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.Armed).toEqualTypeOf(); + expect(data.bloodLust).toBeDefined(); + expect(data.bloodLust).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.bloodLust).toEqualTypeOf(); + expect(data.bountyHunter).toBeDefined(); + expect(data.bountyHunter).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.bountyHunter).toEqualTypeOf(); + expect(data.cleanJob).toBeDefined(); + expect(data.cleanJob).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.cleanJob).toEqualTypeOf(); + expect(data.Collateral).toBeDefined(); + expect(data.Collateral).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.Collateral).toEqualTypeOf(); + expect(data.contagionContained).toBeDefined(); + expect(data.contagionContained).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.contagionContained).toEqualTypeOf(); + expect(data.Cornucopia).toBeDefined(); + expect(data.Cornucopia).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.Cornucopia).toEqualTypeOf(); + expect(data.crimsonJoy).toBeDefined(); + expect(data.crimsonJoy).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.crimsonJoy).toEqualTypeOf(); + expect(data.crowdControl).toBeDefined(); + expect(data.crowdControl).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.crowdControl).toEqualTypeOf(); + expect(data.cuttingTheroots).toBeDefined(); + expect(data.cuttingTheroots).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.cuttingTheroots).toEqualTypeOf(); + expect(data.deadlyPrecision).toBeDefined(); + expect(data.deadlyPrecision).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.deadlyPrecision).toEqualTypeOf(); + expect(data.deadorAlive).toBeDefined(); + expect(data.deadorAlive).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.deadorAlive).toEqualTypeOf(); + expect(data.deathDefy).toBeDefined(); + expect(data.deathDefy).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.deathDefy).toEqualTypeOf(); + expect(data.distanttransMission).toBeDefined(); + expect(data.distanttransMission).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.distanttransMission).toEqualTypeOf(); + expect(data.doubleDosage).toBeDefined(); + expect(data.doubleDosage).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.doubleDosage).toEqualTypeOf(); + expect(data.dualProficiency).toBeDefined(); + expect(data.dualProficiency).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.dualProficiency).toEqualTypeOf(); + expect(data.exponentiation).toBeDefined(); + expect(data.exponentiation).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.exponentiation).toEqualTypeOf(); + expect(data.eyeonPrey).toBeDefined(); + expect(data.eyeonPrey).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.eyeonPrey).toEqualTypeOf(); + expect(data.firstJob).toBeDefined(); + expect(data.firstJob).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.firstJob).toEqualTypeOf(); + expect(data.firstOfMany).toBeDefined(); + expect(data.firstOfMany).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.firstOfMany).toEqualTypeOf(); + expect(data.firstSteps).toBeDefined(); + expect(data.firstSteps).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.firstSteps).toEqualTypeOf(); + expect(data.grandSlam).toBeDefined(); + expect(data.grandSlam).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.grandSlam).toEqualTypeOf(); + expect(data.hero).toBeDefined(); + expect(data.hero).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.hero).toEqualTypeOf(); + expect(data.highRoller).toBeDefined(); + expect(data.highRoller).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.highRoller).toEqualTypeOf(); + expect(data.holdGround).toBeDefined(); + expect(data.holdGround).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.holdGround).toEqualTypeOf(); + expect(data.huntsman).toBeDefined(); + expect(data.huntsman).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.huntsman).toEqualTypeOf(); + expect(data.jobSearch).toBeDefined(); + expect(data.jobSearch).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.jobSearch).toEqualTypeOf(); + expect(data.lawMaker).toBeDefined(); + expect(data.lawMaker).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.lawMaker).toEqualTypeOf(); + expect(data.Legacy).toBeDefined(); + expect(data.Legacy).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.Legacy).toEqualTypeOf(); + expect(data.localSpecialty).toBeDefined(); + expect(data.localSpecialty).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.localSpecialty).toEqualTypeOf(); + expect(data.lurkingContagion).toBeDefined(); + expect(data.lurkingContagion).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.lurkingContagion).toEqualTypeOf(); + expect(data.makeshiftShield).toBeDefined(); + expect(data.makeshiftShield).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.makeshiftShield).toEqualTypeOf(); + expect(data.mowingDown).toBeDefined(); + expect(data.mowingDown).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.mowingDown).toEqualTypeOf(); + expect(data.oneOfUs).toBeDefined(); + expect(data.oneOfUs).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.oneOfUs).toEqualTypeOf(); + expect(data.paneKiller).toBeDefined(); + expect(data.paneKiller).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.paneKiller).toEqualTypeOf(); + expect(data.patientZero).toBeDefined(); + expect(data.patientZero).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.patientZero).toEqualTypeOf(); + expect(data.postPandemic).toBeDefined(); + expect(data.postPandemic).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.postPandemic).toEqualTypeOf(); + expect(data.pythagoreanDisposal).toBeDefined(); + expect(data.pythagoreanDisposal).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.pythagoreanDisposal).toEqualTypeOf(); + expect(data.quickDraw).toBeDefined(); + expect(data.quickDraw).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.quickDraw).toEqualTypeOf(); + expect(data.reloaded).toBeDefined(); + expect(data.reloaded).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.reloaded).toEqualTypeOf(); + expect(data.seasonedHitman).toBeDefined(); + expect(data.seasonedHitman).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.seasonedHitman).toEqualTypeOf(); + expect(data.selfDefense).toBeDefined(); + expect(data.selfDefense).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.selfDefense).toEqualTypeOf(); + expect(data.serialTrapper).toBeDefined(); + expect(data.serialTrapper).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.serialTrapper).toEqualTypeOf(); + expect(data.silverBullet).toBeDefined(); + expect(data.silverBullet).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.silverBullet).toEqualTypeOf(); + expect(data.slaughterHouse).toBeDefined(); + expect(data.slaughterHouse).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.slaughterHouse).toEqualTypeOf(); + expect(data.sneaky).toBeDefined(); + expect(data.sneaky).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.sneaky).toEqualTypeOf(); + expect(data.survival).toBeDefined(); + expect(data.survival).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.survival).toEqualTypeOf(); + expect(data.totaloutBreak).toBeDefined(); + expect(data.totaloutBreak).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.totaloutBreak).toEqualTypeOf(); + expect(data.trapping101).toBeDefined(); + expect(data.trapping101).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.trapping101).toEqualTypeOf(); + expect(data.trulyMad).toBeDefined(); + expect(data.trulyMad).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.trulyMad).toEqualTypeOf(); + expect(data.viralKnife).toBeDefined(); + expect(data.viralKnife).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data.viralKnife).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.ts new file mode 100644 index 000000000..57213dd2d --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescent.ts @@ -0,0 +1,110 @@ +import MurderMysteryDescentItem from './MurderMysteryDescentItem.js'; + +class MurderMysteryDescent { + Armed: MurderMysteryDescentItem; + bloodLust: MurderMysteryDescentItem; + bountyHunter: MurderMysteryDescentItem; + cleanJob: MurderMysteryDescentItem; + Collateral: MurderMysteryDescentItem; + contagionContained: MurderMysteryDescentItem; + Cornucopia: MurderMysteryDescentItem; + crimsonJoy: MurderMysteryDescentItem; + crowdControl: MurderMysteryDescentItem; + cuttingTheroots: MurderMysteryDescentItem; + deadlyPrecision: MurderMysteryDescentItem; + deadorAlive: MurderMysteryDescentItem; + deathDefy: MurderMysteryDescentItem; + distanttransMission: MurderMysteryDescentItem; + doubleDosage: MurderMysteryDescentItem; + dualProficiency: MurderMysteryDescentItem; + exponentiation: MurderMysteryDescentItem; + eyeonPrey: MurderMysteryDescentItem; + firstJob: MurderMysteryDescentItem; + firstOfMany: MurderMysteryDescentItem; + firstSteps: MurderMysteryDescentItem; + grandSlam: MurderMysteryDescentItem; + hero: MurderMysteryDescentItem; + highRoller: MurderMysteryDescentItem; + holdGround: MurderMysteryDescentItem; + huntsman: MurderMysteryDescentItem; + jobSearch: MurderMysteryDescentItem; + lawMaker: MurderMysteryDescentItem; + Legacy: MurderMysteryDescentItem; + localSpecialty: MurderMysteryDescentItem; + lurkingContagion: MurderMysteryDescentItem; + makeshiftShield: MurderMysteryDescentItem; + mowingDown: MurderMysteryDescentItem; + oneOfUs: MurderMysteryDescentItem; + paneKiller: MurderMysteryDescentItem; + patientZero: MurderMysteryDescentItem; + postPandemic: MurderMysteryDescentItem; + pythagoreanDisposal: MurderMysteryDescentItem; + quickDraw: MurderMysteryDescentItem; + reloaded: MurderMysteryDescentItem; + seasonedHitman: MurderMysteryDescentItem; + selfDefense: MurderMysteryDescentItem; + serialTrapper: MurderMysteryDescentItem; + silverBullet: MurderMysteryDescentItem; + slaughterHouse: MurderMysteryDescentItem; + sneaky: MurderMysteryDescentItem; + survival: MurderMysteryDescentItem; + totaloutBreak: MurderMysteryDescentItem; + trapping101: MurderMysteryDescentItem; + trulyMad: MurderMysteryDescentItem; + viralKnife: MurderMysteryDescentItem; + constructor(data: Record) { + this.Armed = new MurderMysteryDescentItem(data?.Armed || {}); + this.bloodLust = new MurderMysteryDescentItem(data?.Bloodlust || {}); + this.bountyHunter = new MurderMysteryDescentItem(data?.Bountyhunter || {}); + this.cleanJob = new MurderMysteryDescentItem(data?.Cleanjob || {}); + this.Collateral = new MurderMysteryDescentItem(data?.Collateral || {}); + this.contagionContained = new MurderMysteryDescentItem(data?.Contagioncontained || {}); + this.Cornucopia = new MurderMysteryDescentItem(data?.Cornucopia || {}); + this.crimsonJoy = new MurderMysteryDescentItem(data?.Crimsonjoy || {}); + this.crowdControl = new MurderMysteryDescentItem(data?.Crowdcontrol || {}); + this.cuttingTheroots = new MurderMysteryDescentItem(data?.Cuttingtheroots || {}); + this.deadlyPrecision = new MurderMysteryDescentItem(data?.Deadlyprecision || {}); + this.deadorAlive = new MurderMysteryDescentItem(data?.Deadoralive || {}); + this.deathDefy = new MurderMysteryDescentItem(data?.Deathdefy || {}); + this.distanttransMission = new MurderMysteryDescentItem(data?.Distanttransmission || {}); + this.doubleDosage = new MurderMysteryDescentItem(data?.Doubledosage || {}); + this.dualProficiency = new MurderMysteryDescentItem(data?.Dualproficiency || {}); + this.exponentiation = new MurderMysteryDescentItem(data?.Exponentiation || {}); + this.eyeonPrey = new MurderMysteryDescentItem(data?.Eyeonprey || {}); + this.firstJob = new MurderMysteryDescentItem(data?.Firstjob || {}); + this.firstOfMany = new MurderMysteryDescentItem(data?.Firstofmany || {}); + this.firstSteps = new MurderMysteryDescentItem(data?.Firststeps || {}); + this.grandSlam = new MurderMysteryDescentItem(data?.Grandslam || {}); + this.hero = new MurderMysteryDescentItem(data?.Hero || {}); + this.highRoller = new MurderMysteryDescentItem(data?.Highroller || {}); + this.holdGround = new MurderMysteryDescentItem(data?.Holdground || {}); + this.huntsman = new MurderMysteryDescentItem(data?.Huntsman || {}); + this.jobSearch = new MurderMysteryDescentItem(data?.Jobsearch || {}); + this.lawMaker = new MurderMysteryDescentItem(data?.Lawmaker || {}); + this.Legacy = new MurderMysteryDescentItem(data?.Legacy || {}); + this.localSpecialty = new MurderMysteryDescentItem(data?.Localspecialty || {}); + this.lurkingContagion = new MurderMysteryDescentItem(data?.Lurkingcontagion || {}); + this.makeshiftShield = new MurderMysteryDescentItem(data?.Makeshiftshield || {}); + this.mowingDown = new MurderMysteryDescentItem(data?.Mowingdown || {}); + this.oneOfUs = new MurderMysteryDescentItem(data?.Oneofus || {}); + this.paneKiller = new MurderMysteryDescentItem(data?.Panekiller || {}); + this.patientZero = new MurderMysteryDescentItem(data?.Patientzero || {}); + this.postPandemic = new MurderMysteryDescentItem(data?.Postpandemic || {}); + this.pythagoreanDisposal = new MurderMysteryDescentItem(data?.Pythagoreandisposal || {}); + this.quickDraw = new MurderMysteryDescentItem(data?.Quickdraw || {}); + this.reloaded = new MurderMysteryDescentItem(data?.Reloaded || {}); + this.seasonedHitman = new MurderMysteryDescentItem(data?.Seasonedhitman || {}); + this.selfDefense = new MurderMysteryDescentItem(data?.Selfdefense || {}); + this.serialTrapper = new MurderMysteryDescentItem(data?.Serialtrapper || {}); + this.silverBullet = new MurderMysteryDescentItem(data?.Silverbullet || {}); + this.slaughterHouse = new MurderMysteryDescentItem(data?.Slaughterhouse || {}); + this.sneaky = new MurderMysteryDescentItem(data?.Sneaky || {}); + this.survival = new MurderMysteryDescentItem(data?.Survival || {}); + this.totaloutBreak = new MurderMysteryDescentItem(data?.Totaloutbreak || {}); + this.trapping101 = new MurderMysteryDescentItem(data?.Trapping101 || {}); + this.trulyMad = new MurderMysteryDescentItem(data?.Trulymad || {}); + this.viralKnife = new MurderMysteryDescentItem(data?.Viralknife || {}); + } +} + +export default MurderMysteryDescent; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.test.ts new file mode 100644 index 000000000..96cd56fc5 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.test.ts @@ -0,0 +1,14 @@ +import MurderMysteryDescentItem from './MurderMysteryDescentItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MurderMysteryDescentItem', () => { + const data = new MurderMysteryDescentItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryDescentItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.claimed).toBeDefined(); + expectTypeOf(data.claimed).toEqualTypeOf(); + expect(data.progress).toBeDefined(); + expect(data.progress).toBeGreaterThanOrEqual(0); + expectTypeOf(data.progress).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.ts new file mode 100644 index 000000000..e8ad7fb35 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.ts @@ -0,0 +1,10 @@ +class MurderMysteryDescentItem { + claimed: boolean; + progress: number; + constructor(data: Record) { + this.claimed = data?.claimed || false; + this.progress = data?.progress || 0; + } +} + +export default MurderMysteryDescentItem; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.test.ts new file mode 100644 index 000000000..03e313ad5 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.test.ts @@ -0,0 +1,38 @@ +import MurderMysteryFavorites from './MurderMysteryFavorites.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + MurderMysteryAnimatedHatRaw, + MurderMysteryDeathCryRaw, + MurderMysteryGestureRaw, + MurderMysteryGravestoneRaw, + MurderMysteryKillNoteRaw, + MurderMysteryKnifeSkinRaw, + MurderMysteryLastWordsRaw, + MurderMysteryProjectileTrailRaw, + MurderMysteryVictoryDanceRaw +} from '../../../Types/Player.js'; + +test('MurderMysteryFavorites', () => { + const data = new MurderMysteryFavorites({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryFavorites); + expectTypeOf(data).toEqualTypeOf(); + expect(data.animatedHat).toBeDefined(); + expectTypeOf(data.animatedHat).toEqualTypeOf(); + expect(data.deathCry).toBeDefined(); + expectTypeOf(data.deathCry).toEqualTypeOf(); + expect(data.gesture).toBeDefined(); + expectTypeOf(data.gesture).toEqualTypeOf(); + expect(data.gravestone).toBeDefined(); + expectTypeOf(data.gravestone).toEqualTypeOf(); + expect(data.killNote).toBeDefined(); + expectTypeOf(data.killNote).toEqualTypeOf(); + expect(data.knifeSkin).toBeDefined(); + expectTypeOf(data.knifeSkin).toEqualTypeOf(); + expect(data.lastWords).toBeDefined(); + expectTypeOf(data.lastWords).toEqualTypeOf(); + expect(data.projectileTrail).toBeDefined(); + expectTypeOf(data.projectileTrail).toEqualTypeOf(); + expect(data.victoryDance).toBeDefined(); + expectTypeOf(data.victoryDance).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.ts new file mode 100644 index 000000000..5dd8d5585 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryFavorites.ts @@ -0,0 +1,36 @@ +import type { + MurderMysteryAnimatedHatRaw, + MurderMysteryDeathCryRaw, + MurderMysteryGestureRaw, + MurderMysteryGravestoneRaw, + MurderMysteryKillNoteRaw, + MurderMysteryKnifeSkinRaw, + MurderMysteryLastWordsRaw, + MurderMysteryProjectileTrailRaw, + MurderMysteryVictoryDanceRaw +} from '../../../Types/Player.js'; + +class MurderMysteryFavorites { + animatedHat: MurderMysteryAnimatedHatRaw[]; + deathCry: MurderMysteryDeathCryRaw[]; + gesture: MurderMysteryGestureRaw[]; + gravestone: MurderMysteryGravestoneRaw[]; + killNote: MurderMysteryKillNoteRaw[]; + knifeSkin: MurderMysteryKnifeSkinRaw[]; + lastWords: MurderMysteryLastWordsRaw[]; + projectileTrail: MurderMysteryProjectileTrailRaw[]; + victoryDance: MurderMysteryVictoryDanceRaw[]; + constructor(data: Record) { + this.animatedHat = data?.animated_hat || []; + this.deathCry = data?.deathcry || []; + this.gesture = data?.gesture || []; + this.gravestone = data?.gravestone || []; + this.killNote = data?.kill_note || []; + this.knifeSkin = data?.knife_skin || []; + this.lastWords = data?.last_words || []; + this.projectileTrail = data?.projectile_trail || []; + this.victoryDance = data?.victory_dance || []; + } +} + +export default MurderMysteryFavorites; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.test.ts new file mode 100644 index 000000000..4fc6b6da9 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.test.ts @@ -0,0 +1,66 @@ +import MurderMysteryGamemode from './MurderMysteryGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MurderMysteryGamemode', () => { + const data = new MurderMysteryGamemode({ stats: 'meow' }, 'MURDER_ASSASSINS', 'ancient_tomb'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.alphaWins).toBeDefined(); + expect(data.alphaWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.alphaWins).toEqualTypeOf(); + expect(data.bowKills).toBeDefined(); + expect(data.bowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowKills).toEqualTypeOf(); + expect(data.tokensPickedUp).toBeDefined(); + expect(data.tokensPickedUp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokensPickedUp).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.detectiveWins).toBeDefined(); + expect(data.detectiveWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.detectiveWins).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeGreaterThanOrEqual(0); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.lastOneAlive).toBeDefined(); + expect(data.lastOneAlive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastOneAlive).toEqualTypeOf(); + expect(data.longestTimeAsSurvivorSeconds).toBeDefined(); + expect(data.longestTimeAsSurvivorSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestTimeAsSurvivorSeconds).toEqualTypeOf(); + expect(data.murdererWins).toBeDefined(); + expect(data.murdererWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murdererWins).toEqualTypeOf(); + expect(data.quickestDetectiveWinTimeSeconds).toBeDefined(); + expect(data.quickestDetectiveWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestDetectiveWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestMurdererWinTimeSeconds).toBeDefined(); + expect(data.quickestMurdererWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestMurdererWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestShowdownWinTimeSeconds).toBeDefined(); + expect(data.quickestShowdownWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestShowdownWinTimeSeconds).toEqualTypeOf(); + expect(data.showdownPotg).toBeDefined(); + expect(data.showdownPotg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.showdownPotg).toEqualTypeOf(); + expect(data.suicides).toBeDefined(); + expect(data.suicides).toBeGreaterThanOrEqual(0); + expectTypeOf(data.suicides).toEqualTypeOf(); + expect(data.survivorWins).toBeDefined(); + expect(data.survivorWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.survivorWins).toEqualTypeOf(); + expect(data.totalTimeSurvivedSeconds).toBeDefined(); + expect(data.totalTimeSurvivedSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalTimeSurvivedSeconds).toEqualTypeOf(); + expect(data.wasHero).toBeDefined(); + expect(data.wasHero).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wasHero).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.ts new file mode 100644 index 000000000..f7d06a57d --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryGamemode.ts @@ -0,0 +1,47 @@ +import type { MurderMysteryMapName, MurderMysteryMode } from '../../../Types/Player.js'; + +class MurderMysteryGamemode { + alphaWins: number; + bowKills: number; + tokensPickedUp: number; + deaths: number; + detectiveWins: number; + games: number; + kills: number; + lastOneAlive: number; + longestTimeAsSurvivorSeconds: number; + murdererWins: number; + quickestDetectiveWinTimeSeconds: number; + quickestMurdererWinTimeSeconds: number; + quickestShowdownWinTimeSeconds: number; + showdownPotg: number; + suicides: number; + survivorWins: number; + totalTimeSurvivedSeconds: number; + wasHero: number; + wins: number; + constructor(data: Record, gamemode: MurderMysteryMode, map?: MurderMysteryMapName) { + const key = `${gamemode}${map ? `_${map}` : ''}`; + this.alphaWins = data?.[`alpha_wins_${key}`] || 0; + this.bowKills = data?.[`bow_kills_${key}`] || 0; + this.tokensPickedUp = data?.[`coins_pickedup_${key}`] || 0; + this.deaths = data?.[`deaths_${key}`] || 0; + this.detectiveWins = data?.[`detective_wins_${key}`] || 0; + this.games = data?.[`games_${key}`] || 0; + this.kills = data?.[`kills_${key}`] || 0; + this.lastOneAlive = data?.[`last_one_alive_${key}`] || 0; + this.longestTimeAsSurvivorSeconds = data?.[`longest_time_as_survivor_seconds_${key}`] || 0; + this.murdererWins = data?.[`murderer_wins_${key}`] || 0; + this.quickestDetectiveWinTimeSeconds = data?.[`quickest_detective_win_time_seconds_${key}`] || 0; + this.quickestMurdererWinTimeSeconds = data?.[`quickest_murderer_win_time_seconds_${key}`] || 0; + this.quickestShowdownWinTimeSeconds = data?.[`quickest_showdown_win_time_seconds_${key}`] || 0; + this.showdownPotg = data?.[`showdown_potg_${key}`] || 0; + this.suicides = data?.[`suicides_${key}`] || 0; + this.survivorWins = data?.[`survivor_wins_${key}`] || 0; + this.totalTimeSurvivedSeconds = data?.[`total_time_survived_seconds_${key}`] || 0; + this.wasHero = data?.[`was_hero_${key}`] || 0; + this.wins = data?.[`wins_${key}`] || 0; + } +} + +export default MurderMysteryGamemode; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.test.ts new file mode 100644 index 000000000..797e5eed9 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.test.ts @@ -0,0 +1,16 @@ +import MurderMysteryKnifeSkinPrestige from './MurderMysteryKnifeSkinPrestige.js'; +import MurderMysteryKnifeSkinPrestigeXp from './MurderMysteryKnifeSkinPrestigeXp.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { MurderMysteryKnifeSkinRaw } from '../../../Types/Player.js'; + +test('MurderMysteryKnifeSkinPrestige', () => { + const data = new MurderMysteryKnifeSkinPrestige({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryKnifeSkinPrestige); + expectTypeOf(data).toEqualTypeOf(); + expect(data.usePrestige).toBeDefined(); + expectTypeOf(data.usePrestige).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeInstanceOf(MurderMysteryKnifeSkinPrestigeXp); + expectTypeOf(data.xp).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.ts new file mode 100644 index 000000000..d7743980d --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.ts @@ -0,0 +1,13 @@ +import MurderMysteryKnifeSkinPrestigeXp from './MurderMysteryKnifeSkinPrestigeXp.js'; +import type { MurderMysteryKnifeSkinRaw } from '../../../Types/Player.js'; + +class MurderMysteryKnifeSkinPrestige { + usePrestige: MurderMysteryKnifeSkinRaw[]; + xp: MurderMysteryKnifeSkinPrestigeXp; + constructor(data: Record) { + this.usePrestige = data?.usePrestige || []; + this.xp = new MurderMysteryKnifeSkinPrestigeXp(data?.xp || {}); + } +} + +export default MurderMysteryKnifeSkinPrestige; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.test.ts new file mode 100644 index 000000000..2a4a55f5a --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.test.ts @@ -0,0 +1,138 @@ +import MurderMysteryKnifeSkinPrestigeXp from './MurderMysteryKnifeSkinPrestigeXp.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MurderMysteryKnifeSkinPrestigeXp', () => { + const data = new MurderMysteryKnifeSkinPrestigeXp({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryKnifeSkinPrestigeXp); + expectTypeOf(data).toEqualTypeOf(); + expect(data['10000Spoons']).toBeDefined(); + expect(data['10000Spoons']).toBeGreaterThanOrEqual(0); + expectTypeOf(data['10000Spoons']).toEqualTypeOf(); + expect(data.apple).toBeDefined(); + expect(data.apple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.apple).toEqualTypeOf(); + expect(data.bastedTurkey).toBeDefined(); + expect(data.bastedTurkey).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bastedTurkey).toEqualTypeOf(); + expect(data.blazeStick).toBeDefined(); + expect(data.blazeStick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blazeStick).toEqualTypeOf(); + expect(data.bloodyBrick).toBeDefined(); + expect(data.bloodyBrick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bloodyBrick).toEqualTypeOf(); + expect(data.bone).toBeDefined(); + expect(data.bone).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bone).toEqualTypeOf(); + expect(data.campfireLeftovers).toBeDefined(); + expect(data.campfireLeftovers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.campfireLeftovers).toEqualTypeOf(); + expect(data.carrotOnStick).toBeDefined(); + expect(data.carrotOnStick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.carrotOnStick).toEqualTypeOf(); + expect(data.cheapo).toBeDefined(); + expect(data.cheapo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cheapo).toEqualTypeOf(); + expect(data.cheese).toBeDefined(); + expect(data.cheese).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cheese).toEqualTypeOf(); + expect(data.chewedBush).toBeDefined(); + expect(data.chewedBush).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chewedBush).toEqualTypeOf(); + expect(data.diamondShovel).toBeDefined(); + expect(data.diamondShovel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamondShovel).toEqualTypeOf(); + expect(data.doubleDeathScythe).toBeDefined(); + expect(data.doubleDeathScythe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doubleDeathScythe).toEqualTypeOf(); + expect(data.dragonEgg).toBeDefined(); + expect(data.dragonEgg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dragonEgg).toEqualTypeOf(); + expect(data.earthenDagger).toBeDefined(); + expect(data.earthenDagger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.earthenDagger).toEqualTypeOf(); + expect(data.easterBasket).toBeDefined(); + expect(data.easterBasket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.easterBasket).toEqualTypeOf(); + expect(data.farmingImplement).toBeDefined(); + expect(data.farmingImplement).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farmingImplement).toEqualTypeOf(); + expect(data.feather).toBeDefined(); + expect(data.feather).toBeGreaterThanOrEqual(0); + expectTypeOf(data.feather).toEqualTypeOf(); + expect(data.fragilePlant).toBeDefined(); + expect(data.fragilePlant).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fragilePlant).toEqualTypeOf(); + expect(data.frisbee).toBeDefined(); + expect(data.frisbee).toBeGreaterThanOrEqual(0); + expectTypeOf(data.frisbee).toEqualTypeOf(); + expect(data.glisteningMelon).toBeDefined(); + expect(data.glisteningMelon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.glisteningMelon).toEqualTypeOf(); + expect(data.goldDigger).toBeDefined(); + expect(data.goldDigger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldDigger).toEqualTypeOf(); + expect(data.grilledSteak).toBeDefined(); + expect(data.grilledSteak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grilledSteak).toEqualTypeOf(); + expect(data.grimoire).toBeDefined(); + expect(data.grimoire).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grimoire).toEqualTypeOf(); + expect(data.iceShard).toBeDefined(); + expect(data.iceShard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iceShard).toEqualTypeOf(); + expect(data.mouseTrap).toBeDefined(); + expect(data.mouseTrap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mouseTrap).toEqualTypeOf(); + expect(data.prickly).toBeDefined(); + expect(data.prickly).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prickly).toEqualTypeOf(); + expect(data.pumpkinPie).toBeDefined(); + expect(data.pumpkinPie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pumpkinPie).toEqualTypeOf(); + expect(data.rudolphsNose).toBeDefined(); + expect(data.rudolphsNose).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rudolphsNose).toEqualTypeOf(); + expect(data.rudolphsSnack).toBeDefined(); + expect(data.rudolphsSnack).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rudolphsSnack).toEqualTypeOf(); + expect(data.salmon).toBeDefined(); + expect(data.salmon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.salmon).toEqualTypeOf(); + expect(data.scythe).toBeDefined(); + expect(data.scythe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.scythe).toEqualTypeOf(); + expect(data.shears).toBeDefined(); + expect(data.shears).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shears).toEqualTypeOf(); + expect(data.shinySnack).toBeDefined(); + expect(data.shinySnack).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shinySnack).toEqualTypeOf(); + expect(data.shovel).toBeDefined(); + expect(data.shovel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shovel).toEqualTypeOf(); + expect(data.shred).toBeDefined(); + expect(data.shred).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shred).toEqualTypeOf(); + expect(data.sprayPaintedShovel).toBeDefined(); + expect(data.sprayPaintedShovel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sprayPaintedShovel).toEqualTypeOf(); + expect(data.stake).toBeDefined(); + expect(data.stake).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stake).toEqualTypeOf(); + expect(data.stick).toBeDefined(); + expect(data.stick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stick).toEqualTypeOf(); + expect(data.stickWithHat).toBeDefined(); + expect(data.stickWithHat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stickWithHat).toEqualTypeOf(); + expect(data.sweetTreat).toBeDefined(); + expect(data.sweetTreat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sweetTreat).toEqualTypeOf(); + expect(data.timber).toBeDefined(); + expect(data.timber).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timber).toEqualTypeOf(); + expect(data.woodAxe).toBeDefined(); + expect(data.woodAxe).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woodAxe).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.ts new file mode 100644 index 000000000..02a854020 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.ts @@ -0,0 +1,92 @@ +class MurderMysteryKnifeSkinPrestigeXp { + '10000Spoons': number; + apple: number; + bastedTurkey: number; + blazeStick: number; + bloodyBrick: number; + bone: number; + campfireLeftovers: number; + carrotOnStick: number; + cheapo: number; + cheese: number; + chewedBush: number; + diamondShovel: number; + doubleDeathScythe: number; + dragonEgg: number; + earthenDagger: number; + easterBasket: number; + farmingImplement: number; + feather: number; + fragilePlant: number; + frisbee: number; + glisteningMelon: number; + goldDigger: number; + grilledSteak: number; + grimoire: number; + iceShard: number; + mouseTrap: number; + prickly: number; + pumpkinPie: number; + rudolphsNose: number; + rudolphsSnack: number; + salmon: number; + scythe: number; + shears: number; + shinySnack: number; + shovel: number; + shred: number; + sprayPaintedShovel: number; + stake: number; + stick: number; + stickWithHat: number; + sweetTreat: number; + timber: number; + woodAxe: number; + constructor(data: Record) { + this['10000Spoons'] = data?.['10000_spoons'] || 0; + this.apple = data?.apple || 0; + this.bastedTurkey = data?.basted_turkey || 0; + this.blazeStick = data?.blaze_stick || 0; + this.bloodyBrick = data?.bloody_brick || 0; + this.bone = data?.bone || 0; + this.campfireLeftovers = data?.campfire_leftovers || 0; + this.carrotOnStick = data?.carrot_on_stick || 0; + this.cheapo = data?.cheapo || 0; + this.cheese = data?.cheese || 0; + this.chewedBush = data?.chewed_bush || 0; + this.diamondShovel = data?.diamond_shovel || 0; + this.doubleDeathScythe = data?.double_death_scythe || 0; + this.dragonEgg = data?.dragon_egg || 0; + this.earthenDagger = data?.earthen_dagger || 0; + this.easterBasket = data?.easter_basket || 0; + this.farmingImplement = data?.farming_implement || 0; + this.feather = data?.feather || 0; + this.fragilePlant = data?.fragile_plant || 0; + this.frisbee = data?.frisbee || 0; + this.glisteningMelon = data?.glistening_melon || 0; + this.goldDigger = data?.gold_digger || 0; + this.grilledSteak = data?.grilled_steak || 0; + this.grimoire = data?.grimoire || 0; + this.iceShard = data?.ice_shard || 0; + this.mouseTrap = data?.mouse_trap || 0; + this.prickly = data?.prickly || 0; + this.pumpkinPie = data?.pumpkin_pie || 0; + this.rudolphsNose = data?.rudolphs_nose || 0; + this.rudolphsSnack = data?.rudolphs_snack || 0; + this.salmon = data?.salmon || 0; + this.scythe = data?.scythe || 0; + this.shears = data?.shears || 0; + this.shinySnack = data?.shiny_snack || 0; + this.shovel = data?.shovel || 0; + this.shred = data?.shred || 0; + this.sprayPaintedShovel = data?.spray_painted_shovel || 0; + this.stake = data?.stake || 0; + this.stick = data?.stick || 0; + this.stickWithHat = data?.stick_with_hat || 0; + this.sweetTreat = data?.sweet_treat || 0; + this.timber = data?.timber || 0; + this.woodAxe = data?.wood_axe || 0; + } +} + +export default MurderMysteryKnifeSkinPrestigeXp; diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.test.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.test.ts new file mode 100644 index 000000000..31948ddeb --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.test.ts @@ -0,0 +1,85 @@ +import MurderMysteryGamemode from './MurderMysteryGamemode.js'; +import MurderMysteryMap from './MurderMysteryMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('MurderMysteryMap', () => { + const data = new MurderMysteryMap({ stats: 'meow' }, 'ancient_tomb'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(MurderMysteryMap); + expectTypeOf(data).toEqualTypeOf(); + expect(data.alphaWins).toBeDefined(); + expect(data.alphaWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.alphaWins).toEqualTypeOf(); + expect(data.bowKills).toBeDefined(); + expect(data.bowKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowKills).toEqualTypeOf(); + expect(data.tokensPickedUp).toBeDefined(); + expect(data.tokensPickedUp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokensPickedUp).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.detectiveWins).toBeDefined(); + expect(data.detectiveWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.detectiveWins).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeGreaterThanOrEqual(0); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.lastOneAlive).toBeDefined(); + expect(data.lastOneAlive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastOneAlive).toEqualTypeOf(); + expect(data.longestTimeAsSurvivorSeconds).toBeDefined(); + expect(data.longestTimeAsSurvivorSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestTimeAsSurvivorSeconds).toEqualTypeOf(); + expect(data.murdererWins).toBeDefined(); + expect(data.murdererWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.murdererWins).toEqualTypeOf(); + expect(data.quickestDetectiveWinTimeSeconds).toBeDefined(); + expect(data.quickestDetectiveWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestDetectiveWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestMurdererWinTimeSeconds).toBeDefined(); + expect(data.quickestMurdererWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestMurdererWinTimeSeconds).toEqualTypeOf(); + expect(data.quickestShowdownWinTimeSeconds).toBeDefined(); + expect(data.quickestShowdownWinTimeSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickestShowdownWinTimeSeconds).toEqualTypeOf(); + expect(data.showdownPotg).toBeDefined(); + expect(data.showdownPotg).toBeGreaterThanOrEqual(0); + expectTypeOf(data.showdownPotg).toEqualTypeOf(); + expect(data.suicides).toBeDefined(); + expect(data.suicides).toBeGreaterThanOrEqual(0); + expectTypeOf(data.suicides).toEqualTypeOf(); + expect(data.survivorWins).toBeDefined(); + expect(data.survivorWins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.survivorWins).toEqualTypeOf(); + expect(data.totalTimeSurvivedSeconds).toBeDefined(); + expect(data.totalTimeSurvivedSeconds).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalTimeSurvivedSeconds).toEqualTypeOf(); + expect(data.wasHero).toBeDefined(); + expect(data.wasHero).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wasHero).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.assassins).toBeDefined(); + expect(data.assassins).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.assassins).toEqualTypeOf(); + expect(data.classic).toBeDefined(); + expect(data.classic).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.classic).toEqualTypeOf(); + expect(data.doubleUp).toBeDefined(); + expect(data.doubleUp).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.doubleUp).toEqualTypeOf(); + expect(data.hardcode).toBeDefined(); + expect(data.hardcode).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.hardcode).toEqualTypeOf(); + expect(data.infection).toBeDefined(); + expect(data.infection).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.infection).toEqualTypeOf(); + expect(data.showdown).toBeDefined(); + expect(data.showdown).toBeInstanceOf(MurderMysteryGamemode); + expectTypeOf(data.showdown).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.ts b/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.ts new file mode 100644 index 000000000..1d9d59fa3 --- /dev/null +++ b/src/Structures/MiniGames/MurderMystery/MurderMysteryMap.ts @@ -0,0 +1,59 @@ +import MurderMysteryGamemode from './MurderMysteryGamemode.js'; +import type { MurderMysteryMapName } from '../../../Types/Player.js'; + +class MurderMysteryMap { + alphaWins: number; + bowKills: number; + tokensPickedUp: number; + deaths: number; + detectiveWins: number; + games: number; + kills: number; + lastOneAlive: number; + longestTimeAsSurvivorSeconds: number; + murdererWins: number; + quickestDetectiveWinTimeSeconds: number; + quickestMurdererWinTimeSeconds: number; + quickestShowdownWinTimeSeconds: number; + showdownPotg: number; + suicides: number; + survivorWins: number; + totalTimeSurvivedSeconds: number; + wasHero: number; + wins: number; + assassins: MurderMysteryGamemode; + classic: MurderMysteryGamemode; + doubleUp: MurderMysteryGamemode; + hardcode: MurderMysteryGamemode; + infection: MurderMysteryGamemode; + showdown: MurderMysteryGamemode; + constructor(data: Record, map: MurderMysteryMapName) { + this.alphaWins = data?.[`alpha_wins_${map}`] || 0; + this.bowKills = data?.[`bow_kills_${map}`] || 0; + this.tokensPickedUp = data?.[`coins_pickedup_${map}`] || 0; + this.deaths = data?.[`deaths_${map}`] || 0; + this.detectiveWins = data?.[`detective_wins_${map}`] || 0; + this.games = data?.[`games_${map}`] || 0; + this.kills = data?.[`kills_${map}`] || 0; + this.lastOneAlive = data?.[`last_one_alive_${map}`] || 0; + this.longestTimeAsSurvivorSeconds = data?.[`longest_time_as_survivor_seconds_${map}`] || 0; + this.murdererWins = data?.[`murderer_wins_${map}`] || 0; + this.quickestDetectiveWinTimeSeconds = data?.[`quickest_detective_win_time_seconds_${map}`] || 0; + this.quickestMurdererWinTimeSeconds = data?.[`quickest_murderer_win_time_seconds_${map}`] || 0; + this.quickestShowdownWinTimeSeconds = data?.[`quickest_showdown_win_time_seconds_${map}`] || 0; + this.showdownPotg = data?.[`showdown_potg_${map}`] || 0; + this.suicides = data?.[`suicides_${map}`] || 0; + this.survivorWins = data?.[`survivor_wins_${map}`] || 0; + this.totalTimeSurvivedSeconds = data?.[`total_time_survived_seconds_${map}`] || 0; + this.wasHero = data?.[`was_hero_${map}`] || 0; + this.wins = data?.[`wins_${map}`] || 0; + this.assassins = new MurderMysteryGamemode(data, 'MURDER_ASSASSINS', map); + this.classic = new MurderMysteryGamemode(data, 'MURDER_CLASSIC', map); + this.doubleUp = new MurderMysteryGamemode(data, 'MURDER_DOUBLE_UP', map); + this.hardcode = new MurderMysteryGamemode(data, 'MURDER_HARDCORE', map); + this.infection = new MurderMysteryGamemode(data, 'MURDER_INFECTION', map); + this.showdown = new MurderMysteryGamemode(data, 'MURDER_SHOWDOWN', map); + } +} + +export default MurderMysteryMap; diff --git a/src/Structures/MiniGames/Paintball.test.ts b/src/Structures/MiniGames/Paintball.test.ts new file mode 100644 index 000000000..0274ecb3a --- /dev/null +++ b/src/Structures/MiniGames/Paintball.test.ts @@ -0,0 +1,54 @@ +import Paintball from './Paintball.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PaintballHats } from '../../Types/Player.js'; + +test('Paintball', () => { + const data = new Paintball({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Paintball); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.shotsFired).toBeDefined(); + expect(data.shotsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shotsFired).toEqualTypeOf(); + expect(data.killStreaks).toBeDefined(); + expect(data.killStreaks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killStreaks).toEqualTypeOf(); + expect(data.forceFieldTime).toBeDefined(); + expect(data.forceFieldTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.forceFieldTime).toEqualTypeOf(); + expect(data.hat).toBeDefined(); + expectTypeOf(data.hat).toEqualTypeOf(); + expect(data.adrenaline).toBeDefined(); + expect(data.adrenaline).toBeGreaterThanOrEqual(0); + expectTypeOf(data.adrenaline).toEqualTypeOf(); + expect(data.endurance).toBeDefined(); + expect(data.endurance).toBeGreaterThanOrEqual(0); + expectTypeOf(data.endurance).toEqualTypeOf(); + expect(data.fortune).toBeDefined(); + expect(data.fortune).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fortune).toEqualTypeOf(); + expect(data.godfather).toBeDefined(); + expect(data.godfather).toBeGreaterThanOrEqual(0); + expectTypeOf(data.godfather).toEqualTypeOf(); + expect(data.superluck).toBeDefined(); + expect(data.superluck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.superluck).toEqualTypeOf(); + expect(data.transfusion).toBeDefined(); + expect(data.transfusion).toBeGreaterThanOrEqual(0); + expectTypeOf(data.transfusion).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Paintball.ts b/src/Structures/MiniGames/Paintball.ts new file mode 100644 index 000000000..fe080ef25 --- /dev/null +++ b/src/Structures/MiniGames/Paintball.ts @@ -0,0 +1,39 @@ +import Divide from '../../Utils/Divide.js'; +import type { PaintballHats } from '../../Types/Player.js'; + +class Paintball { + coins: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + shotsFired: number; + killStreaks: number; + forceFieldTime: number; + hat: PaintballHats | 'None'; + adrenaline: number; + endurance: number; + fortune: number; + godfather: number; + superluck: number; + transfusion: number; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.shotsFired = data?.shots_fired || 0; + this.killStreaks = data?.killstreaks || 0; + this.forceFieldTime = data?.forcefieldTime || 0; + this.hat = data?.hat || 'None'; + this.adrenaline = data?.adrenaline || 0; + this.endurance = data?.endurance || 0; + this.fortune = data?.fortune || 0; + this.godfather = data?.godfather || 0; + this.superluck = data?.superluck || 0; + this.transfusion = data?.transfusion || 0; + } +} + +export default Paintball; diff --git a/src/Structures/MiniGames/Pit/Pit.test.ts b/src/Structures/MiniGames/Pit/Pit.test.ts new file mode 100644 index 000000000..c71d54ac4 --- /dev/null +++ b/src/Structures/MiniGames/Pit/Pit.test.ts @@ -0,0 +1,95 @@ +import Pit from './Pit.js'; +import PitInventoryItem from './PitInventoryItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PitArmor } from '../../../Types/Player.js'; + +test('Pit', () => { + const data = new Pit({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Pit); + expectTypeOf(data).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expect(data.prestige).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prestige).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xp).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.maxKillStreak).toBeDefined(); + expect(data.maxKillStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxKillStreak).toEqualTypeOf(); + expect(data.playtime).toBeDefined(); + expect(data.playtime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playtime).toEqualTypeOf(); + expect(data.joins).toBeDefined(); + expect(data.joins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.joins).toEqualTypeOf(); + expect(data.damageReceived).toBeDefined(); + expect(data.damageReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageReceived).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); + expect(data.damageRatio).toBeDefined(); + expect(data.damageRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageRatio).toEqualTypeOf(); + expect(data.meleeDamageReceived).toBeDefined(); + expect(data.meleeDamageReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeDamageReceived).toEqualTypeOf(); + expect(data.meleeDamageDealt).toBeDefined(); + expect(data.meleeDamageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeDamageDealt).toEqualTypeOf(); + expect(data.swordHits).toBeDefined(); + expect(data.swordHits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.swordHits).toEqualTypeOf(); + expect(data.leftClicks).toBeDefined(); + expect(data.leftClicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.leftClicks).toEqualTypeOf(); + expect(data.meleeAccuracy).toBeDefined(); + expect(data.meleeAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeAccuracy).toEqualTypeOf(); + expect(data.meleeDamageRatio).toBeDefined(); + expect(data.meleeDamageRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meleeDamageRatio).toEqualTypeOf(); + expect(data.bowDamageReceived).toBeDefined(); + expect(data.bowDamageReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowDamageReceived).toEqualTypeOf(); + expect(data.bowDamageDealt).toBeDefined(); + expect(data.bowDamageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowDamageDealt).toEqualTypeOf(); + expect(data.arrowsHit).toBeDefined(); + expect(data.arrowsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsHit).toEqualTypeOf(); + expect(data.arrowsFired).toBeDefined(); + expect(data.arrowsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsFired).toEqualTypeOf(); + expect(data.bowAccuracy).toBeDefined(); + expect(data.bowAccuracy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowAccuracy).toEqualTypeOf(); + expect(data.bowDamageRatio).toBeDefined(); + expect(data.bowDamageRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowDamageRatio).toEqualTypeOf(); + expect(data.goldenHeadsEaten).toBeDefined(); + expect(data.goldenHeadsEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenHeadsEaten).toEqualTypeOf(); + expect(data.getInventory).toBeDefined(); + expectTypeOf(data.getInventory).toEqualTypeOf<() => Promise>(); + expect(data.getEnterChest).toBeDefined(); + expectTypeOf(data.getEnterChest).toEqualTypeOf<() => Promise>(); + expect(data.getArmor).toBeDefined(); + expectTypeOf(data.getArmor).toEqualTypeOf<() => Promise>(); +}); diff --git a/src/Structures/MiniGames/Pit/Pit.ts b/src/Structures/MiniGames/Pit/Pit.ts new file mode 100644 index 000000000..fe92c99d7 --- /dev/null +++ b/src/Structures/MiniGames/Pit/Pit.ts @@ -0,0 +1,128 @@ +import Divide from '../../../Utils/Divide.js'; +import PitInventoryItem from './PitInventoryItem.js'; +import { decode } from '../../../Utils/SkyBlockUtils.js'; +import { pit } from '../../../Utils/Constants.js'; +import type { PitArmor } from '../../../Types/Player.js'; + +class Pit { + prestige: number; + xp: number; + level: number; + kills: number; + deaths: number; + KDR: number; + assists: number; + maxKillStreak: number; + playtime: number; + joins: number; + damageReceived: number; + damageDealt: number; + damageRatio: number; + meleeDamageReceived: number; + meleeDamageDealt: number; + swordHits: number; + leftClicks: number; + meleeAccuracy: number; + meleeDamageRatio: number; + bowDamageReceived: number; + bowDamageDealt: number; + arrowsHit: number; + arrowsFired: number; + bowAccuracy: number; + bowDamageRatio: number; + goldenHeadsEaten: number; + getInventory: () => Promise; + getEnterChest: () => Promise; + getArmor: () => Promise; + constructor(data: Record) { + this.prestige = data?.profile?.prestiges?.[data?.profile?.prestiges?.length - 1]?.index || 0; + this.xp = data?.profile?.xp || 0; + this.level = + this.calcLevel( + this.prestige, + this.prestige > 0 + ? this.xp - (pit?.Prestiges?.[this.prestige - 1] ? pit?.Prestiges?.[this.prestige - 1]?.SumXp || 0 : 0) + : this.xp + ) ?? 0; + this.kills = data?.pit_stats_ptl?.kills || 0; + this.deaths = data?.pit_stats_ptl?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.assists = data?.pit_stats_ptl?.assists || 0; + this.maxKillStreak = data?.pit_stats_ptl?.max_streak || 0; + this.playtime = (data?.pit_stats_ptl?.playtime_minutes || 0) * 60; + this.joins = data?.pit_stats_ptl?.joins || 0; + this.damageReceived = data?.pit_stats_ptl?.damage_received || 0; + this.damageDealt = data?.pit_stats_ptl?.damage_dealt || 0; + this.damageRatio = Divide(this.damageDealt, this.damageReceived); + this.meleeDamageReceived = data?.pit_stats_ptl?.melee_damage_received || 0; + this.meleeDamageDealt = data?.pit_stats_ptl?.melee_damage_dealt || 0; + this.swordHits = data?.pit_stats_ptl?.sword_hits || 0; + this.leftClicks = data?.pit_stats_ptl?.left_clicks || 0; + this.meleeAccuracy = Divide(this.swordHits, this.leftClicks); + this.meleeDamageRatio = Divide(this.meleeDamageDealt, this.meleeDamageReceived); + this.bowDamageReceived = data?.pit_stats_ptl?.bow_damage_received || 0; + this.bowDamageDealt = data?.pit_stats_ptl?.bow_damage_dealt || 0; + this.arrowsHit = data?.pit_stats_ptl?.arrow_hits || 0; + this.arrowsFired = data?.pit_stats_ptl?.arrows_fired || 0; + this.bowAccuracy = Divide(this.arrowsHit, this.arrowsFired); + this.bowDamageRatio = Divide(this.bowDamageDealt, this.bowDamageReceived); + this.goldenHeadsEaten = data?.pit_stats_ptl?.ghead_eaten || 0; + this.getInventory = async (): Promise => { + let inventory = data?.profile?.inv_contents || undefined; + if (!inventory) return []; + inventory = await decode(inventory?.data); + const edited = []; + for (let i = 1; i < inventory?.length; i++) { + if (!inventory[i]?.id) { + continue; + } + edited?.push(new PitInventoryItem(inventory[i])); + } + return edited; + }; + this.getEnterChest = async () => { + let chest = data?.profile?.inv_enderchest || undefined; + if (!chest) return []; + chest = await decode(chest?.data); + const edited = []; + for (let i = 1; i < chest?.length; i++) { + if (!chest[i]?.id) { + continue; + } + edited?.push(new PitInventoryItem(chest[i])); + } + return edited; + }; + this.getArmor = async () => { + const base64 = data?.profile?.inv_armor || undefined; + if (!base64) return { helmet: null, chestplate: null, leggings: null, boots: null }; + const decoded = await decode(base64?.data); + const armor = { + helmet: decoded[3]?.id ? new PitInventoryItem(decoded[3]) : null, + chestplate: decoded[2]?.id ? new PitInventoryItem(decoded[2]) : null, + leggings: decoded[1]?.id ? new PitInventoryItem(decoded[1]) : null, + boots: decoded[0]?.id ? new PitInventoryItem(decoded[0]) : null + }; + return armor; + }; + } + // Credit https://github.com/PitPanda/PitPandaProduction/blob/b1971f56ea1aa8c829b722cbb33247c96591c0cb/Structures/Pit.js + private calcLevel(prestige: number, xp: number): number { + const multiplier = pit?.Prestiges[prestige]?.Multiplier || 0; + let level = 0; + while (xp > 0 && level < 120) { + const levelXp = pit?.Levels?.[Math.floor(level / 10)]?.Xp || 0 * multiplier; + if (xp >= levelXp * 10) { + xp -= levelXp * 10; + level += 10; + } else { + const gain = Math.floor(xp / levelXp); + level += gain; + xp = 0; + } + } + return level; + } +} + +export default Pit; diff --git a/src/Structures/MiniGames/Pit/PitInventoryItem.test.ts b/src/Structures/MiniGames/Pit/PitInventoryItem.test.ts new file mode 100644 index 000000000..88e830cec --- /dev/null +++ b/src/Structures/MiniGames/Pit/PitInventoryItem.test.ts @@ -0,0 +1,23 @@ +import PitInventoryItem from './PitInventoryItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PitInventoryItem', () => { + const data = new PitInventoryItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PitInventoryItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.itemId).toBeDefined(); + expect(data.itemId).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemId).toEqualTypeOf(); + expect(data.count).toBeDefined(); + expect(data.count).toBeGreaterThanOrEqual(0); + expectTypeOf(data.count).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.lore).toBeDefined(); + expectTypeOf(data.lore).toEqualTypeOf(); + expect(data.loreArray).toBeDefined(); + expectTypeOf(data.loreArray).toEqualTypeOf(); + expect(data.extraAttributes).toBeDefined(); + expectTypeOf(data.extraAttributes).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Pit/PitInventoryItem.ts b/src/Structures/MiniGames/Pit/PitInventoryItem.ts new file mode 100644 index 000000000..7b5d3f98f --- /dev/null +++ b/src/Structures/MiniGames/Pit/PitInventoryItem.ts @@ -0,0 +1,20 @@ +class PitInventoryItem { + itemId: number; + count: number; + name: string | null; + lore: string | null; + loreArray: string[]; + extraAttributes: object | null; + constructor(data: Record) { + this.itemId = data?.id || 0; + this.count = data?.Count || 0; + this.name = data?.tag?.display?.Name + ? data?.tag?.display?.Name?.toString().replace(/§([1-9]|[a-f])|§/gm, '') + : null; + this.lore = data?.tag?.display?.Lore ? data?.tag?.display?.Lore?.join('\n') : null; + this.loreArray = data?.tag?.display?.Lore ?? []; + this.extraAttributes = data?.tag?.ExtraAttributes ?? null; + } +} + +export default PitInventoryItem; diff --git a/src/Structures/MiniGames/Quakecraft/Quakecraft.test.ts b/src/Structures/MiniGames/Quakecraft/Quakecraft.test.ts new file mode 100644 index 000000000..20c4aea6c --- /dev/null +++ b/src/Structures/MiniGames/Quakecraft/Quakecraft.test.ts @@ -0,0 +1,70 @@ +import Quakecraft from './Quakecraft.js'; +import QuakecraftMode from './QuakecraftMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorCode } from '../../../Types/Color.js'; +import type { + QuakecraftBarrels, + QuakecraftCase, + QuakecraftKillSounds, + QuakecraftMuzzle, + QuakecraftSights, + QuakecraftTriggers +} from '../../../Types/Player.js'; + +test('Quakecraft', () => { + const data = new Quakecraft({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Quakecraft); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(QuakecraftMode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.teams).toBeDefined(); + expect(data.teams).toBeInstanceOf(QuakecraftMode); + expectTypeOf(data.teams).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.killStreaks).toBeDefined(); + expect(data.killStreaks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killStreaks).toEqualTypeOf(); + expect(data.distanceTraveled).toBeDefined(); + expect(data.distanceTraveled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.distanceTraveled).toEqualTypeOf(); + expect(data.shotsFired).toBeDefined(); + expect(data.shotsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shotsFired).toEqualTypeOf(); + expect(data.headShots).toBeDefined(); + expect(data.headShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headShots).toEqualTypeOf(); + expect(data.instantRespawn).toBeDefined(); + expectTypeOf(data.instantRespawn).toEqualTypeOf(); + expect(data.killPrefixColor).toBeDefined(); + expectTypeOf(data.killPrefixColor).toEqualTypeOf(); + expect(data.showPrefix).toBeDefined(); + expectTypeOf(data.showPrefix).toEqualTypeOf(); + expect(data.killSound).toBeDefined(); + expectTypeOf(data.killSound).toEqualTypeOf(); + expect(data.barrel).toBeDefined(); + expectTypeOf(data.barrel).toEqualTypeOf(); + expect(data.case).toBeDefined(); + expectTypeOf(data.case).toEqualTypeOf(); + expect(data.muzzle).toBeDefined(); + expectTypeOf(data.muzzle).toEqualTypeOf(); + expect(data.sight).toBeDefined(); + expectTypeOf(data.sight).toEqualTypeOf(); + expect(data.trigger).toBeDefined(); + expectTypeOf(data.trigger).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Quakecraft/Quakecraft.ts b/src/Structures/MiniGames/Quakecraft/Quakecraft.ts new file mode 100644 index 000000000..3b129ae81 --- /dev/null +++ b/src/Structures/MiniGames/Quakecraft/Quakecraft.ts @@ -0,0 +1,58 @@ +import Divide from '../../../Utils/Divide.js'; +import QuakecraftMode from './QuakecraftMode.js'; +import type { ColorCode } from '../../../Types/Color.js'; +import type { + QuakecraftBarrels, + QuakecraftCase, + QuakecraftKillSounds, + QuakecraftMuzzle, + QuakecraftSights, + QuakecraftTriggers +} from '../../../Types/Player.js'; + +class Quakecraft { + coins: number; + solo: QuakecraftMode; + teams: QuakecraftMode; + wins: number; + kills: number; + deaths: number; + KDR: number; + killStreaks: number; + distanceTraveled: number; + shotsFired: number; + headShots: number; + instantRespawn: boolean; + killPrefixColor: ColorCode; + showPrefix: boolean; + killSound: QuakecraftKillSounds | 'None'; + barrel: QuakecraftBarrels | 'None'; + case: QuakecraftCase | 'None'; + muzzle: QuakecraftMuzzle | 'None'; + sight: QuakecraftSights | 'None'; + trigger: QuakecraftTriggers | 'None'; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.solo = new QuakecraftMode(data); + this.teams = new QuakecraftMode(data, 'teams'); + this.wins = this.solo?.wins + this.teams?.wins; + this.kills = this.solo?.kills + this.teams?.kills; + this.deaths = this.solo?.deaths + this.teams?.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.killStreaks = this.solo?.killStreaks + this.teams?.killStreaks; + this.distanceTraveled = this.solo?.distanceTraveled + this.teams?.distanceTraveled; + this.shotsFired = this.solo?.shotsFired + this.teams?.shotsFired; + this.headShots = this.solo?.headShots + this.teams?.headShots; + this.instantRespawn = data?.instantRespawn || false; + this.killPrefixColor = data?.selectedKillPrefix || ''; + this.showPrefix = data?.showKillPrefix || false; + this.killSound = data?.killsound || 'None'; + this.barrel = data?.barrel || 'None'; + this.case = data?.case || 'None'; + this.muzzle = data?.muzzle || 'None'; + this.sight = data?.sight || 'None'; + this.trigger = data?.trigger || 'None'; + } +} + +export default Quakecraft; diff --git a/src/Structures/MiniGames/Quakecraft/QuakecraftMode.test.ts b/src/Structures/MiniGames/Quakecraft/QuakecraftMode.test.ts new file mode 100644 index 000000000..a5b8ba4b6 --- /dev/null +++ b/src/Structures/MiniGames/Quakecraft/QuakecraftMode.test.ts @@ -0,0 +1,33 @@ +import QuakecraftMode from './QuakecraftMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('QuakecraftMode', () => { + const data = new QuakecraftMode({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(QuakecraftMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.killStreaks).toBeDefined(); + expect(data.killStreaks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killStreaks).toEqualTypeOf(); + expect(data.distanceTraveled).toBeDefined(); + expect(data.distanceTraveled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.distanceTraveled).toEqualTypeOf(); + expect(data.shotsFired).toBeDefined(); + expect(data.shotsFired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shotsFired).toEqualTypeOf(); + expect(data.headShots).toBeDefined(); + expect(data.headShots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headShots).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Quakecraft/QuakecraftMode.ts b/src/Structures/MiniGames/Quakecraft/QuakecraftMode.ts new file mode 100644 index 000000000..05af248e1 --- /dev/null +++ b/src/Structures/MiniGames/Quakecraft/QuakecraftMode.ts @@ -0,0 +1,25 @@ +import Divide from '../../../Utils/Divide.js'; + +class QuakecraftMode { + wins: number; + kills: number; + deaths: number; + KDR: number; + killStreaks: number; + distanceTraveled: number; + shotsFired: number; + headShots: number; + constructor(data: Record, gamemode?: 'teams') { + const mode = gamemode ? `_${gamemode}` : ''; + this.wins = data?.[`wins${mode}`] || 0; + this.kills = data?.[`kills${mode}`] || 0; + this.deaths = data?.[`deaths${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.killStreaks = data?.[`killstreaks${mode}`] || 0; + this.distanceTraveled = data?.[`distance_travelled${mode}`] || 0; + this.shotsFired = data?.[`shots_fired${mode}`] || 0; + this.headShots = data?.[`headshots${mode}`] || 0; + } +} + +export default QuakecraftMode; diff --git a/src/Structures/MiniGames/Shared/BaseKillDeathsType.ts b/src/Structures/MiniGames/Shared/BaseKillDeathsType.ts new file mode 100644 index 000000000..d9c3879b4 --- /dev/null +++ b/src/Structures/MiniGames/Shared/BaseKillDeathsType.ts @@ -0,0 +1,14 @@ +import Divide from '../../../Utils/Divide.ts'; + +class BaseKillsDeathsType { + kills: number; + deaths: number; + ratio: number; + constructor(data: Record) { + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.ratio = Divide(this.kills, this.deaths); + } +} + +export default BaseKillsDeathsType; diff --git a/src/Structures/MiniGames/Shared/Emblem/Emblem.test.ts b/src/Structures/MiniGames/Shared/Emblem/Emblem.test.ts new file mode 100644 index 000000000..f702e32e1 --- /dev/null +++ b/src/Structures/MiniGames/Shared/Emblem/Emblem.test.ts @@ -0,0 +1,19 @@ +import Emblem from './Emblem.js'; +import EmblemColors from './EmblemColors.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BuildBattleEmblemIcon } from '../../../../Types/Player.js'; +import type { ColorCode } from '../../../../Types/Color.js'; + +test('Emblem', () => { + const data = new Emblem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Emblem); + expectTypeOf(data).toEqualTypeOf>(); + expect(data.colorUnlocked).toBeDefined(); + expect(data.colorUnlocked).toBeInstanceOf(EmblemColors); + expectTypeOf(data.colorUnlocked).toEqualTypeOf(); + expect(data.selectedColor).toBeDefined(); + expectTypeOf(data.selectedColor).toEqualTypeOf(); + expect(data.selectedIcon).toBeDefined(); + expectTypeOf(data.selectedIcon).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Shared/Emblem/Emblem.ts b/src/Structures/MiniGames/Shared/Emblem/Emblem.ts new file mode 100644 index 000000000..1c1bd7d5c --- /dev/null +++ b/src/Structures/MiniGames/Shared/Emblem/Emblem.ts @@ -0,0 +1,15 @@ +import EmblemColors from './EmblemColors.js'; +import type { ColorCode } from '../../../../Types/Color.js'; + +class Emblem { + colorUnlocked: EmblemColors; + selectedColor: ColorCode | 'UNKNOWN'; + selectedIcon: Icons | 'UNKNOWN'; + constructor(data: Record) { + this.colorUnlocked = new EmblemColors(data?.color_unlocked || {}); + this.selectedColor = data?.selected_color || 'UNKNOWN'; + this.selectedIcon = data?.selected_icon || 'UNKNOWN'; + } +} + +export default Emblem; diff --git a/src/Structures/MiniGames/Shared/Emblem/EmblemColors.test.ts b/src/Structures/MiniGames/Shared/Emblem/EmblemColors.test.ts new file mode 100644 index 000000000..ffd5aa1ed --- /dev/null +++ b/src/Structures/MiniGames/Shared/Emblem/EmblemColors.test.ts @@ -0,0 +1,37 @@ +import EmblemColors from './EmblemColors.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('EmblemColors', () => { + const data = new EmblemColors({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(EmblemColors); + expectTypeOf(data).toEqualTypeOf(); + expect(data.aqua).toBeDefined(); + expectTypeOf(data.aqua).toEqualTypeOf(); + expect(data.black).toBeDefined(); + expectTypeOf(data.black).toEqualTypeOf(); + expect(data.blue).toBeDefined(); + expectTypeOf(data.blue).toEqualTypeOf(); + expect(data.darkAqua).toBeDefined(); + expectTypeOf(data.darkAqua).toEqualTypeOf(); + expect(data.darkBlue).toBeDefined(); + expectTypeOf(data.darkBlue).toEqualTypeOf(); + expect(data.darkGray).toBeDefined(); + expectTypeOf(data.darkGray).toEqualTypeOf(); + expect(data.darkGreen).toBeDefined(); + expectTypeOf(data.darkGreen).toEqualTypeOf(); + expect(data.darkPurple).toBeDefined(); + expectTypeOf(data.darkPurple).toEqualTypeOf(); + expect(data.darkRed).toBeDefined(); + expectTypeOf(data.darkRed).toEqualTypeOf(); + expect(data.gray).toBeDefined(); + expectTypeOf(data.gray).toEqualTypeOf(); + expect(data.green).toBeDefined(); + expectTypeOf(data.green).toEqualTypeOf(); + expect(data.lightPurple).toBeDefined(); + expectTypeOf(data.lightPurple).toEqualTypeOf(); + expect(data.red).toBeDefined(); + expectTypeOf(data.red).toEqualTypeOf(); + expect(data.yellow).toBeDefined(); + expectTypeOf(data.yellow).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Shared/Emblem/EmblemColors.ts b/src/Structures/MiniGames/Shared/Emblem/EmblemColors.ts new file mode 100644 index 000000000..2e39df1b3 --- /dev/null +++ b/src/Structures/MiniGames/Shared/Emblem/EmblemColors.ts @@ -0,0 +1,34 @@ +class EmblemColors { + aqua: boolean; + black: boolean; + blue: boolean; + darkAqua: boolean; + darkBlue: boolean; + darkGray: boolean; + darkGreen: boolean; + darkPurple: boolean; + darkRed: boolean; + gray: boolean; + green: boolean; + lightPurple: boolean; + red: boolean; + yellow: boolean; + constructor(data: Record) { + this.aqua = data?.aqua || false; + this.black = data?.black || false; + this.blue = data?.blue || false; + this.darkAqua = data?.dark_aqua || false; + this.darkBlue = data?.dark_blue || false; + this.darkGray = data?.dark_gray || false; + this.darkGreen = data?.dark_green || false; + this.darkPurple = data?.dark_purple || false; + this.darkRed = data?.dark_red || false; + this.gray = data?.gray || false; + this.green = data?.green || false; + this.lightPurple = data?.light_purple || false; + this.red = data?.red || false; + this.yellow = data?.yellow || false; + } +} + +export default EmblemColors; diff --git a/src/Structures/MiniGames/Shared/LeaderboardSettings.test.ts b/src/Structures/MiniGames/Shared/LeaderboardSettings.test.ts new file mode 100644 index 000000000..bb0b4c018 --- /dev/null +++ b/src/Structures/MiniGames/Shared/LeaderboardSettings.test.ts @@ -0,0 +1,14 @@ +import LeaderboardSettings from './LeaderboardSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BuildBattleLeaderboardSettingsMode, LeaderboardSettingsResetType } from '../../../Types/Player.js'; + +test('LeaderboardSettings', () => { + const data = new LeaderboardSettings({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(LeaderboardSettings); + expectTypeOf(data).toEqualTypeOf>(); + expect(data.mode).toBeDefined(); + expectTypeOf(data.mode).toEqualTypeOf(); + expect(data.resetType).toBeDefined(); + expectTypeOf(data.resetType).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Shared/LeaderboardSettings.ts b/src/Structures/MiniGames/Shared/LeaderboardSettings.ts new file mode 100644 index 000000000..a10d42e02 --- /dev/null +++ b/src/Structures/MiniGames/Shared/LeaderboardSettings.ts @@ -0,0 +1,12 @@ +import type { LeaderboardSettingsResetType } from '../../../Types/Player.js'; + +class LeaderboardSettings { + mode: ModeType | 'UNKNOWN'; + resetType: LeaderboardSettingsResetType | 'UNKNOWN'; + constructor(data: Record) { + this.mode = data?.mode || 'UNKNOWN'; + this.resetType = data?.resetType || 'UNKNOWN'; + } +} + +export default LeaderboardSettings; diff --git a/src/Structures/MiniGames/SkyWars/SkyWars.test.ts b/src/Structures/MiniGames/SkyWars/SkyWars.test.ts new file mode 100644 index 000000000..c40aca42e --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWars.test.ts @@ -0,0 +1,153 @@ +import SkyWars from './SkyWars.js'; +import SkyWarsKitsMythics from './SkyWarsKitsMythics/SkyWarsKitsMythics.js'; +import SkyWarsMega from './SkyWarsMega/SkyWarsMega.js'; +import SkyWarsMini from './SkyWarsMini.js'; +import SkyWarsPrivateGames from './SkyWarsPrivateGames.js'; +import SkyWarsSolo from './SkyWarsSolo/SkyWarsSolo.js'; +import SkyWarsTeams from './SkyWarsTeams/SkyWarsTeams.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ShopSort } from '../../../Types/Player.js'; + +test('SkyWars', () => { + const data = new SkyWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeKillEffect).toBeDefined(); + expectTypeOf(data.activeKillEffect).toEqualTypeOf(); + expect(data.activeVictoryDance).toBeDefined(); + expectTypeOf(data.activeVictoryDance).toEqualTypeOf(); + expect(data.activeKillMessages).toBeDefined(); + expectTypeOf(data.activeKillMessages).toEqualTypeOf(); + expect(data.activeDeathCry).toBeDefined(); + expectTypeOf(data.activeDeathCry).toEqualTypeOf(); + expect(data.activeBalloon).toBeDefined(); + expectTypeOf(data.activeBalloon).toEqualTypeOf(); + expect(data.activeCage).toBeDefined(); + expectTypeOf(data.activeCage).toEqualTypeOf(); + expect(data.activeSprays).toBeDefined(); + expectTypeOf(data.activeSprays).toEqualTypeOf(); + expect(data.activeProjectileTrail).toBeDefined(); + expectTypeOf(data.activeProjectileTrail).toEqualTypeOf(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.tokens).toBeDefined(); + expect(data.tokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokens).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xp).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.levelWithProgress).toBeDefined(); + expectTypeOf(data.levelWithProgress).toEqualTypeOf<{ currentXp: number; required: number }>(); + expect(data.levelFormatted).toBeDefined(); + expectTypeOf(data.levelFormatted).toEqualTypeOf(); + expect(data.mythicalKits).toBeDefined(); + expect(data.mythicalKits).toBeInstanceOf(SkyWarsKitsMythics); + expectTypeOf(data.mythicalKits).toEqualTypeOf(); + expect(data.selectedPrestigeIcon).toBeDefined(); + expectTypeOf(data.selectedPrestigeIcon).toEqualTypeOf(); + expect(data.angelOfDeathLevel).toBeDefined(); + expect(data.angelOfDeathLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.angelOfDeathLevel).toEqualTypeOf(); + expect(data.quits).toBeDefined(); + expect(data.quits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quits).toEqualTypeOf(); + expect(data.souls).toBeDefined(); + expect(data.souls).toBeGreaterThanOrEqual(0); + expectTypeOf(data.souls).toEqualTypeOf(); + expect(data.soulWell).toBeDefined(); + expect(data.soulWell).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soulWell).toEqualTypeOf(); + expect(data.soulsGathered).toBeDefined(); + expect(data.soulsGathered).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soulsGathered).toEqualTypeOf(); + expect(data.paidSouls).toBeDefined(); + expect(data.paidSouls).toBeGreaterThanOrEqual(0); + expectTypeOf(data.paidSouls).toEqualTypeOf(); + expect(data.soulWellRares).toBeDefined(); + expect(data.soulWellRares).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soulWellRares).toEqualTypeOf(); + expect(data.soulWellLegendaries).toBeDefined(); + expect(data.soulWellLegendaries).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soulWellLegendaries).toEqualTypeOf(); + expect(data.refillChestDestroy).toBeDefined(); + expect(data.refillChestDestroy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.refillChestDestroy).toEqualTypeOf(); + expect(data.harvestingSeason).toBeDefined(); + expect(data.harvestingSeason).toBeGreaterThanOrEqual(0); + expectTypeOf(data.harvestingSeason).toEqualTypeOf(); + expect(data.xezbethLuck).toBeDefined(); + expect(data.xezbethLuck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xezbethLuck).toEqualTypeOf(); + expect(data.extraWheels).toBeDefined(); + expect(data.extraWheels).toBeGreaterThanOrEqual(0); + expectTypeOf(data.extraWheels).toEqualTypeOf(); + expect(data.weeklyKills).toBeDefined(); + expect(data.weeklyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKills).toEqualTypeOf(); + expect(data.weeklyKillsA).toBeDefined(); + expect(data.weeklyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsA).toEqualTypeOf(); + expect(data.weeklyKillsB).toBeDefined(); + expect(data.weeklyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.weeklyKillsB).toEqualTypeOf(); + expect(data.monthlyKills).toBeDefined(); + expect(data.monthlyKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKills).toEqualTypeOf(); + expect(data.monthlyKillsA).toBeDefined(); + expect(data.monthlyKillsA).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsA).toEqualTypeOf(); + expect(data.monthlyKillsB).toBeDefined(); + expect(data.monthlyKillsB).toBeGreaterThanOrEqual(0); + expectTypeOf(data.monthlyKillsB).toEqualTypeOf(); + expect(data.quickjoinUsesTotal).toBeDefined(); + expect(data.quickjoinUsesTotal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickjoinUsesTotal).toEqualTypeOf(); + expect(data.quickjoinUsesRandom).toBeDefined(); + expect(data.quickjoinUsesRandom).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quickjoinUsesRandom).toEqualTypeOf(); + expect(data.chests).toBeDefined(); + expect(data.chests).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chests).toEqualTypeOf(); + expect(data.chestHistory).toBeDefined(); + expectTypeOf(data.chestHistory).toEqualTypeOf(); + expect(data.goldenBoxes).toBeDefined(); + expect(data.goldenBoxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldenBoxes).toEqualTypeOf(); + expect(data.halloweenBoxes).toBeDefined(); + expect(data.halloweenBoxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.halloweenBoxes).toEqualTypeOf(); + expect(data.christmasBoxes).toBeDefined(); + expect(data.christmasBoxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.christmasBoxes).toEqualTypeOf(); + expect(data.lunarBoxes).toBeDefined(); + expect(data.lunarBoxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lunarBoxes).toEqualTypeOf(); + expect(data.easterBoxes).toBeDefined(); + expect(data.easterBoxes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.easterBoxes).toEqualTypeOf(); + expect(data.beastChance).toBeDefined(); + expect(data.beastChance).toBeGreaterThanOrEqual(0); + expectTypeOf(data.beastChance).toEqualTypeOf(); + expect(data.privateGamesSettings).toBeDefined(); + expect(data.privateGamesSettings).toBeInstanceOf(SkyWarsPrivateGames); + expectTypeOf(data.privateGamesSettings).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(SkyWarsSolo); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.teams).toBeDefined(); + expect(data.teams).toBeInstanceOf(SkyWarsTeams); + expectTypeOf(data.teams).toEqualTypeOf(); + expect(data.mega).toBeDefined(); + expect(data.mega).toBeInstanceOf(SkyWarsMega); + expectTypeOf(data.mega).toEqualTypeOf(); + expect(data.mini).toBeDefined(); + expect(data.mini).toBeInstanceOf(SkyWarsMini); + expectTypeOf(data.mini).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWars.ts b/src/Structures/MiniGames/SkyWars/SkyWars.ts new file mode 100644 index 000000000..b6ce77f27 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWars.ts @@ -0,0 +1,164 @@ +import SkyWarsKitsMythics from './SkyWarsKitsMythics/SkyWarsKitsMythics.ts'; +import SkyWarsMega from './SkyWarsMega/SkyWarsMega.ts'; +import SkyWarsMini from './SkyWarsMini.ts'; +import SkyWarsMode from './SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsPrivateGames from './SkyWarsPrivateGames.ts'; +import SkyWarsSolo from './SkyWarsSolo/SkyWarsSolo.ts'; +import SkyWarsTeams from './SkyWarsTeams/SkyWarsTeams.js'; +import { + SKYWARS_CONSTANT_LEVELING_XP, + SKYWARS_CONSTANT_XP_TO_NEXT_LEVEL, + SKYWARS_LEVEL_MAX, + SKYWARS_TOTAL_XP, + SKYWARS_XP_TO_NEXT_LEVEL +} from '../../../Utils/Constants.ts'; +import { weekAB } from '../../../Utils/Oscillation.ts'; +import type { ShopSort } from '../../../Types/Player.ts'; + +class SkyWars extends SkyWarsMode { + activeKillEffect: string | 'UNKNOWN'; + activeVictoryDance: string | 'UNKNOWN'; + activeKillMessages: string | 'UNKNOWN'; + activeDeathCry: string | 'UNKNOWN'; + activeBalloon: string | 'UNKNOWN'; + activeCage: string | 'UNKNOWN'; + activeSprays: string | 'UNKNOWN'; + activeProjectileTrail: string | 'UNKNOWN'; + shopSort: ShopSort | 'UNKNOWN'; + coins: number; + tokens: number; + xp: number; + level: number; + levelWithProgress: { currentXp: number; required: number }; + levelFormatted: string | null; + mythicalKits: SkyWarsKitsMythics; + selectedPrestigeIcon: string | 'UNKNOWN'; + angelOfDeathLevel: number; + quits: number; + souls: number; + soulWell: number; + soulsGathered: number; + paidSouls: number; + soulWellRares: number; + soulWellLegendaries: number; + refillChestDestroy: number; + harvestingSeason: number; + xezbethLuck: number; + extraWheels: number; + weeklyKills: number; + weeklyKillsA: number; + weeklyKillsB: number; + monthlyKills: number; + monthlyKillsA: number; + monthlyKillsB: number; + quickjoinUsesTotal: number; + quickjoinUsesRandom: number; + chests: number; + chestHistory: string[]; + goldenBoxes: number; + halloweenBoxes: number; + christmasBoxes: number; + lunarBoxes: number; + easterBoxes: number; + beastChance: number; + privateGamesSettings: SkyWarsPrivateGames; + solo: SkyWarsSolo; + teams: SkyWarsTeams; + mega: SkyWarsMega; + mini: SkyWarsMini; + ranked: SkyWarsMode; + constructor(data: Record) { + super(data); + this.activeKillEffect = data?.active_killeffect || 'UNKNOWN'; + this.activeVictoryDance = data?.active_victorydance || 'UNKNOWN'; + this.activeKillMessages = data?.active_killmessages || 'UNKNOWN'; + this.activeDeathCry = data?.active_deathcry || 'UNKNOWN'; + this.activeBalloon = data?.active_balloon || 'UNKNOWN'; + this.activeCage = data?.active_cage || 'UNKNOWN'; + this.activeSprays = data?.active_sprays || 'UNKNOWN'; + this.activeProjectileTrail = data?.active_projectiletrail || 'UNKNOWN'; + this.shopSort = data?.shop_sort || 'UNKNOWN'; + this.coins = data?.coins || 0; + this.tokens = data?.cosmetic_tokens || 0; + this.heads = data?.heads || 0; + this.xp = data?.skywars_experience || 0; + this.level = SkyWars.getLevel(this.xp); + this.levelWithProgress = SkyWars.getLevelProgress(this.xp, this.level); + this.levelFormatted = data?.levelFormatted + ? data?.levelFormatted + ?.replace(/§l/gm, '**') + ?.replace(/§([a-f]|[1-9])/gm, '') + ?.replace(/§r/gm, '') + : null; + this.mythicalKits = new SkyWarsKitsMythics(data); + this.selectedPrestigeIcon = data?.selected_prestige_icon || 'UNKNOWN'; + this.angelOfDeathLevel = data?.angel_of_death_level || 0; + this.quits = data?.quits || 0; + this.souls = data?.souls || 0; + this.soulWell = data?.soul_well || 0; + this.soulsGathered = data?.souls_gathered || 0; + this.paidSouls = data?.paid_souls || 0; + this.soulWellRares = data?.soul_well_rares || 0; + this.soulWellLegendaries = data?.soul_well_legendaries || 0; + this.refillChestDestroy = data?.refill_chest_destroy || 0; + this.harvestingSeason = data?.harvesting_season || 0; + this.xezbethLuck = data?.xezbeth_luck || 0; + this.extraWheels = data?.extra_wheels || 0; + this.weeklyKills = parseInt(data?.[`kills_weekly_${weekAB()}`] || 0, 10); + this.weeklyKillsA = data?.kills_weekly_a || 0; + this.weeklyKillsB = data?.kills_weekly_b || 0; + this.monthlyKills = parseInt(data?.[`kills_monthly_${weekAB()}`] || 0, 10); + this.monthlyKillsA = data?.kills_monthly_a || 0; + this.monthlyKillsB = data?.kills_monthly_b || 0; + this.quickjoinUsesTotal = data?.quickjoin_uses_total || 0; + this.quickjoinUsesRandom = data?.quickjoin_uses_random || 0; + this.chests = data?.skywars_chests || 0; + this.chestHistory = data?.skywars_chest_history || []; + this.goldenBoxes = data?.skywars_golden_boxes || 0; + this.halloweenBoxes = data?.skywars_halloween_boxes || 0; + this.christmasBoxes = data?.skywars_christmas_boxes || 0; + this.lunarBoxes = data?.skywars_lunar_boxes || 0; + this.easterBoxes = data?.skywars_easter_boxes || 0; + this.beastChance = data?.beast_chance || 0; + this.privateGamesSettings = new SkyWarsPrivateGames(data?.privategames || {}); + this.solo = new SkyWarsSolo(data); + this.teams = new SkyWarsTeams(data); + this.mega = new SkyWarsMega(data); + this.mini = new SkyWarsMini(data); + this.ranked = new SkyWarsMode(data, 'ranked'); + } + + // Credit: https://github.com/Statsify/statsify/blob/main/packages/schemas/src/player/gamemodes/skywars/util.ts#L27-L38 + static getLevel(xp: number): number { + if (xp >= SKYWARS_CONSTANT_LEVELING_XP) { + const level = + Math.floor((xp - SKYWARS_CONSTANT_LEVELING_XP) / SKYWARS_CONSTANT_XP_TO_NEXT_LEVEL) + + SKYWARS_XP_TO_NEXT_LEVEL.length; + + return Math.min(level, SKYWARS_LEVEL_MAX); + } + + const level = SKYWARS_TOTAL_XP.findIndex((x) => x > xp); + return level; + } + + // Credit: https://github.com/Statsify/statsify/blob/main/packages/schemas/src/player/gamemodes/skywars/util.ts#L40-L63 + static getLevelProgress(xp: number, level: number): { currentXp: number; required: number } { + let currentXp = xp; + + if (xp >= SKYWARS_CONSTANT_LEVELING_XP) { + currentXp -= SKYWARS_CONSTANT_LEVELING_XP; + currentXp %= SKYWARS_CONSTANT_XP_TO_NEXT_LEVEL; + return { currentXp, required: level >= SKYWARS_LEVEL_MAX ? 0 : SKYWARS_CONSTANT_XP_TO_NEXT_LEVEL }; + } + + for (const element of SKYWARS_XP_TO_NEXT_LEVEL) { + if (currentXp < element) break; + currentXp -= element; + } + + return { currentXp, required: SKYWARS_XP_TO_NEXT_LEVEL[SKYWARS_TOTAL_XP.findIndex((x) => x > xp)] || 0 }; + } +} + +export default SkyWars; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsHeads.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsHeads.test.ts new file mode 100644 index 000000000..bebd31691 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsHeads.test.ts @@ -0,0 +1,51 @@ +import SkyWarsHeads from './SkyWarsHeads.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsHeads', () => { + const data = new SkyWarsHeads({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsHeads); + expectTypeOf(data).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.tasty).toBeDefined(); + expect(data.tasty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tasty).toEqualTypeOf(); + expect(data.yucky).toBeDefined(); + expect(data.yucky).toBeGreaterThanOrEqual(0); + expectTypeOf(data.yucky).toEqualTypeOf(); + expect(data.eww).toBeDefined(); + expect(data.eww).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eww).toEqualTypeOf(); + expect(data.salty).toBeDefined(); + expect(data.salty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.salty).toEqualTypeOf(); + expect(data.divine).toBeDefined(); + expect(data.divine).toBeGreaterThanOrEqual(0); + expectTypeOf(data.divine).toEqualTypeOf(); + expect(data.heavenly).toBeDefined(); + expect(data.heavenly).toBeGreaterThanOrEqual(0); + expectTypeOf(data.heavenly).toEqualTypeOf(); + expect(data.decent).toBeDefined(); + expect(data.decent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.decent).toEqualTypeOf(); + expect(data.meh).toBeDefined(); + expect(data.meh).toBeGreaterThanOrEqual(0); + expectTypeOf(data.meh).toEqualTypeOf(); + expect(data.succulent).toBeDefined(); + expect(data.succulent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.succulent).toEqualTypeOf(); + expect(data.sweet).toBeDefined(); + expect(data.sweet).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sweet).toEqualTypeOf(); + expect(data.ethereal).toBeDefined(); + expect(data.ethereal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ethereal).toEqualTypeOf(); + expect(data.indescribable).toBeDefined(); + expect(data.indescribable).toBeGreaterThanOrEqual(0); + expectTypeOf(data.indescribable).toEqualTypeOf(); + expect(data.special).toBeDefined(); + expect(data.special).toBeGreaterThanOrEqual(0); + expectTypeOf(data.special).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsHeads.ts b/src/Structures/MiniGames/SkyWars/SkyWarsHeads.ts new file mode 100644 index 000000000..98c1e7309 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsHeads.ts @@ -0,0 +1,38 @@ +import { ParseModeAfter } from '../../../Utils/ParseMode.ts'; +import type { SkyWarsKitId, SkyWarsModeId } from '../../../Types/Player.ts'; + +class SkyWarsHeads { + total: number; + tasty: number; + yucky: number; + eww: number; + salty: number; + divine: number; + heavenly: number; + decent: number; + meh: number; + succulent: number; + sweet: number; + ethereal: number; + indescribable: number; + special: number; + constructor(data: Record, mode?: SkyWarsModeId | SkyWarsKitId) { + mode = ParseModeAfter(mode) as SkyWarsModeId; + this.total = data?.[`heads${mode}`] || 0; + this.tasty = data?.[`heads_tasty${mode}`] || 0; + this.yucky = data?.[`heads_yucky${mode}`] || 0; + this.eww = data?.[`heads_eww${mode}`] || 0; + this.salty = data?.[`heads_salty${mode}`] || 0; + this.divine = data?.[`heads_divine${mode}`] || 0; + this.heavenly = data?.[`heads_heavenly${mode}`] || 0; + this.decent = data?.[`heads_decent${mode}`] || 0; + this.meh = data?.[`heads_meh${mode}`] || 0; + this.succulent = data?.[`heads_succulent${mode}`] || 0; + this.sweet = data?.[`heads_sweet${mode}`] || 0; + this.ethereal = data?.[`heads_ethereal${mode}`] || 0; + this.indescribable = data?.[`heads_indescribable${mode}`] || 0; + this.special = data?.[`heads_special${mode}`] || 0; + } +} + +export default SkyWarsHeads; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.test.ts new file mode 100644 index 000000000..e4e6e631c --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.test.ts @@ -0,0 +1,28 @@ +import SkyWarsKillsDeaths from './SkyWarsKillsDeaths.js'; +import SkyWarsKillsDeathsType from './SkyWarsKillsDeathsType.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsKillsDeaths', () => { + const data = new SkyWarsKillsDeaths({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsKillsDeaths); + expectTypeOf(data).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.melee).toBeDefined(); + expect(data.melee).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.melee).toEqualTypeOf(); + expect(data.void).toBeDefined(); + expect(data.void).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.void).toEqualTypeOf(); + expect(data.bow).toBeDefined(); + expect(data.bow).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.bow).toEqualTypeOf(); + expect(data.mob).toBeDefined(); + expect(data.mob).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.mob).toEqualTypeOf(); + expect(data.fall).toBeDefined(); + expect(data.fall).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data.fall).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.ts new file mode 100644 index 000000000..cde17d44c --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.ts @@ -0,0 +1,23 @@ +import SkyWarsKillsDeathsType from './SkyWarsKillsDeathsType.ts'; +import { ParseModeAfter } from '../../../Utils/ParseMode.ts'; +import type { SkyWarsKitId, SkyWarsModeId } from '../../../Types/Player.ts'; + +class SkyWarsKillsDeaths { + total: SkyWarsKillsDeathsType; + melee: SkyWarsKillsDeathsType; + void: SkyWarsKillsDeathsType; + bow: SkyWarsKillsDeathsType; + mob: SkyWarsKillsDeathsType; + fall: SkyWarsKillsDeathsType; + constructor(data: Record, mode?: SkyWarsModeId | SkyWarsKitId) { + mode = ParseModeAfter(mode) as SkyWarsModeId; + this.total = new SkyWarsKillsDeathsType(data, '', mode); + this.melee = new SkyWarsKillsDeathsType(data, 'melee', mode); + this.void = new SkyWarsKillsDeathsType(data, 'void', mode); + this.bow = new SkyWarsKillsDeathsType(data, 'bow', mode); + this.mob = new SkyWarsKillsDeathsType(data, 'mob', mode); + this.fall = new SkyWarsKillsDeathsType(data, 'fall', mode); + } +} + +export default SkyWarsKillsDeaths; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.test.ts new file mode 100644 index 000000000..fff407229 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.test.ts @@ -0,0 +1,9 @@ +import SkyWarsKillsDeathsType from './SkyWarsKillsDeathsType.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsKillsDeathsType', () => { + const data = new SkyWarsKillsDeathsType({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsKillsDeathsType); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.ts new file mode 100644 index 000000000..40ef6cf2d --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.ts @@ -0,0 +1,17 @@ +import BaseKillsDeathsType from '../Shared/BaseKillDeathsType.ts'; +import Divide from '../../../Utils/Divide.ts'; +import { ParseModeAfter, ParseModeBefore } from '../../../Utils/ParseMode.ts'; +import type { SkyWarsKillType, SkyWarsKitId, SkyWarsModeId } from '../../../Types/Player.ts'; + +class SkyWarsKillsDeathsType extends BaseKillsDeathsType { + constructor(data: Record, type?: SkyWarsKillType, mode?: SkyWarsModeId | SkyWarsKitId) { + type = ParseModeBefore(type) as SkyWarsKillType; + mode = ParseModeAfter(mode) as SkyWarsModeId; + super(data); + this.kills = data?.[`${type}kills${mode}`] || 0; + this.deaths = data?.[`${type}deaths${mode}`] || 0; + this.ratio = Divide(this.kills, this.deaths); + } +} + +export default SkyWarsKillsDeathsType; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.test.ts new file mode 100644 index 000000000..b2e3a8afc --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.test.ts @@ -0,0 +1,14 @@ +import SkyWarsKitsMythic from './SkyWarsKitsMythic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsKitsMythic', () => { + const data = new SkyWarsKitsMythic({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data).toEqualTypeOf(); + expect(data.autoEquipArmor).toBeDefined(); + expectTypeOf(data.autoEquipArmor).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xp).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.ts new file mode 100644 index 000000000..3beea15d2 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.ts @@ -0,0 +1,16 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.ts'; +import { ParseModeAfter, ParseModeBefore } from '../../../../Utils/ParseMode.ts'; +import type { SkyWarsMythicKitId } from '../../../../Types/Player.ts'; + +class SkyWarsKitsMythic extends BaseSkyWarsMode { + autoEquipArmor: boolean; + xp: number; + constructor(data: Record, kit?: SkyWarsMythicKitId) { + kit = ParseModeAfter(kit) as SkyWarsMythicKitId; + super(data, kit); + this.autoEquipArmor = data?.[`${ParseModeBefore(kit)}inventory_auto_equip_armor`] || true; + this.xp = data?.[`xp${kit}`] || 0; + } +} + +export default SkyWarsKitsMythic; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.test.ts new file mode 100644 index 000000000..2124e0efb --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.test.ts @@ -0,0 +1,31 @@ +import SkyWarsKitsMythic from './SkyWarsKitsMythic.js'; +import SkyWarsKitsMythics from './SkyWarsKitsMythics.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsKitsMythics', () => { + const data = new SkyWarsKitsMythics({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsKitsMythics); + expectTypeOf(data).toEqualTypeOf(); + expect(data.chronobreaker).toBeDefined(); + expect(data.chronobreaker).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.chronobreaker).toEqualTypeOf(); + expect(data.netherLord).toBeDefined(); + expect(data.netherLord).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.netherLord).toEqualTypeOf(); + expect(data.endLord).toBeDefined(); + expect(data.endLord).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.endLord).toEqualTypeOf(); + expect(data.monsterTrainer).toBeDefined(); + expect(data.monsterTrainer).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.monsterTrainer).toEqualTypeOf(); + expect(data.cryomancer).toBeDefined(); + expect(data.cryomancer).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.cryomancer).toEqualTypeOf(); + expect(data.thundermeister).toBeDefined(); + expect(data.thundermeister).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.thundermeister).toEqualTypeOf(); + expect(data.fishmonger).toBeDefined(); + expect(data.fishmonger).toBeInstanceOf(SkyWarsKitsMythic); + expectTypeOf(data.fishmonger).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.ts b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.ts new file mode 100644 index 000000000..47f5f92f0 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.ts @@ -0,0 +1,22 @@ +import SkyWarsKitsMythic from './SkyWarsKitsMythic.ts'; + +class SkyWarsKitsMythics { + chronobreaker: SkyWarsKitsMythic; + netherLord: SkyWarsKitsMythic; + endLord: SkyWarsKitsMythic; + monsterTrainer: SkyWarsKitsMythic; + cryomancer: SkyWarsKitsMythic; + thundermeister: SkyWarsKitsMythic; + fishmonger: SkyWarsKitsMythic; + constructor(data: Record) { + this.chronobreaker = new SkyWarsKitsMythic(data, 'kit_mythical_chronobreaker'); + this.netherLord = new SkyWarsKitsMythic(data, 'kit_mythical_nether-lord'); + this.endLord = new SkyWarsKitsMythic(data, 'kit_mythical_end-lord'); + this.monsterTrainer = new SkyWarsKitsMythic(data, 'kit_mythical_monster-trainer'); + this.cryomancer = new SkyWarsKitsMythic(data, 'kit_mythical_cryomancer'); + this.thundermeister = new SkyWarsKitsMythic(data, 'kit_mythical_thundermeister'); + this.fishmonger = new SkyWarsKitsMythic(data, 'kit_mythical_fishmonger'); + } +} + +export default SkyWarsKitsMythics; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.test.ts new file mode 100644 index 000000000..ead59da72 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.test.ts @@ -0,0 +1,75 @@ +import SkyWarsMega from './SkyWarsMega.js'; +import SkyWarsMegaKits from './SkyWarsMegaKits.js'; +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsMega', () => { + const data = new SkyWarsMega({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsMega); + expectTypeOf(data).toEqualTypeOf(); + expect(data.doubles).toBeDefined(); + expect(data.doubles).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.doubles).toEqualTypeOf(); + expect(data.doublesNormal).toBeDefined(); + expect(data.doublesNormal).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.doublesNormal).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.kits).toBeDefined(); + expect(data.kits).toBeInstanceOf(SkyWarsMegaKits); + expectTypeOf(data.kits).toEqualTypeOf(); + expect(data.rusher).toBeDefined(); + expect(data.rusher).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.rusher).toEqualTypeOf(); + expect(data.miningExpertise).toBeDefined(); + expect(data.miningExpertise).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.miningExpertise).toEqualTypeOf(); + expect(data.enderMastery).toBeDefined(); + expect(data.enderMastery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.enderMastery).toEqualTypeOf(); + expect(data.blazingArrows).toBeDefined(); + expect(data.blazingArrows).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blazingArrows).toEqualTypeOf(); + expect(data.arrowRecovery).toBeDefined(); + expect(data.arrowRecovery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.arrowRecovery).toEqualTypeOf(); + expect(data.juggernaut).toBeDefined(); + expect(data.juggernaut).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.juggernaut).toEqualTypeOf(); + expect(data.tank).toBeDefined(); + expect(data.tank).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.tank).toEqualTypeOf(); + expect(data.nourishment).toBeDefined(); + expect(data.nourishment).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.nourishment).toEqualTypeOf(); + expect(data.notoriety).toBeDefined(); + expect(data.notoriety).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.notoriety).toEqualTypeOf(); + expect(data.instantSmelting).toBeDefined(); + expect(data.instantSmelting).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.instantSmelting).toEqualTypeOf(); + expect(data.marksmanship).toBeDefined(); + expect(data.marksmanship).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.marksmanship).toEqualTypeOf(); + expect(data.environmentalExpert).toBeDefined(); + expect(data.environmentalExpert).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.environmentalExpert).toEqualTypeOf(); + expect(data.bridger).toBeDefined(); + expect(data.bridger).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.bridger).toEqualTypeOf(); + expect(data.luckyCharm).toBeDefined(); + expect(data.luckyCharm).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.luckyCharm).toEqualTypeOf(); + expect(data.blackMagic).toBeDefined(); + expect(data.blackMagic).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blackMagic).toEqualTypeOf(); + expect(data.necromancer).toBeDefined(); + expect(data.necromancer).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.necromancer).toEqualTypeOf(); + expect(data.telekinesis).toBeDefined(); + expect(data.telekinesis).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.telekinesis).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.ts new file mode 100644 index 000000000..c7ddece02 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.ts @@ -0,0 +1,53 @@ +import SkyWarsMegaKits from './SkyWarsMegaKits.ts'; +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.js'; + +class SkyWarsMega extends SkyWarsMode { + doubles: SkyWarsMode; + doublesNormal: SkyWarsMode; + normal: SkyWarsMode; + kits: SkyWarsMegaKits; + rusher: SkyWarsModePerk; + miningExpertise: SkyWarsModePerk; + enderMastery: SkyWarsModePerk; + blazingArrows: SkyWarsModePerk; + arrowRecovery: SkyWarsModePerk; + juggernaut: SkyWarsModePerk; + tank: SkyWarsModePerk; + nourishment: SkyWarsModePerk; + notoriety: SkyWarsModePerk; + instantSmelting: SkyWarsModePerk; + marksmanship: SkyWarsModePerk; + environmentalExpert: SkyWarsModePerk; + bridger: SkyWarsModePerk; + luckyCharm: SkyWarsModePerk; + blackMagic: SkyWarsModePerk; + necromancer: SkyWarsModePerk; + telekinesis: SkyWarsModePerk; + constructor(data: Record) { + super(data, 'mega'); + this.doubles = new SkyWarsMode(data, 'mega_doubles'); + this.doublesNormal = new SkyWarsMode(data, 'mega_doubles_normal'); + this.normal = new SkyWarsMode(data, 'mega_normal'); + this.kits = new SkyWarsMegaKits(data); + this.rusher = new SkyWarsModePerk(data, 'rusher', 'mega'); + this.miningExpertise = new SkyWarsModePerk(data, 'mining_expertise', 'mega'); + this.enderMastery = new SkyWarsModePerk(data, 'ender_mastery', 'mega'); + this.blazingArrows = new SkyWarsModePerk(data, 'blazing_arrows', 'mega'); + this.arrowRecovery = new SkyWarsModePerk(data, 'arrow_recovery', 'mega'); + this.juggernaut = new SkyWarsModePerk(data, 'juggernaut', 'mega'); + this.tank = new SkyWarsModePerk(data, 'tank', 'mega'); + this.nourishment = new SkyWarsModePerk(data, 'nourishment', 'mega'); + this.notoriety = new SkyWarsModePerk(data, 'notoriety', 'mega'); + this.instantSmelting = new SkyWarsModePerk(data, 'instant_smelting', 'mega'); + this.marksmanship = new SkyWarsModePerk(data, 'marksmanship', 'mega'); + this.environmentalExpert = new SkyWarsModePerk(data, 'environmental_expert', 'mega'); + this.bridger = new SkyWarsModePerk(data, 'bridger', 'mega'); + this.luckyCharm = new SkyWarsModePerk(data, 'lucky_charm', 'mega'); + this.blackMagic = new SkyWarsModePerk(data, 'black_magic', 'mega'); + this.necromancer = new SkyWarsModePerk(data, 'necromancer', 'mega'); + this.telekinesis = new SkyWarsModePerk(data, 'telekinesis', 'mega'); + } +} + +export default SkyWarsMega; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.test.ts new file mode 100644 index 000000000..ace3ccbf3 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.test.ts @@ -0,0 +1,58 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsMegaKits from './SkyWarsMegaKits.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsMegaKits', () => { + const data = new SkyWarsMegaKits({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsMegaKits); + expectTypeOf(data).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.baseballPlayer).toBeDefined(); + expect(data.baseballPlayer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.baseballPlayer).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.cannoneer).toBeDefined(); + expect(data.cannoneer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cannoneer).toEqualTypeOf(); + expect(data.hellhound).toBeDefined(); + expect(data.hellhound).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hellhound).toEqualTypeOf(); + expect(data.witch).toBeDefined(); + expect(data.witch).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.witch).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.armorsmith).toBeDefined(); + expect(data.armorsmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorsmith).toEqualTypeOf(); + expect(data.pyromaniac).toBeDefined(); + expect(data.pyromaniac).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyromaniac).toEqualTypeOf(); + expect(data.paladin).toBeDefined(); + expect(data.paladin).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.paladin).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.skeletor).toBeDefined(); + expect(data.skeletor).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.skeletor).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderman).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.ts new file mode 100644 index 000000000..fd15d55d4 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.ts @@ -0,0 +1,40 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsMegaKits { + default: BaseSkyWarsMode; + hunter: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + baseballPlayer: BaseSkyWarsMode; + armorer: BaseSkyWarsMode; + knight: BaseSkyWarsMode; + cannoneer: BaseSkyWarsMode; + hellhound: BaseSkyWarsMode; + witch: BaseSkyWarsMode; + fisherman: BaseSkyWarsMode; + armorsmith: BaseSkyWarsMode; + pyromaniac: BaseSkyWarsMode; + paladin: BaseSkyWarsMode; + healer: BaseSkyWarsMode; + skeletor: BaseSkyWarsMode; + enderman: BaseSkyWarsMode; + constructor(data: Record) { + this.default = new BaseSkyWarsMode(data, 'kit_mega_mega_default'); + this.hunter = new BaseSkyWarsMode(data, 'kit_mega_mega_hunter'); + this.scout = new BaseSkyWarsMode(data, 'kit_mega_mega_scout'); + this.baseballPlayer = new BaseSkyWarsMode(data, 'kit_mega_mega_baseball-player'); + this.armorer = new BaseSkyWarsMode(data, 'kit_mega_mega_armorer'); + this.knight = new BaseSkyWarsMode(data, 'kit_mega_mega_knight'); + this.cannoneer = new BaseSkyWarsMode(data, 'kit_mega_mega_cannoneer'); + this.hellhound = new BaseSkyWarsMode(data, 'kit_mega_mega_hellhound'); + this.witch = new BaseSkyWarsMode(data, 'kit_mega_mega_witch'); + this.fisherman = new BaseSkyWarsMode(data, 'kit_mega_mega_fisherman'); + this.armorsmith = new BaseSkyWarsMode(data, 'kit_mega_mega_armorsmith'); + this.pyromaniac = new BaseSkyWarsMode(data, 'kit_mega_mega_pyromaniac'); + this.paladin = new BaseSkyWarsMode(data, 'kit_mega_mega_paladin'); + this.healer = new BaseSkyWarsMode(data, 'kit_mega_mega_healer'); + this.skeletor = new BaseSkyWarsMode(data, 'kit_mega_mega_skeletor'); + this.enderman = new BaseSkyWarsMode(data, 'kit_mega_mega_enderman'); + } +} + +export default SkyWarsMegaKits; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMini.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMini.test.ts new file mode 100644 index 000000000..5cc9ed340 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMini.test.ts @@ -0,0 +1,13 @@ +import SkyWarsMini from './SkyWarsMini.js'; +import SkyWarsMode from './SkyWarsMode/SkyWarsMode.ts'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsMini', () => { + const data = new SkyWarsMini({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsMini); + expectTypeOf(data).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.normal).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMini.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMini.ts new file mode 100644 index 000000000..44b017df5 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMini.ts @@ -0,0 +1,11 @@ +import SkyWarsMode from './SkyWarsMode/SkyWarsMode.ts'; + +class SkyWarsMini extends SkyWarsMode { + normal: SkyWarsMode; + constructor(data: Record) { + super(data, 'mini'); + this.normal = new SkyWarsMode(data, 'mini_normal'); + } +} + +export default SkyWarsMini; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.test.ts new file mode 100644 index 000000000..2b25ecef2 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.test.ts @@ -0,0 +1,89 @@ +import BaseSkyWarsMode from './BaseSkyWarsMode.js'; +import SkyWarsHeads from '../SkyWarsHeads.js'; +import SkyWarsKillsDeaths from '../SkyWarsKillsDeaths.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BaseSkyWarsMode', () => { + const data = new BaseSkyWarsMode({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeInstanceOf(SkyWarsKillsDeaths); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeInstanceOf(SkyWarsKillsDeaths); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.heads).toBeDefined(); + expect(data.heads).toBeInstanceOf(SkyWarsHeads); + expectTypeOf(data.heads).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLRatio).toBeDefined(); + expect(data.WLRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLRatio).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.timePlayed).toBeDefined(); + expect(data.timePlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timePlayed).toEqualTypeOf(); + expect(data.winstreak).toBeDefined(); + expect(data.winstreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winstreak).toEqualTypeOf(); + expect(data.survivedPlayers).toBeDefined(); + expect(data.survivedPlayers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.survivedPlayers).toEqualTypeOf(); + expect(data.chestsOpened).toBeDefined(); + expect(data.chestsOpened).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chestsOpened).toEqualTypeOf(); + expect(data.killstreak).toBeDefined(); + expect(data.killstreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killstreak).toEqualTypeOf(); + expect(data.longestBowKill).toBeDefined(); + expect(data.longestBowKill).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestBowKill).toEqualTypeOf(); + expect(data.fastestWin).toBeDefined(); + expect(data.fastestWin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestWin).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.mostKillsGame).toBeDefined(); + expect(data.mostKillsGame).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostKillsGame).toEqualTypeOf(); + expect(data.longestBowShot).toBeDefined(); + expect(data.longestBowShot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.longestBowShot).toEqualTypeOf(); + expect(data.arrowsHit).toBeDefined(); + expect(data.arrowsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsHit).toEqualTypeOf(); + expect(data.arrowsShot).toBeDefined(); + expect(data.arrowsShot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arrowsShot).toEqualTypeOf(); + expect(data.shard).toBeDefined(); + expect(data.shard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shard).toEqualTypeOf(); + expect(data.mobsKilled).toBeDefined(); + expect(data.mobsKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mobsKilled).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.eggThrown).toBeDefined(); + expect(data.eggThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggThrown).toEqualTypeOf(); + expect(data.enderpearlsThrown).toBeDefined(); + expect(data.enderpearlsThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderpearlsThrown).toEqualTypeOf(); + expect(data.itemsEnchanted).toBeDefined(); + expect(data.itemsEnchanted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemsEnchanted).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.ts new file mode 100644 index 000000000..7b01cea56 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.ts @@ -0,0 +1,65 @@ +import Divide from '../../../../Utils/Divide.ts'; +import SkyWarsHeads from '../SkyWarsHeads.ts'; +import SkyWarsKillsDeaths from '../SkyWarsKillsDeaths.ts'; +import { ParseModeAfter } from '../../../../Utils/ParseMode.ts'; +import type { SkyWarsKitId, SkyWarsModeId } from '../../../../Types/Player.ts'; + +class BaseSkyWarsMode { + kills: SkyWarsKillsDeaths; + deaths: SkyWarsKillsDeaths; + heads: SkyWarsHeads; + wins: number; + losses: number; + WLRatio: number; + gamesPlayed: number; + timePlayed: number; + winstreak: number; + survivedPlayers: number; + chestsOpened: number; + killstreak: number; + longestBowKill: number; + fastestWin: number; + assists: number; + mostKillsGame: number; + longestBowShot: number; + arrowsHit: number; + arrowsShot: number; + shard: number; + mobsKilled: number; + blocksBroken: number; + blocksPlaced: number; + eggThrown: number; + enderpearlsThrown: number; + itemsEnchanted: number; + constructor(data: Record, mode?: SkyWarsModeId | SkyWarsKitId) { + mode = ParseModeAfter(mode) as SkyWarsModeId; + this.kills = new SkyWarsKillsDeaths(data, mode); + this.deaths = new SkyWarsKillsDeaths(data, mode); + this.heads = new SkyWarsHeads(data, mode); + this.wins = data?.[`wins${mode}`] || 0; + this.losses = data?.[`losses${mode}`] || 0; + this.WLRatio = Divide(this.wins, this.losses) || 0; + this.gamesPlayed = data?.[`games${mode}`] || 0; + this.timePlayed = data?.[`time_played${mode}`] || 0; + this.winstreak = data?.[`winstreak${mode}`] || 0; + this.survivedPlayers = data?.[`survived_players${mode}`] || 0; + this.chestsOpened = data?.[`chests_opened${mode}`] || 0; + this.killstreak = data?.[`killstreak${mode}`] || 0; + this.longestBowKill = data?.[`longest_bow_kill${mode}`] || 0; + this.fastestWin = data?.[`fastest_win${mode}`] || 0; + this.assists = data?.[`assists${mode}`] || 0; + this.mostKillsGame = data?.[`most_kills_game${mode}`] || 0; + this.longestBowShot = data?.[`longest_bow_shot${mode}`] || 0; + this.arrowsHit = data?.[`arrows_hit${mode}`] || 0; + this.arrowsShot = data?.[`arrows_shot${mode}`] || 0; + this.shard = data?.[`shard${mode}`] || 0; + this.mobsKilled = data?.[`mobs_killed${mode}`] || 0; + this.blocksBroken = data?.[`blocks_broken${mode}`] || 0; + this.blocksPlaced = data?.[`blocks_placed${mode}`] || 0; + this.eggThrown = data?.[`egg_thrown${mode}`] || 0; + this.enderpearlsThrown = data?.[`enderpearls_thrown${mode}`] || 0; + this.itemsEnchanted = data?.[`items_enchanted${mode}`] || 0; + } +} + +export default BaseSkyWarsMode; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.test.ts new file mode 100644 index 000000000..88a3de79c --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.test.ts @@ -0,0 +1,11 @@ +import SkyWarsMode from './SkyWarsMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsMode', () => { + const data = new SkyWarsMode({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeKit).toBeDefined(); + expectTypeOf(data.activeKit).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.ts new file mode 100644 index 000000000..1afb156f1 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.ts @@ -0,0 +1,14 @@ +import BaseSkyWarsMode from './BaseSkyWarsMode.ts'; +import { ParseModeAfter } from '../../../../Utils/ParseMode.ts'; +import type { SkyWarsModeId } from '../../../../Types/Player.ts'; + +class SkyWarsMode extends BaseSkyWarsMode { + activeKit: string | 'UNKNOWN'; + constructor(data: Record, mode?: SkyWarsModeId) { + mode = ParseModeAfter(mode) as SkyWarsModeId; + super(data, mode); + this.activeKit = data?.[`activeKit${mode.toUpperCase()}`] || 'UNKNOWN'; + } +} + +export default SkyWarsMode; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.test.ts new file mode 100644 index 000000000..533465fff --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.test.ts @@ -0,0 +1,14 @@ +import SkyWarsModePerk from './SkyWarsModePerk.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsModePerk', () => { + const data = new SkyWarsModePerk({ stats: 'meow' }, 'annoy', 'crazytourney'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.enabled).toBeDefined(); + expectTypeOf(data.enabled).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.ts b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.ts new file mode 100644 index 000000000..8c812d7b8 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.ts @@ -0,0 +1,16 @@ +import { ParseModeAfter, ParseModeBefore, ParseModeBeforeAfter } from '../../../../Utils/ParseMode.ts'; +import type { SkyWarsModeId, SkyWarsPerkId } from '../../../../Types/Player.ts'; + +class SkyWarsModePerk { + level: number; + enabled: boolean; + constructor(data: Record, perk: SkyWarsPerkId, mode: SkyWarsModeId) { + perk = ParseModeAfter(mode) as SkyWarsPerkId; + mode = ParseModeBefore(mode) as SkyWarsModeId; + this.level = data?.[`${mode}${perk}`] || 0; + mode = ParseModeBeforeAfter(mode) as SkyWarsModeId; + this.enabled = data?.[`toggle_${mode}${perk}`] || 0; + } +} + +export default SkyWarsModePerk; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.test.ts new file mode 100644 index 000000000..359a1f23d --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.test.ts @@ -0,0 +1,36 @@ +import SkyWarsPrivateGames from './SkyWarsPrivateGames.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PrivateGameSettingsGameSpeed, PrivateGameSettingsHealthBuff } from '../../../Types/Player.js'; + +test('SkyWarsPrivateGames', () => { + const data = new SkyWarsPrivateGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsPrivateGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.maxKitsAndPerks).toBeDefined(); + expectTypeOf(data.maxKitsAndPerks).toEqualTypeOf(); + expect(data.legacyItems).toBeDefined(); + expectTypeOf(data.legacyItems).toEqualTypeOf(); + expect(data.speed).toBeDefined(); + expectTypeOf(data.speed).toEqualTypeOf(); + expect(data.dragons).toBeDefined(); + expectTypeOf(data.dragons).toEqualTypeOf(); + expect(data.noKits).toBeDefined(); + expectTypeOf(data.noKits).toEqualTypeOf(); + expect(data.nightTime).toBeDefined(); + expectTypeOf(data.nightTime).toEqualTypeOf(); + expect(data.healthBuff).toBeDefined(); + expectTypeOf(data.healthBuff).toEqualTypeOf(); + expect(data.teleportMayhem).toBeDefined(); + expectTypeOf(data.teleportMayhem).toEqualTypeOf(); + expect(data.chestSwords).toBeDefined(); + expectTypeOf(data.chestSwords).toEqualTypeOf(); + expect(data.chestArmour).toBeDefined(); + expectTypeOf(data.chestArmour).toEqualTypeOf(); + expect(data.oneHitOneKill).toBeDefined(); + expectTypeOf(data.oneHitOneKill).toEqualTypeOf(); + expect(data.lowGravity).toBeDefined(); + expectTypeOf(data.lowGravity).toEqualTypeOf(); + expect(data.chestBows).toBeDefined(); + expectTypeOf(data.chestBows).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.ts b/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.ts new file mode 100644 index 000000000..ce394750d --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsPrivateGames.ts @@ -0,0 +1,34 @@ +import type { PrivateGameSettingsGameSpeed, PrivateGameSettingsHealthBuff } from '../../../Types/Player.ts'; + +class SkyWarsPrivateGames { + maxKitsAndPerks: boolean; + legacyItems: boolean; + speed: PrivateGameSettingsGameSpeed | 'UNKNOWN'; + dragons: string | 'UNKNOWN'; + noKits: boolean; + nightTime: boolean; + healthBuff: PrivateGameSettingsHealthBuff | 'UNKNOWN'; + teleportMayhem: boolean; + chestSwords: string | 'UNKNOWN'; + chestArmour: string | 'UNKNOWN'; + oneHitOneKill: boolean; + lowGravity: boolean; + chestBows: string | 'UNKNOWN'; + constructor(data: Record) { + this.maxKitsAndPerks = data?.enable_max_kits_and_perks || false; + this.legacyItems = data?.enable_legacy_items || false; + this.speed = data?.speed || 'UNKNOWN'; + this.dragons = data?.dragons || 'UNKNOWN'; + this.noKits = data?.no_kits || false; + this.nightTime = data?.enable_night_time || false; + this.healthBuff = data?.health_buff || 'UNKNOWN'; + this.teleportMayhem = data?.enable_teleport_mayhem || false; + this.chestSwords = data?.chest_swords || 'UNKNOWN'; + this.chestArmour = data?.chest_armour || 'UNKNOWN'; + this.oneHitOneKill = data?.one_hit_one_kill || false; + this.lowGravity = data?.low_gravity || false; + this.chestBows = data?.chest_bows || 'UNKNOWN'; + } +} + +export default SkyWarsPrivateGames; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.test.ts new file mode 100644 index 000000000..2208179f0 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.test.ts @@ -0,0 +1,17 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsRanked from './SkyWarsRanked.js'; +import SkyWarsRankedKits from './SkyWarsRankedKits.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsRanked', () => { + const data = new SkyWarsRanked({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsRanked); + expectTypeOf(data).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.kits).toBeDefined(); + expect(data.kits).toBeInstanceOf(SkyWarsRankedKits); + expectTypeOf(data.kits).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.ts b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.ts new file mode 100644 index 000000000..de836f32a --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.ts @@ -0,0 +1,14 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsRankedKits from './SkyWarsRankedKits.ts'; + +class SkyWarsRanked extends BaseSkyWarsMode { + normal: BaseSkyWarsMode; + kits: SkyWarsRankedKits; + constructor(data: Record) { + super(data, 'ranked'); + this.normal = new BaseSkyWarsMode(data, 'ranked_normal'); + this.kits = new SkyWarsRankedKits(data); + } +} + +export default SkyWarsRanked; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.test.ts new file mode 100644 index 000000000..d6a2ac67d --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.test.ts @@ -0,0 +1,46 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsRankedKits from './SkyWarsRankedKits.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsRankedKits', () => { + const data = new SkyWarsRankedKits({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsRankedKits); + expectTypeOf(data).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.bowman).toBeDefined(); + expect(data.bowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.bowman).toEqualTypeOf(); + expect(data.champion).toBeDefined(); + expect(data.champion).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.champion).toEqualTypeOf(); + expect(data.pyromancer).toBeDefined(); + expect(data.pyromancer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyromancer).toEqualTypeOf(); + expect(data.hound).toBeDefined(); + expect(data.hound).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hound).toEqualTypeOf(); + expect(data.athlete).toBeDefined(); + expect(data.athlete).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.athlete).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.paladin).toBeDefined(); + expect(data.paladin).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.paladin).toEqualTypeOf(); + expect(data.blacksmith).toBeDefined(); + expect(data.blacksmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.blacksmith).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.ts b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.ts new file mode 100644 index 000000000..9ea5f8c24 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.ts @@ -0,0 +1,32 @@ +import BaseSkyWarsMode from '../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsRankedKits { + default: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + armorer: BaseSkyWarsMode; + bowman: BaseSkyWarsMode; + champion: BaseSkyWarsMode; + pyromancer: BaseSkyWarsMode; + hound: BaseSkyWarsMode; + athlete: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + healer: BaseSkyWarsMode; + paladin: BaseSkyWarsMode; + blacksmith: BaseSkyWarsMode; + constructor(data: Record) { + this.default = new BaseSkyWarsMode(data, 'kit_ranked_ranked_default'); + this.scout = new BaseSkyWarsMode(data, 'kit_ranked_ranked_scout'); + this.armorer = new BaseSkyWarsMode(data, 'kit_ranked_ranked_armorer'); + this.bowman = new BaseSkyWarsMode(data, 'kit_ranked_ranked_bowman'); + this.champion = new BaseSkyWarsMode(data, 'kit_ranked_ranked_champion'); + this.pyromancer = new BaseSkyWarsMode(data, 'kit_ranked_ranked_pyromancer'); + this.hound = new BaseSkyWarsMode(data, 'kit_ranked_ranked_hound'); + this.athlete = new BaseSkyWarsMode(data, 'kit_ranked_ranked_athlete'); + this.magician = new BaseSkyWarsMode(data, 'kit_ranked_ranked_magician'); + this.healer = new BaseSkyWarsMode(data, 'kit_ranked_ranked_healer'); + this.paladin = new BaseSkyWarsMode(data, 'kit_ranked_ranked_paladin'); + this.blacksmith = new BaseSkyWarsMode(data, 'kit_ranked_ranked_blacksmith'); + } +} + +export default SkyWarsRankedKits; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.test.ts new file mode 100644 index 000000000..adeda206e --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.test.ts @@ -0,0 +1,96 @@ +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.js'; +import SkyWarsSolo from './SkyWarsSolo.js'; +import SkyWarsSoloKits from './SkyWarsSoloKits/SkyWarsSoloKits.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSolo', () => { + const data = new SkyWarsSolo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSolo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.insane).toBeDefined(); + expect(data.insane).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.insane).toEqualTypeOf(); + expect(data.lab).toBeDefined(); + expect(data.lab).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.lab).toEqualTypeOf(); + expect(data.kits).toBeDefined(); + expect(data.kits).toBeInstanceOf(SkyWarsSoloKits); + expectTypeOf(data.kits).toEqualTypeOf(); + expect(data.enderMastery).toBeDefined(); + expect(data.enderMastery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.enderMastery).toEqualTypeOf(); + expect(data.arrowRecovery).toBeDefined(); + expect(data.arrowRecovery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.arrowRecovery).toEqualTypeOf(); + expect(data.miningExpertise).toBeDefined(); + expect(data.miningExpertise).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.miningExpertise).toEqualTypeOf(); + expect(data.blazingArrows).toBeDefined(); + expect(data.blazingArrows).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blazingArrows).toEqualTypeOf(); + expect(data.instantSmelting).toBeDefined(); + expect(data.instantSmelting).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.instantSmelting).toEqualTypeOf(); + expect(data.resistanceBoost).toBeDefined(); + expect(data.resistanceBoost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.resistanceBoost).toEqualTypeOf(); + expect(data.speedBoost).toBeDefined(); + expect(data.speedBoost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.speedBoost).toEqualTypeOf(); + expect(data.bulldozer).toBeDefined(); + expect(data.bulldozer).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.bulldozer).toEqualTypeOf(); + expect(data.marksmanship).toBeDefined(); + expect(data.marksmanship).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.marksmanship).toEqualTypeOf(); + expect(data.juggernaut).toBeDefined(); + expect(data.juggernaut).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.juggernaut).toEqualTypeOf(); + expect(data.knowledge).toBeDefined(); + expect(data.knowledge).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.knowledge).toEqualTypeOf(); + expect(data.fat).toBeDefined(); + expect(data.fat).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.fat).toEqualTypeOf(); + expect(data.nourishment).toBeDefined(); + expect(data.nourishment).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.nourishment).toEqualTypeOf(); + expect(data.annoy).toBeDefined(); + expect(data.annoy).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.annoy).toEqualTypeOf(); + expect(data.revenge).toBeDefined(); + expect(data.revenge).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.revenge).toEqualTypeOf(); + expect(data.luckyCharm).toBeDefined(); + expect(data.luckyCharm).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.luckyCharm).toEqualTypeOf(); + expect(data.bridger).toBeDefined(); + expect(data.bridger).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.bridger).toEqualTypeOf(); + expect(data.environmentalExpert).toBeDefined(); + expect(data.environmentalExpert).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.environmentalExpert).toEqualTypeOf(); + expect(data.necromancer).toBeDefined(); + expect(data.necromancer).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.necromancer).toEqualTypeOf(); + expect(data.blackMagic).toBeDefined(); + expect(data.blackMagic).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blackMagic).toEqualTypeOf(); + expect(data.robbery).toBeDefined(); + expect(data.robbery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.robbery).toEqualTypeOf(); + expect(data.frost).toBeDefined(); + expect(data.frost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.frost).toEqualTypeOf(); + expect(data.barbarian).toBeDefined(); + expect(data.barbarian).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.barbarian).toEqualTypeOf(); + expect(data.savior).toBeDefined(); + expect(data.savior).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.savior).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.ts new file mode 100644 index 000000000..95a976dfd --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.ts @@ -0,0 +1,67 @@ +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.ts'; +import SkyWarsSoloKits from './SkyWarsSoloKits/SkyWarsSoloKits.js'; + +class SkyWarsSolo extends SkyWarsMode { + normal: SkyWarsMode; + insane: SkyWarsMode; + lab: SkyWarsMode; + kits: SkyWarsSoloKits; + enderMastery: SkyWarsModePerk; + arrowRecovery: SkyWarsModePerk; + miningExpertise: SkyWarsModePerk; + blazingArrows: SkyWarsModePerk; + instantSmelting: SkyWarsModePerk; + resistanceBoost: SkyWarsModePerk; + speedBoost: SkyWarsModePerk; + bulldozer: SkyWarsModePerk; + marksmanship: SkyWarsModePerk; + juggernaut: SkyWarsModePerk; + knowledge: SkyWarsModePerk; + fat: SkyWarsModePerk; + nourishment: SkyWarsModePerk; + annoy: SkyWarsModePerk; + revenge: SkyWarsModePerk; + luckyCharm: SkyWarsModePerk; + bridger: SkyWarsModePerk; + environmentalExpert: SkyWarsModePerk; + necromancer: SkyWarsModePerk; + blackMagic: SkyWarsModePerk; + robbery: SkyWarsModePerk; + frost: SkyWarsModePerk; + barbarian: SkyWarsModePerk; + savior: SkyWarsModePerk; + constructor(data: Record) { + super(data, 'solo'); + this.normal = new SkyWarsMode(data, 'solo_normal'); + this.insane = new SkyWarsMode(data, 'solo_insane'); + this.lab = new SkyWarsMode(data, 'lab_solo'); + this.kits = new SkyWarsSoloKits(data); + this.enderMastery = new SkyWarsModePerk(data, 'ender_mastery', 'solo'); + this.arrowRecovery = new SkyWarsModePerk(data, 'arrow_recovery', 'solo'); + this.miningExpertise = new SkyWarsModePerk(data, 'mining_expertise', 'solo'); + this.blazingArrows = new SkyWarsModePerk(data, 'blazing_arrows', 'solo'); + this.instantSmelting = new SkyWarsModePerk(data, 'instant_smelting', 'solo'); + this.resistanceBoost = new SkyWarsModePerk(data, 'resistance_boost', 'solo'); + this.speedBoost = new SkyWarsModePerk(data, 'speed_boost', 'solo'); + this.bulldozer = new SkyWarsModePerk(data, 'bulldozer', 'solo'); + this.marksmanship = new SkyWarsModePerk(data, 'marksmanship', 'solo'); + this.juggernaut = new SkyWarsModePerk(data, 'juggernaut', 'solo'); + this.knowledge = new SkyWarsModePerk(data, 'knowledge', 'solo'); + this.fat = new SkyWarsModePerk(data, 'fat', 'solo'); + this.nourishment = new SkyWarsModePerk(data, 'nourishment', 'solo'); + this.annoy = new SkyWarsModePerk(data, 'annoy', 'solo'); + this.revenge = new SkyWarsModePerk(data, 'revenge', 'solo'); + this.luckyCharm = new SkyWarsModePerk(data, 'lucky_charm', 'solo'); + this.bridger = new SkyWarsModePerk(data, 'bridger', 'solo'); + this.environmentalExpert = new SkyWarsModePerk(data, 'environmental_expert', 'solo'); + this.necromancer = new SkyWarsModePerk(data, 'necromancer', 'solo'); + this.blackMagic = new SkyWarsModePerk(data, 'black_magic', 'solo'); + this.robbery = new SkyWarsModePerk(data, 'robbery', 'solo'); + this.frost = new SkyWarsModePerk(data, 'frost', 'solo'); + this.barbarian = new SkyWarsModePerk(data, 'barbarian', 'solo'); + this.savior = new SkyWarsModePerk(data, 'savior', 'solo'); + } +} + +export default SkyWarsSolo; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.test.ts new file mode 100644 index 000000000..95e48dbd0 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.test.ts @@ -0,0 +1,33 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKits from './SkyWarsSoloKits.js'; +import SkyWarsSoloKitsAdvanced from './SkyWarsSoloKitsAdvanced.js'; +import SkyWarsSoloKitsBasic from './SkyWarsSoloKitsBasic.js'; +import SkyWarsSoloKitsLab from './SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.js'; +import SkyWarsSoloKitsMini from './SkyWarsSoloKitsMini.js'; +import SkyWarsSoloKitsTourney from './SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKits', () => { + const data = new SkyWarsSoloKits({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKits); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lab).toBeDefined(); + expect(data.lab).toBeInstanceOf(SkyWarsSoloKitsLab); + expectTypeOf(data.lab).toEqualTypeOf(); + expect(data.basic).toBeDefined(); + expect(data.basic).toBeInstanceOf(SkyWarsSoloKitsBasic); + expectTypeOf(data.basic).toEqualTypeOf(); + expect(data.advanced).toBeDefined(); + expect(data.advanced).toBeInstanceOf(SkyWarsSoloKitsAdvanced); + expectTypeOf(data.advanced).toEqualTypeOf(); + expect(data.mini).toBeDefined(); + expect(data.mini).toBeInstanceOf(SkyWarsSoloKitsMini); + expectTypeOf(data.mini).toEqualTypeOf(); + expect(data.tourney).toBeDefined(); + expect(data.tourney).toBeInstanceOf(SkyWarsSoloKitsTourney); + expectTypeOf(data.tourney).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderChest).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.ts new file mode 100644 index 000000000..5e347feac --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.ts @@ -0,0 +1,25 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsSoloKitsAdvanced from './SkyWarsSoloKitsAdvanced.ts'; +import SkyWarsSoloKitsBasic from './SkyWarsSoloKitsBasic.ts'; +import SkyWarsSoloKitsLab from './SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.ts'; +import SkyWarsSoloKitsMini from './SkyWarsSoloKitsMini.ts'; +import SkyWarsSoloKitsTourney from './SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.ts'; + +class SkyWarsSoloKits { + lab: SkyWarsSoloKitsLab; + basic: SkyWarsSoloKitsBasic; + advanced: SkyWarsSoloKitsAdvanced; + mini: SkyWarsSoloKitsMini; + tourney: SkyWarsSoloKitsTourney; + enderChest: BaseSkyWarsMode; + constructor(data: Record) { + this.lab = new SkyWarsSoloKitsLab(data); + this.basic = new SkyWarsSoloKitsBasic(data); + this.advanced = new SkyWarsSoloKitsAdvanced(data); + this.mini = new SkyWarsSoloKitsMini(data); + this.tourney = new SkyWarsSoloKitsTourney(data); + this.enderChest = new BaseSkyWarsMode(data, 'kit_enderchest_solo_enderchest'); + } +} + +export default SkyWarsSoloKits; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.test.ts new file mode 100644 index 000000000..9e7b297e5 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.test.ts @@ -0,0 +1,61 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsAdvanced from './SkyWarsSoloKitsAdvanced.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsAdvanced', () => { + const data = new SkyWarsSoloKitsAdvanced({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsAdvanced); + expectTypeOf(data).toEqualTypeOf(); + expect(data.farmer).toBeDefined(); + expect(data.farmer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.farmer).toEqualTypeOf(); + expect(data.enchanter).toBeDefined(); + expect(data.enchanter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enchanter).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.cannoneer).toBeDefined(); + expect(data.cannoneer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cannoneer).toEqualTypeOf(); + expect(data.pyro).toBeDefined(); + expect(data.pyro).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyro).toEqualTypeOf(); + expect(data.salmon).toBeDefined(); + expect(data.salmon).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.salmon).toEqualTypeOf(); + expect(data.zookeeper).toBeDefined(); + expect(data.zookeeper).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.zookeeper).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.pigRider).toBeDefined(); + expect(data.pigRider).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pigRider).toEqualTypeOf(); + expect(data.sloth).toBeDefined(); + expect(data.sloth).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.sloth).toEqualTypeOf(); + expect(data.jester).toBeDefined(); + expect(data.jester).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.jester).toEqualTypeOf(); + expect(data.guardian).toBeDefined(); + expect(data.guardian).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.guardian).toEqualTypeOf(); + expect(data.engineer).toBeDefined(); + expect(data.engineer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.engineer).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.ts new file mode 100644 index 000000000..936f9722f --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.ts @@ -0,0 +1,42 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsAdvanced { + farmer: BaseSkyWarsMode; + enchanter: BaseSkyWarsMode; + hunter: BaseSkyWarsMode; + knight: BaseSkyWarsMode; + armorer: BaseSkyWarsMode; + cannoneer: BaseSkyWarsMode; + pyro: BaseSkyWarsMode; + salmon: BaseSkyWarsMode; + zookeeper: BaseSkyWarsMode; + enderman: BaseSkyWarsMode; + slime: BaseSkyWarsMode; + pigRider: BaseSkyWarsMode; + sloth: BaseSkyWarsMode; + jester: BaseSkyWarsMode; + guardian: BaseSkyWarsMode; + engineer: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + constructor(data: Record) { + this.farmer = new BaseSkyWarsMode(data, 'kit_advanced_solo_farmer'); + this.enchanter = new BaseSkyWarsMode(data, 'kit_advanced_solo_enchanter'); + this.hunter = new BaseSkyWarsMode(data, 'kit_advanced_solo_hunter'); + this.knight = new BaseSkyWarsMode(data, 'kit_advanced_solo_knight'); + this.armorer = new BaseSkyWarsMode(data, 'kit_advanced_solo_armorer'); + this.cannoneer = new BaseSkyWarsMode(data, 'kit_advanced_solo_cannoneer'); + this.pyro = new BaseSkyWarsMode(data, 'kit_advanced_solo_pyro'); + this.salmon = new BaseSkyWarsMode(data, 'kit_advanced_solo_salmon'); + this.zookeeper = new BaseSkyWarsMode(data, 'kit_advanced_solo_zookeeper'); + this.enderman = new BaseSkyWarsMode(data, 'kit_advanced_solo_enderman'); + this.slime = new BaseSkyWarsMode(data, 'kit_advanced_solo_slime'); + this.pigRider = new BaseSkyWarsMode(data, 'kit_advanced_solo_pig-rider'); + this.sloth = new BaseSkyWarsMode(data, 'kit_advanced_solo_sloth'); + this.jester = new BaseSkyWarsMode(data, 'kit_advanced_solo_jester'); + this.guardian = new BaseSkyWarsMode(data, 'kit_advanced_solo_guardian'); + this.engineer = new BaseSkyWarsMode(data, 'kit_advanced_solo_engineer'); + this.magician = new BaseSkyWarsMode(data, 'kit_advanced_solo_magician'); + } +} + +export default SkyWarsSoloKitsAdvanced; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.test.ts new file mode 100644 index 000000000..492ffeb77 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.test.ts @@ -0,0 +1,76 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsBasic from './SkyWarsSoloKitsBasic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsBasic', () => { + const data = new SkyWarsSoloKitsBasic({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsBasic); + expectTypeOf(data).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.armorsmith).toBeDefined(); + expect(data.armorsmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorsmith).toEqualTypeOf(); + expect(data.ecologist).toBeDefined(); + expect(data.ecologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.ecologist).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.speleologist).toBeDefined(); + expect(data.speleologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.speleologist).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.troll).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.rookie).toBeDefined(); + expect(data.rookie).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.rookie).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.energix).toBeDefined(); + expect(data.energix).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.energix).toEqualTypeOf(); + expect(data.grenade).toBeDefined(); + expect(data.grenade).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.grenade).toEqualTypeOf(); + expect(data.pharaoh).toBeDefined(); + expect(data.pharaoh).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pharaoh).toEqualTypeOf(); + expect(data.disco).toBeDefined(); + expect(data.disco).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.disco).toEqualTypeOf(); + expect(data.frog).toBeDefined(); + expect(data.frog).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.frog).toEqualTypeOf(); + expect(data.baseballPlayer).toBeDefined(); + expect(data.baseballPlayer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.baseballPlayer).toEqualTypeOf(); + expect(data.princess).toBeDefined(); + expect(data.princess).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.princess).toEqualTypeOf(); + expect(data.batguy).toBeDefined(); + expect(data.batguy).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.batguy).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expect(data.cactus).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.warlock).toBeDefined(); + expect(data.warlock).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.warlock).toEqualTypeOf(); + expect(data.archeologist).toBeDefined(); + expect(data.archeologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.archeologist).toEqualTypeOf(); + expect(data.fallenAngel).toBeDefined(); + expect(data.fallenAngel).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fallenAngel).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.ts new file mode 100644 index 000000000..0d45e7d7f --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.ts @@ -0,0 +1,52 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsBasic { + default: BaseSkyWarsMode; + armorsmith: BaseSkyWarsMode; + ecologist: BaseSkyWarsMode; + fisherman: BaseSkyWarsMode; + speleologist: BaseSkyWarsMode; + troll: BaseSkyWarsMode; + snowman: BaseSkyWarsMode; + rookie: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + energix: BaseSkyWarsMode; + grenade: BaseSkyWarsMode; + pharaoh: BaseSkyWarsMode; + disco: BaseSkyWarsMode; + frog: BaseSkyWarsMode; + baseballPlayer: BaseSkyWarsMode; + princess: BaseSkyWarsMode; + batguy: BaseSkyWarsMode; + healer: BaseSkyWarsMode; + cactus: BaseSkyWarsMode; + warlock: BaseSkyWarsMode; + archeologist: BaseSkyWarsMode; + fallenAngel: BaseSkyWarsMode; + constructor(data: Record) { + this.default = new BaseSkyWarsMode(data, 'kit_basic_solo_default'); + this.armorsmith = new BaseSkyWarsMode(data, 'kit_basic_solo_armorsmith'); + this.ecologist = new BaseSkyWarsMode(data, 'kit_basic_solo_ecologist'); + this.fisherman = new BaseSkyWarsMode(data, 'kit_basic_solo_fisherman'); + this.speleologist = new BaseSkyWarsMode(data, 'kit_basic_solo_speleologist'); + this.troll = new BaseSkyWarsMode(data, 'kit_basic_solo_troll'); + this.snowman = new BaseSkyWarsMode(data, 'kit_basic_solo_snowman'); + this.rookie = new BaseSkyWarsMode(data, 'kit_basic_solo_rookie'); + this.scout = new BaseSkyWarsMode(data, 'kit_basic_solo_scout'); + this.energix = new BaseSkyWarsMode(data, 'kit_basic_solo_energix'); + this.grenade = new BaseSkyWarsMode(data, 'kit_basic_solo_grenade'); + this.pharaoh = new BaseSkyWarsMode(data, 'kit_basic_solo_pharaoh'); + this.disco = new BaseSkyWarsMode(data, 'kit_basic_solo_disco'); + this.frog = new BaseSkyWarsMode(data, 'kit_basic_solo_frog'); + this.baseballPlayer = new BaseSkyWarsMode(data, 'kit_basic_solo_baseball-player'); + this.princess = new BaseSkyWarsMode(data, 'kit_basic_solo_princess'); + this.batguy = new BaseSkyWarsMode(data, 'kit_basic_solo_batguy'); + this.healer = new BaseSkyWarsMode(data, 'kit_basic_solo_healer'); + this.cactus = new BaseSkyWarsMode(data, 'kit_basic_solo_cactus'); + this.warlock = new BaseSkyWarsMode(data, 'kit_basic_solo_warlock'); + this.archeologist = new BaseSkyWarsMode(data, 'kit_basic_solo_archeologist'); + this.fallenAngel = new BaseSkyWarsMode(data, 'kit_basic_solo_fallen-angel'); + } +} + +export default SkyWarsSoloKitsBasic; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.test.ts new file mode 100644 index 000000000..3feef3746 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.test.ts @@ -0,0 +1,21 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsLab from './SkyWarsSoloKitsLab.js'; +import SkyWarsSoloKitsLabAdvanced from './SkyWarsSoloKitsLabAdvanced.js'; +import SkyWarsSoloKitsLabBasic from './SkyWarsSoloKitsLabBasic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsLab', () => { + const data = new SkyWarsSoloKitsLab({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsLab); + expectTypeOf(data).toEqualTypeOf(); + expect(data.basic).toBeDefined(); + expect(data.basic).toBeInstanceOf(SkyWarsSoloKitsLabBasic); + expectTypeOf(data.basic).toEqualTypeOf(); + expect(data.advanced).toBeDefined(); + expect(data.advanced).toBeInstanceOf(SkyWarsSoloKitsLabAdvanced); + expectTypeOf(data.advanced).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderChest).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.ts new file mode 100644 index 000000000..1c5d308b2 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.ts @@ -0,0 +1,16 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsSoloKitsLabAdvanced from './SkyWarsSoloKitsLabAdvanced.ts'; +import SkyWarsSoloKitsLabBasic from './SkyWarsSoloKitsLabBasic.js'; + +class SkyWarsSoloKitsLab { + basic: SkyWarsSoloKitsLabBasic; + advanced: SkyWarsSoloKitsLabAdvanced; + enderChest: BaseSkyWarsMode; + constructor(data: Record) { + this.basic = new SkyWarsSoloKitsLabBasic(data); + this.advanced = new SkyWarsSoloKitsLabAdvanced(data); + this.enderChest = new BaseSkyWarsMode(data, 'lab_kit_enderchest_solo_enderchest'); + } +} + +export default SkyWarsSoloKitsLab; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.test.ts new file mode 100644 index 000000000..b148abb4a --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.test.ts @@ -0,0 +1,58 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsLabAdvanced from './SkyWarsSoloKitsLabAdvanced.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsLabAdvanced', () => { + const data = new SkyWarsSoloKitsLabAdvanced({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsLabAdvanced); + expectTypeOf(data).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.salmon).toBeDefined(); + expect(data.salmon).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.salmon).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.pyro).toBeDefined(); + expect(data.pyro).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyro).toEqualTypeOf(); + expect(data.zookeeper).toBeDefined(); + expect(data.zookeeper).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.zookeeper).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.farmer).toBeDefined(); + expect(data.farmer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.farmer).toEqualTypeOf(); + expect(data.enchanter).toBeDefined(); + expect(data.enchanter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enchanter).toEqualTypeOf(); + expect(data.jester).toBeDefined(); + expect(data.jester).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.jester).toEqualTypeOf(); + expect(data.engineer).toBeDefined(); + expect(data.engineer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.engineer).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.cannoneer).toBeDefined(); + expect(data.cannoneer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cannoneer).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.sloth).toBeDefined(); + expect(data.sloth).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.sloth).toEqualTypeOf(); + expect(data.pigRider).toBeDefined(); + expect(data.pigRider).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pigRider).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.ts new file mode 100644 index 000000000..b603fb230 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.ts @@ -0,0 +1,40 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsLabAdvanced { + armorer: BaseSkyWarsMode; + salmon: BaseSkyWarsMode; + knight: BaseSkyWarsMode; + pyro: BaseSkyWarsMode; + zookeeper: BaseSkyWarsMode; + slime: BaseSkyWarsMode; + farmer: BaseSkyWarsMode; + enchanter: BaseSkyWarsMode; + jester: BaseSkyWarsMode; + engineer: BaseSkyWarsMode; + enderman: BaseSkyWarsMode; + cannoneer: BaseSkyWarsMode; + hunter: BaseSkyWarsMode; + sloth: BaseSkyWarsMode; + pigRider: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + constructor(data: Record) { + this.armorer = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_armorer'); + this.salmon = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_salmon'); + this.knight = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_knight'); + this.pyro = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_pyro'); + this.zookeeper = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_zookeeper'); + this.slime = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_slime'); + this.farmer = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_farmer'); + this.enchanter = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_enchanter'); + this.jester = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_jester'); + this.engineer = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_engineer'); + this.enderman = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_enderman'); + this.cannoneer = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_cannoneer'); + this.hunter = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_hunter'); + this.sloth = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_sloth'); + this.pigRider = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_pig-rider'); + this.magician = new BaseSkyWarsMode(data, 'lab_kit_advanced_solo_magician'); + } +} + +export default SkyWarsSoloKitsLabAdvanced; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.test.ts new file mode 100644 index 000000000..01bf7e74d --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.test.ts @@ -0,0 +1,61 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsLabBasic from './SkyWarsSoloKitsLabBasic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsLabBasic', () => { + const data = new SkyWarsSoloKitsLabBasic({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsLabBasic); + expectTypeOf(data).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.ecologist).toBeDefined(); + expect(data.ecologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.ecologist).toEqualTypeOf(); + expect(data.speleologist).toBeDefined(); + expect(data.speleologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.speleologist).toEqualTypeOf(); + expect(data.armorsmith).toBeDefined(); + expect(data.armorsmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorsmith).toEqualTypeOf(); + expect(data.energix).toBeDefined(); + expect(data.energix).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.energix).toEqualTypeOf(); + expect(data.baseballPlayer).toBeDefined(); + expect(data.baseballPlayer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.baseballPlayer).toEqualTypeOf(); + expect(data.disco).toBeDefined(); + expect(data.disco).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.disco).toEqualTypeOf(); + expect(data.pharaoh).toBeDefined(); + expect(data.pharaoh).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pharaoh).toEqualTypeOf(); + expect(data.frog).toBeDefined(); + expect(data.frog).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.frog).toEqualTypeOf(); + expect(data.grenade).toBeDefined(); + expect(data.grenade).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.grenade).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.rookie).toBeDefined(); + expect(data.rookie).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.rookie).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.troll).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.princess).toBeDefined(); + expect(data.princess).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.princess).toEqualTypeOf(); + expect(data.batguy).toBeDefined(); + expect(data.batguy).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.batguy).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.ts new file mode 100644 index 000000000..2e69232a1 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.ts @@ -0,0 +1,42 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsLabBasic { + default: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + ecologist: BaseSkyWarsMode; + speleologist: BaseSkyWarsMode; + armorsmith: BaseSkyWarsMode; + energix: BaseSkyWarsMode; + baseballPlayer: BaseSkyWarsMode; + disco: BaseSkyWarsMode; + pharaoh: BaseSkyWarsMode; + frog: BaseSkyWarsMode; + grenade: BaseSkyWarsMode; + fisherman: BaseSkyWarsMode; + rookie: BaseSkyWarsMode; + troll: BaseSkyWarsMode; + snowman: BaseSkyWarsMode; + princess: BaseSkyWarsMode; + batguy: BaseSkyWarsMode; + constructor(data: Record) { + this.default = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_default'); + this.scout = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_scout'); + this.ecologist = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_ecologist'); + this.speleologist = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_speleologist'); + this.armorsmith = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_armorsmith'); + this.energix = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_energix'); + this.baseballPlayer = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_baseball-player'); + this.disco = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_disco'); + this.pharaoh = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_pharaoh'); + this.frog = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_frog'); + this.grenade = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_grenade'); + this.fisherman = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_fisherman'); + this.rookie = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_rookie'); + this.troll = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_troll'); + this.snowman = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_snowman'); + this.princess = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_princess'); + this.batguy = new BaseSkyWarsMode(data, 'lab_kit_basic_solo_batguy'); + } +} + +export default SkyWarsSoloKitsLabBasic; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.test.ts new file mode 100644 index 000000000..7150a0ef9 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.test.ts @@ -0,0 +1,43 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsMini from './SkyWarsSoloKitsMini.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsMini', () => { + const data = new SkyWarsSoloKitsMini({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsMini); + expectTypeOf(data).toEqualTypeOf(); + expect(data.athlete).toBeDefined(); + expect(data.athlete).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.athlete).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.champion).toBeDefined(); + expect(data.champion).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.champion).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); + expect(data.bowman).toBeDefined(); + expect(data.bowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.bowman).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.pyromancer).toBeDefined(); + expect(data.pyromancer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyromancer).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.blacksmith).toBeDefined(); + expect(data.blacksmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.blacksmith).toEqualTypeOf(); + expect(data.hound).toBeDefined(); + expect(data.hound).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hound).toEqualTypeOf(); + expect(data.paladin).toBeDefined(); + expect(data.paladin).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.paladin).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.ts new file mode 100644 index 000000000..f9eef776e --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.ts @@ -0,0 +1,30 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsMini { + athlete: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + champion: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + bowman: BaseSkyWarsMode; + healer: BaseSkyWarsMode; + pyromancer: BaseSkyWarsMode; + armorer: BaseSkyWarsMode; + blacksmith: BaseSkyWarsMode; + hound: BaseSkyWarsMode; + paladin: BaseSkyWarsMode; + constructor(data: Record) { + this.athlete = new BaseSkyWarsMode(data, 'kit_mini_solo_athlete'); + this.scout = new BaseSkyWarsMode(data, 'kit_mini_solo_scout'); + this.champion = new BaseSkyWarsMode(data, 'kit_mini_solo_champion'); + this.magician = new BaseSkyWarsMode(data, 'kit_mini_solo_magician'); + this.bowman = new BaseSkyWarsMode(data, 'kit_mini_solo_bowman'); + this.healer = new BaseSkyWarsMode(data, 'kit_mini_solo_healer'); + this.pyromancer = new BaseSkyWarsMode(data, 'kit_mini_solo_pyromancer'); + this.armorer = new BaseSkyWarsMode(data, 'kit_mini_solo_armorer'); + this.blacksmith = new BaseSkyWarsMode(data, 'kit_mini_solo_blacksmith'); + this.hound = new BaseSkyWarsMode(data, 'kit_mini_solo_hound'); + this.paladin = new BaseSkyWarsMode(data, 'kit_mini_solo_paladin'); + } +} + +export default SkyWarsSoloKitsMini; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.test.ts new file mode 100644 index 000000000..6b47a0d23 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.test.ts @@ -0,0 +1,21 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsTourney from './SkyWarsSoloKitsTourney.js'; +import SkyWarsSoloKitsTourneyAdvanced from './SkyWarsSoloKitsTourneyAdvanced.js'; +import SkyWarsSoloKitsTourneyBasic from './SkyWarsSoloKitsTourneyBasic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsTourney', () => { + const data = new SkyWarsSoloKitsTourney({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsTourney); + expectTypeOf(data).toEqualTypeOf(); + expect(data.basic).toBeDefined(); + expect(data.basic).toBeInstanceOf(SkyWarsSoloKitsTourneyBasic); + expectTypeOf(data.basic).toEqualTypeOf(); + expect(data.advanced).toBeDefined(); + expect(data.advanced).toBeInstanceOf(SkyWarsSoloKitsTourneyAdvanced); + expectTypeOf(data.advanced).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderChest).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.ts new file mode 100644 index 000000000..2be391133 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.ts @@ -0,0 +1,16 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsSoloKitsTourneyAdvanced from './SkyWarsSoloKitsTourneyAdvanced.ts'; +import SkyWarsSoloKitsTourneyBasic from './SkyWarsSoloKitsTourneyBasic.ts'; + +class SkyWarsSoloKitsTourney { + basic: SkyWarsSoloKitsTourneyBasic; + advanced: SkyWarsSoloKitsTourneyAdvanced; + enderChest: BaseSkyWarsMode; + constructor(data: Record) { + this.basic = new SkyWarsSoloKitsTourneyBasic(data); + this.advanced = new SkyWarsSoloKitsTourneyAdvanced(data); + this.enderChest = new BaseSkyWarsMode(data, 'tourney_kit_enderchest_solo_enderchest'); + } +} + +export default SkyWarsSoloKitsTourney; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.test.ts new file mode 100644 index 000000000..857dcc548 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.test.ts @@ -0,0 +1,49 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsTourneyAdvanced from './SkyWarsSoloKitsTourneyAdvanced.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsTourneyAdvanced', () => { + const data = new SkyWarsSoloKitsTourneyAdvanced({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsTourneyAdvanced); + expectTypeOf(data).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.enchanter).toBeDefined(); + expect(data.enchanter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enchanter).toEqualTypeOf(); + expect(data.farmer).toBeDefined(); + expect(data.farmer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.farmer).toEqualTypeOf(); + expect(data.cannoneer).toBeDefined(); + expect(data.cannoneer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cannoneer).toEqualTypeOf(); + expect(data.jester).toBeDefined(); + expect(data.jester).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.jester).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); + expect(data.zookeeper).toBeDefined(); + expect(data.zookeeper).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.zookeeper).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.engineer).toBeDefined(); + expect(data.engineer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.engineer).toEqualTypeOf(); + expect(data.pigRider).toBeDefined(); + expect(data.pigRider).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pigRider).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.ts new file mode 100644 index 000000000..5e1f821df --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.ts @@ -0,0 +1,34 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsTourneyAdvanced { + armorer: BaseSkyWarsMode; + enderman: BaseSkyWarsMode; + knight: BaseSkyWarsMode; + enchanter: BaseSkyWarsMode; + farmer: BaseSkyWarsMode; + cannoneer: BaseSkyWarsMode; + jester: BaseSkyWarsMode; + hunter: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + zookeeper: BaseSkyWarsMode; + slime: BaseSkyWarsMode; + engineer: BaseSkyWarsMode; + pigRider: BaseSkyWarsMode; + constructor(data: Record) { + this.armorer = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_armorer'); + this.enderman = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_enderman'); + this.knight = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_knight'); + this.enchanter = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_enchanter'); + this.farmer = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_farmer'); + this.cannoneer = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_cannoneer'); + this.jester = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_jester'); + this.hunter = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_hunter'); + this.magician = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_magician'); + this.zookeeper = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_zookeeper'); + this.slime = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_slime'); + this.engineer = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_engineer'); + this.pigRider = new BaseSkyWarsMode(data, 'tourney_kit_advanced_solo_pig-rider'); + } +} + +export default SkyWarsSoloKitsTourneyAdvanced; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.test.ts new file mode 100644 index 000000000..ac08d161a --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.test.ts @@ -0,0 +1,70 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsSoloKitsTourneyBasic from './SkyWarsSoloKitsTourneyBasic.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsSoloKitsTourneyBasic', () => { + const data = new SkyWarsSoloKitsTourneyBasic({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsSoloKitsTourneyBasic); + expectTypeOf(data).toEqualTypeOf(); + expect(data.frog).toBeDefined(); + expect(data.frog).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.frog).toEqualTypeOf(); + expect(data.disco).toBeDefined(); + expect(data.disco).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.disco).toEqualTypeOf(); + expect(data.armorsmith).toBeDefined(); + expect(data.armorsmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorsmith).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.pharaoh).toBeDefined(); + expect(data.pharaoh).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pharaoh).toEqualTypeOf(); + expect(data.ecologist).toBeDefined(); + expect(data.ecologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.ecologist).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.energix).toBeDefined(); + expect(data.energix).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.energix).toEqualTypeOf(); + expect(data.speleologist).toBeDefined(); + expect(data.speleologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.speleologist).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expect(data.cactus).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.rookie).toBeDefined(); + expect(data.rookie).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.rookie).toEqualTypeOf(); + expect(data.baseballPlayer).toBeDefined(); + expect(data.baseballPlayer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.baseballPlayer).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.princess).toBeDefined(); + expect(data.princess).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.princess).toEqualTypeOf(); + expect(data.grenade).toBeDefined(); + expect(data.grenade).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.grenade).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.troll).toEqualTypeOf(); + expect(data.warlock).toBeDefined(); + expect(data.warlock).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.warlock).toEqualTypeOf(); + expect(data.batguy).toBeDefined(); + expect(data.batguy).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.batguy).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.ts b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.ts new file mode 100644 index 000000000..c6cb949c0 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.ts @@ -0,0 +1,48 @@ +import BaseSkyWarsMode from '../../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsSoloKitsTourneyBasic { + frog: BaseSkyWarsMode; + disco: BaseSkyWarsMode; + armorsmith: BaseSkyWarsMode; + fisherman: BaseSkyWarsMode; + pharaoh: BaseSkyWarsMode; + ecologist: BaseSkyWarsMode; + healer: BaseSkyWarsMode; + energix: BaseSkyWarsMode; + speleologist: BaseSkyWarsMode; + cactus: BaseSkyWarsMode; + rookie: BaseSkyWarsMode; + baseballPlayer: BaseSkyWarsMode; + default: BaseSkyWarsMode; + scout: BaseSkyWarsMode; + snowman: BaseSkyWarsMode; + princess: BaseSkyWarsMode; + grenade: BaseSkyWarsMode; + troll: BaseSkyWarsMode; + warlock: BaseSkyWarsMode; + batguy: BaseSkyWarsMode; + constructor(data: Record) { + this.frog = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_frog'); + this.disco = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_disco'); + this.armorsmith = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_armorsmith'); + this.fisherman = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_fisherman'); + this.pharaoh = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_pharaoh'); + this.ecologist = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_ecologist'); + this.healer = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_healer'); + this.energix = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_energix'); + this.speleologist = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_speleologist'); + this.cactus = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_cactus'); + this.rookie = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_rookie'); + this.baseballPlayer = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_baseball-player'); + this.default = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_default'); + this.scout = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_scout'); + this.snowman = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_snowman'); + this.princess = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_princess'); + this.grenade = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_grenade'); + this.troll = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_troll'); + this.warlock = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_warlock'); + this.batguy = new BaseSkyWarsMode(data, 'tourney_kit_basic_solo_batguy'); + } +} + +export default SkyWarsSoloKitsTourneyBasic; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.test.ts new file mode 100644 index 000000000..10815d401 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.test.ts @@ -0,0 +1,90 @@ +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.js'; +import SkyWarsTeams from './SkyWarsTeams.js'; +import SkyWarsTeamsKits from './SkyWarsTeamsKits/SkyWarsTeamsKits.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeams', () => { + const data = new SkyWarsTeams({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeams); + expectTypeOf(data).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.insane).toBeDefined(); + expect(data.insane).toBeInstanceOf(SkyWarsMode); + expectTypeOf(data.insane).toEqualTypeOf(); + expect(data.kits).toBeDefined(); + expect(data.kits).toBeInstanceOf(SkyWarsTeamsKits); + expectTypeOf(data.kits).toEqualTypeOf(); + expect(data.instantSmelting).toBeDefined(); + expect(data.instantSmelting).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.instantSmelting).toEqualTypeOf(); + expect(data.enderMastery).toBeDefined(); + expect(data.enderMastery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.enderMastery).toEqualTypeOf(); + expect(data.resistanceBoost).toBeDefined(); + expect(data.resistanceBoost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.resistanceBoost).toEqualTypeOf(); + expect(data.miningExpertise).toBeDefined(); + expect(data.miningExpertise).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.miningExpertise).toEqualTypeOf(); + expect(data.juggernaut).toBeDefined(); + expect(data.juggernaut).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.juggernaut).toEqualTypeOf(); + expect(data.blazingArrows).toBeDefined(); + expect(data.blazingArrows).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blazingArrows).toEqualTypeOf(); + expect(data.arrowRecovery).toBeDefined(); + expect(data.arrowRecovery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.arrowRecovery).toEqualTypeOf(); + expect(data.speedBoost).toBeDefined(); + expect(data.speedBoost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.speedBoost).toEqualTypeOf(); + expect(data.fat).toBeDefined(); + expect(data.fat).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.fat).toEqualTypeOf(); + expect(data.nourishment).toBeDefined(); + expect(data.nourishment).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.nourishment).toEqualTypeOf(); + expect(data.knowledge).toBeDefined(); + expect(data.knowledge).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.knowledge).toEqualTypeOf(); + expect(data.savior).toBeDefined(); + expect(data.savior).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.savior).toEqualTypeOf(); + expect(data.marksmanship).toBeDefined(); + expect(data.marksmanship).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.marksmanship).toEqualTypeOf(); + expect(data.bridger).toBeDefined(); + expect(data.bridger).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.bridger).toEqualTypeOf(); + expect(data.luckyCharm).toBeDefined(); + expect(data.luckyCharm).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.luckyCharm).toEqualTypeOf(); + expect(data.necromancer).toBeDefined(); + expect(data.necromancer).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.necromancer).toEqualTypeOf(); + expect(data.blackMagic).toBeDefined(); + expect(data.blackMagic).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.blackMagic).toEqualTypeOf(); + expect(data.environmentalExpert).toBeDefined(); + expect(data.environmentalExpert).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.environmentalExpert).toEqualTypeOf(); + expect(data.robbery).toBeDefined(); + expect(data.robbery).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.robbery).toEqualTypeOf(); + expect(data.frost).toBeDefined(); + expect(data.frost).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.frost).toEqualTypeOf(); + expect(data.annoyOMite).toBeDefined(); + expect(data.annoyOMite).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.annoyOMite).toEqualTypeOf(); + expect(data.bulldozer).toBeDefined(); + expect(data.bulldozer).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.bulldozer).toEqualTypeOf(); + expect(data.barbarian).toBeDefined(); + expect(data.barbarian).toBeInstanceOf(SkyWarsModePerk); + expectTypeOf(data.barbarian).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.ts new file mode 100644 index 000000000..eb4605726 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.ts @@ -0,0 +1,63 @@ +import SkyWarsMode from '../SkyWarsMode/SkyWarsMode.ts'; +import SkyWarsModePerk from '../SkyWarsMode/SkyWarsModePerk.ts'; +import SkyWarsTeamsKits from './SkyWarsTeamsKits/SkyWarsTeamsKits.ts'; + +class SkyWarsTeams extends SkyWarsMode { + normal: SkyWarsMode; + insane: SkyWarsMode; + kits: SkyWarsTeamsKits; + instantSmelting: SkyWarsModePerk; + enderMastery: SkyWarsModePerk; + resistanceBoost: SkyWarsModePerk; + miningExpertise: SkyWarsModePerk; + juggernaut: SkyWarsModePerk; + blazingArrows: SkyWarsModePerk; + arrowRecovery: SkyWarsModePerk; + speedBoost: SkyWarsModePerk; + fat: SkyWarsModePerk; + nourishment: SkyWarsModePerk; + knowledge: SkyWarsModePerk; + savior: SkyWarsModePerk; + marksmanship: SkyWarsModePerk; + bridger: SkyWarsModePerk; + luckyCharm: SkyWarsModePerk; + necromancer: SkyWarsModePerk; + blackMagic: SkyWarsModePerk; + environmentalExpert: SkyWarsModePerk; + robbery: SkyWarsModePerk; + frost: SkyWarsModePerk; + annoyOMite: SkyWarsModePerk; + bulldozer: SkyWarsModePerk; + barbarian: SkyWarsModePerk; + constructor(data: Record) { + super(data, 'team'); + this.normal = new SkyWarsMode(data, 'team_normal'); + this.insane = new SkyWarsMode(data, 'team_insane'); + this.kits = new SkyWarsTeamsKits(data); + this.instantSmelting = new SkyWarsModePerk(data, 'instant_smelting', 'team'); + this.enderMastery = new SkyWarsModePerk(data, 'ender_mastery', 'team'); + this.resistanceBoost = new SkyWarsModePerk(data, 'resistance_boost', 'team'); + this.miningExpertise = new SkyWarsModePerk(data, 'mining_expertise', 'team'); + this.juggernaut = new SkyWarsModePerk(data, 'juggernaut', 'team'); + this.blazingArrows = new SkyWarsModePerk(data, 'blazing_arrows', 'team'); + this.arrowRecovery = new SkyWarsModePerk(data, 'arrow_recovery', 'team'); + this.speedBoost = new SkyWarsModePerk(data, 'speed_boost', 'team'); + this.fat = new SkyWarsModePerk(data, 'fat', 'team'); + this.nourishment = new SkyWarsModePerk(data, 'nourishment', 'team'); + this.knowledge = new SkyWarsModePerk(data, 'knowledge', 'team'); + this.savior = new SkyWarsModePerk(data, 'savior', 'team'); + this.marksmanship = new SkyWarsModePerk(data, 'marksmanship', 'team'); + this.bridger = new SkyWarsModePerk(data, 'bridger', 'team'); + this.luckyCharm = new SkyWarsModePerk(data, 'lucky_charm', 'team'); + this.necromancer = new SkyWarsModePerk(data, 'necromancer', 'team'); + this.blackMagic = new SkyWarsModePerk(data, 'black_magic', 'team'); + this.environmentalExpert = new SkyWarsModePerk(data, 'environmental_expert', 'team'); + this.robbery = new SkyWarsModePerk(data, 'robbery', 'team'); + this.frost = new SkyWarsModePerk(data, 'frost', 'team'); + this.annoyOMite = new SkyWarsModePerk(data, 'annoy-o-mite', 'team'); + this.bulldozer = new SkyWarsModePerk(data, 'bulldozer', 'team'); + this.barbarian = new SkyWarsModePerk(data, 'barbarian', 'team'); + } +} + +export default SkyWarsTeams; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.test.ts new file mode 100644 index 000000000..32b7e3c33 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.test.ts @@ -0,0 +1,29 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsTeamsKits from './SkyWarsTeamsKits.js'; +import SkyWarsTeamsKitsAttacking from './SkyWarsTeamsKitsAttacking.js'; +import SkyWarsTeamsKitsDefending from './SkyWarsTeamsKitsDefending.js'; +import SkyWarsTeamsKitsMining from './SkyWarsTeamsKitsMining.js'; +import SkyWarsTeamsKitsSupporting from './SkyWarsTeamsKitsSupporting.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeamsKits', () => { + const data = new SkyWarsTeamsKits({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeamsKits); + expectTypeOf(data).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expect(data.mining).toBeInstanceOf(SkyWarsTeamsKitsMining); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.defending).toBeDefined(); + expect(data.defending).toBeInstanceOf(SkyWarsTeamsKitsDefending); + expectTypeOf(data.defending).toEqualTypeOf(); + expect(data.supporting).toBeDefined(); + expect(data.supporting).toBeInstanceOf(SkyWarsTeamsKitsSupporting); + expectTypeOf(data.supporting).toEqualTypeOf(); + expect(data.attacking).toBeDefined(); + expect(data.attacking).toBeInstanceOf(SkyWarsTeamsKitsAttacking); + expectTypeOf(data.attacking).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderChest).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.ts new file mode 100644 index 000000000..144647f33 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.ts @@ -0,0 +1,22 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; +import SkyWarsTeamsKitsAttacking from './SkyWarsTeamsKitsAttacking.ts'; +import SkyWarsTeamsKitsDefending from './SkyWarsTeamsKitsDefending.ts'; +import SkyWarsTeamsKitsMining from './SkyWarsTeamsKitsMining.ts'; +import SkyWarsTeamsKitsSupporting from './SkyWarsTeamsKitsSupporting.ts'; + +class SkyWarsTeamsKits { + mining: SkyWarsTeamsKitsMining; + defending: SkyWarsTeamsKitsDefending; + supporting: SkyWarsTeamsKitsSupporting; + attacking: SkyWarsTeamsKitsAttacking; + enderChest: BaseSkyWarsMode; + constructor(data: Record) { + this.mining = new SkyWarsTeamsKitsMining(data); + this.defending = new SkyWarsTeamsKitsDefending(data); + this.supporting = new SkyWarsTeamsKitsSupporting(data); + this.attacking = new SkyWarsTeamsKitsAttacking(data); + this.enderChest = new BaseSkyWarsMode(data, 'kit_enderchest_team_enderchest'); + } +} + +export default SkyWarsTeamsKits; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.test.ts new file mode 100644 index 000000000..898631e9b --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.test.ts @@ -0,0 +1,67 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsTeamsKitsAttacking from './SkyWarsTeamsKitsAttacking.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeamsKitsAttacking', () => { + const data = new SkyWarsTeamsKitsAttacking({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeamsKitsAttacking); + expectTypeOf(data).toEqualTypeOf(); + expect(data.scout).toBeDefined(); + expect(data.scout).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.scout).toEqualTypeOf(); + expect(data.knight).toBeDefined(); + expect(data.knight).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.knight).toEqualTypeOf(); + expect(data.snowman).toBeDefined(); + expect(data.snowman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.snowman).toEqualTypeOf(); + expect(data.hunter).toBeDefined(); + expect(data.hunter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.hunter).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.energix).toBeDefined(); + expect(data.energix).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.energix).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.salmon).toBeDefined(); + expect(data.salmon).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.salmon).toEqualTypeOf(); + expect(data.sloth).toBeDefined(); + expect(data.sloth).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.sloth).toEqualTypeOf(); + expect(data.pigRider).toBeDefined(); + expect(data.pigRider).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pigRider).toEqualTypeOf(); + expect(data.grenade).toBeDefined(); + expect(data.grenade).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.grenade).toEqualTypeOf(); + expect(data.engineer).toBeDefined(); + expect(data.engineer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.engineer).toEqualTypeOf(); + expect(data.magician).toBeDefined(); + expect(data.magician).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.magician).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.jester).toBeDefined(); + expect(data.jester).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.jester).toEqualTypeOf(); + expect(data.fisherman).toBeDefined(); + expect(data.fisherman).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fisherman).toEqualTypeOf(); + expect(data.archeologist).toBeDefined(); + expect(data.archeologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.archeologist).toEqualTypeOf(); + expect(data.defaultTeams).toBeDefined(); + expect(data.defaultTeams).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.defaultTeams).toEqualTypeOf(); + expect(data.fallenAngel).toBeDefined(); + expect(data.fallenAngel).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.fallenAngel).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.ts new file mode 100644 index 000000000..f84d5b029 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.ts @@ -0,0 +1,46 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsTeamsKitsAttacking { + scout: BaseSkyWarsMode; + knight: BaseSkyWarsMode; + snowman: BaseSkyWarsMode; + hunter: BaseSkyWarsMode; + enderman: BaseSkyWarsMode; + energix: BaseSkyWarsMode; + slime: BaseSkyWarsMode; + salmon: BaseSkyWarsMode; + sloth: BaseSkyWarsMode; + pigRider: BaseSkyWarsMode; + grenade: BaseSkyWarsMode; + engineer: BaseSkyWarsMode; + magician: BaseSkyWarsMode; + default: BaseSkyWarsMode; + jester: BaseSkyWarsMode; + fisherman: BaseSkyWarsMode; + archeologist: BaseSkyWarsMode; + defaultTeams: BaseSkyWarsMode; + fallenAngel: BaseSkyWarsMode; + constructor(data: Record) { + this.scout = new BaseSkyWarsMode(data, 'kit_attacking_team_scout'); + this.knight = new BaseSkyWarsMode(data, 'kit_attacking_team_knight'); + this.snowman = new BaseSkyWarsMode(data, 'kit_attacking_team_snowman'); + this.hunter = new BaseSkyWarsMode(data, 'kit_attacking_team_hunter'); + this.enderman = new BaseSkyWarsMode(data, 'kit_attacking_team_enderman'); + this.energix = new BaseSkyWarsMode(data, 'kit_attacking_team_energix'); + this.slime = new BaseSkyWarsMode(data, 'kit_attacking_team_slime'); + this.salmon = new BaseSkyWarsMode(data, 'kit_attacking_team_salmon'); + this.sloth = new BaseSkyWarsMode(data, 'kit_attacking_team_sloth'); + this.pigRider = new BaseSkyWarsMode(data, 'kit_attacking_team_pig-rider'); + this.grenade = new BaseSkyWarsMode(data, 'kit_attacking_team_grenade'); + this.engineer = new BaseSkyWarsMode(data, 'kit_attacking_team_engineer'); + this.magician = new BaseSkyWarsMode(data, 'kit_attacking_team_magician'); + this.default = new BaseSkyWarsMode(data, 'kit_attacking_team_default'); + this.jester = new BaseSkyWarsMode(data, 'kit_attacking_team_jester'); + this.fisherman = new BaseSkyWarsMode(data, 'kit_attacking_team_fisherman'); + this.archeologist = new BaseSkyWarsMode(data, 'kit_attacking_team_archeologist'); + this.defaultTeams = new BaseSkyWarsMode(data, 'kit_attacking_teams_default'); + this.fallenAngel = new BaseSkyWarsMode(data, 'kit_attacking_team_fallen-angel'); + } +} + +export default SkyWarsTeamsKitsAttacking; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.test.ts new file mode 100644 index 000000000..bf72180e8 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.test.ts @@ -0,0 +1,37 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsTeamsKitsDefending from './SkyWarsTeamsKitsDefending.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeamsKitsDefending', () => { + const data = new SkyWarsTeamsKitsDefending({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeamsKitsDefending); + expectTypeOf(data).toEqualTypeOf(); + expect(data.armorer).toBeDefined(); + expect(data.armorer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorer).toEqualTypeOf(); + expect(data.baseballPlayer).toBeDefined(); + expect(data.baseballPlayer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.baseballPlayer).toEqualTypeOf(); + expect(data.guardian).toBeDefined(); + expect(data.guardian).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.guardian).toEqualTypeOf(); + expect(data.batguy).toBeDefined(); + expect(data.batguy).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.batguy).toEqualTypeOf(); + expect(data.frog).toBeDefined(); + expect(data.frog).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.frog).toEqualTypeOf(); + expect(data.disco).toBeDefined(); + expect(data.disco).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.disco).toEqualTypeOf(); + expect(data.farmer).toBeDefined(); + expect(data.farmer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.farmer).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expect(data.cactus).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.golem).toBeDefined(); + expect(data.golem).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.golem).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.ts new file mode 100644 index 000000000..fd416c527 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.ts @@ -0,0 +1,26 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsTeamsKitsDefending { + armorer: BaseSkyWarsMode; + baseballPlayer: BaseSkyWarsMode; + guardian: BaseSkyWarsMode; + batguy: BaseSkyWarsMode; + frog: BaseSkyWarsMode; + disco: BaseSkyWarsMode; + farmer: BaseSkyWarsMode; + cactus: BaseSkyWarsMode; + golem: BaseSkyWarsMode; + constructor(data: Record) { + this.armorer = new BaseSkyWarsMode(data, 'kit_defending_team_armorer'); + this.baseballPlayer = new BaseSkyWarsMode(data, 'kit_defending_team_baseball-player'); + this.guardian = new BaseSkyWarsMode(data, 'kit_defending_team_guardian'); + this.batguy = new BaseSkyWarsMode(data, 'kit_defending_team_batguy'); + this.frog = new BaseSkyWarsMode(data, 'kit_defending_team_frog'); + this.disco = new BaseSkyWarsMode(data, 'kit_defending_team_disco'); + this.farmer = new BaseSkyWarsMode(data, 'kit_defending_team_farmer'); + this.cactus = new BaseSkyWarsMode(data, 'kit_defending_team_cactus'); + this.golem = new BaseSkyWarsMode(data, 'kit_defending_team_golem'); + } +} + +export default SkyWarsTeamsKitsDefending; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.test.ts new file mode 100644 index 000000000..28814e45e --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.test.ts @@ -0,0 +1,22 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsTeamsKitsMining from './SkyWarsTeamsKitsMining.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeamsKitsMining', () => { + const data = new SkyWarsTeamsKitsMining({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeamsKitsMining); + expectTypeOf(data).toEqualTypeOf(); + expect(data.default).toBeDefined(); + expect(data.default).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.default).toEqualTypeOf(); + expect(data.cannoneer).toBeDefined(); + expect(data.cannoneer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.cannoneer).toEqualTypeOf(); + expect(data.speleologist).toBeDefined(); + expect(data.speleologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.speleologist).toEqualTypeOf(); + expect(data.defaultTeams).toBeDefined(); + expect(data.defaultTeams).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.defaultTeams).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.ts new file mode 100644 index 000000000..d081d5c96 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.ts @@ -0,0 +1,16 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsTeamsKitsMining { + default: BaseSkyWarsMode; + cannoneer: BaseSkyWarsMode; + speleologist: BaseSkyWarsMode; + defaultTeams: BaseSkyWarsMode; + constructor(data: Record) { + this.default = new BaseSkyWarsMode(data, 'kit_mining_team_default'); + this.cannoneer = new BaseSkyWarsMode(data, 'kit_mining_team_cannoneer'); + this.speleologist = new BaseSkyWarsMode(data, 'kit_mining_team_speleologist'); + this.defaultTeams = new BaseSkyWarsMode(data, 'kit_mining_teams_default'); + } +} + +export default SkyWarsTeamsKitsMining; diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.test.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.test.ts new file mode 100644 index 000000000..610d97c2c --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.test.ts @@ -0,0 +1,43 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.js'; +import SkyWarsTeamsKitsSupporting from './SkyWarsTeamsKitsSupporting.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyWarsTeamsKitsSupporting', () => { + const data = new SkyWarsTeamsKitsSupporting({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyWarsTeamsKitsSupporting); + expectTypeOf(data).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expect(data.healer).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.ecologist).toBeDefined(); + expect(data.ecologist).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.ecologist).toEqualTypeOf(); + expect(data.armorsmith).toBeDefined(); + expect(data.armorsmith).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.armorsmith).toEqualTypeOf(); + expect(data.rookie).toBeDefined(); + expect(data.rookie).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.rookie).toEqualTypeOf(); + expect(data.enchanter).toBeDefined(); + expect(data.enchanter).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.enchanter).toEqualTypeOf(); + expect(data.pyro).toBeDefined(); + expect(data.pyro).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pyro).toEqualTypeOf(); + expect(data.pharaoh).toBeDefined(); + expect(data.pharaoh).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.pharaoh).toEqualTypeOf(); + expect(data.warlock).toBeDefined(); + expect(data.warlock).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.warlock).toEqualTypeOf(); + expect(data.zookeeper).toBeDefined(); + expect(data.zookeeper).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.zookeeper).toEqualTypeOf(); + expect(data.princess).toBeDefined(); + expect(data.princess).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.princess).toEqualTypeOf(); + expect(data.troll).toBeDefined(); + expect(data.troll).toBeInstanceOf(BaseSkyWarsMode); + expectTypeOf(data.troll).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.ts b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.ts new file mode 100644 index 000000000..0f9413bc8 --- /dev/null +++ b/src/Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.ts @@ -0,0 +1,30 @@ +import BaseSkyWarsMode from '../../SkyWarsMode/BaseSkyWarsMode.ts'; + +class SkyWarsTeamsKitsSupporting { + healer: BaseSkyWarsMode; + ecologist: BaseSkyWarsMode; + armorsmith: BaseSkyWarsMode; + rookie: BaseSkyWarsMode; + enchanter: BaseSkyWarsMode; + pyro: BaseSkyWarsMode; + pharaoh: BaseSkyWarsMode; + warlock: BaseSkyWarsMode; + zookeeper: BaseSkyWarsMode; + princess: BaseSkyWarsMode; + troll: BaseSkyWarsMode; + constructor(data: Record) { + this.healer = new BaseSkyWarsMode(data, 'kit_supporting_team_healer'); + this.ecologist = new BaseSkyWarsMode(data, 'kit_supporting_team_ecologist'); + this.armorsmith = new BaseSkyWarsMode(data, 'kit_supporting_team_armorsmith'); + this.rookie = new BaseSkyWarsMode(data, 'kit_supporting_team_rookie'); + this.enchanter = new BaseSkyWarsMode(data, 'kit_supporting_team_enchanter'); + this.pyro = new BaseSkyWarsMode(data, 'kit_supporting_team_pyro'); + this.pharaoh = new BaseSkyWarsMode(data, 'kit_supporting_team_pharaoh'); + this.warlock = new BaseSkyWarsMode(data, 'kit_supporting_team_warlock'); + this.zookeeper = new BaseSkyWarsMode(data, 'kit_supporting_team_zookeeper'); + this.princess = new BaseSkyWarsMode(data, 'kit_supporting_team_princess'); + this.troll = new BaseSkyWarsMode(data, 'kit_supporting_team_troll'); + } +} + +export default SkyWarsTeamsKitsSupporting; diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.test.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.test.ts new file mode 100644 index 000000000..a4a1580d9 --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.test.ts @@ -0,0 +1,42 @@ +import SmashHeoresHero from './SmashHeoresHero.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SmashHeoresHeros } from '../../../Types/Player.js'; + +test('SmashHeoresHero', () => { + const data = new SmashHeoresHero({ stats: 'meow' }, 'BOTMUN'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xp).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expect(data.prestige).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prestige).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.ts new file mode 100644 index 000000000..0b50718e5 --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeoresHero.ts @@ -0,0 +1,31 @@ +import Divide from '../../../Utils/Divide.js'; +import type { SmashHeoresHeros } from '../../../Types/Player.js'; + +class SmashHeoresHero { + name: SmashHeoresHeros; + level: number; + xp: number; + prestige: number; + playedGames: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + constructor(data: Record, hero: SmashHeoresHeros) { + this.name = hero; + this.level = data?.[`lastLevel_${hero}`] || 0; + this.xp = data?.[`xp_${hero}`] || 0; + this.prestige = data?.[`pg_${hero}`] || 0; + this.playedGames = data?.class_stats?.[hero]?.games || 0; + this.kills = data?.class_stats?.[hero]?.kills || 0; + this.deaths = data?.class_stats?.[hero]?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.class_stats?.[hero]?.wins || 0; + this.losses = data?.class_stats?.[hero]?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + } +} + +export default SmashHeoresHero; diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeroes.test.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeroes.test.ts new file mode 100644 index 000000000..30ed3b76d --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeroes.test.ts @@ -0,0 +1,104 @@ +import SmashHeoresHero from './SmashHeoresHero.js'; +import SmashHeroes from './SmashHeroes.js'; +import SmashHeroesMode from './SmashHeroesMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SmashHeoresHeros } from '../../../Types/Player.js'; + +test('SmashHeroes', () => { + const data = new SmashHeroes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SmashHeroes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.smashed).toBeDefined(); + expect(data.smashed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.smashed).toEqualTypeOf(); + expect(data['1v1v1v1']).toBeDefined(); + expect(data['1v1v1v1']).toBeInstanceOf(SmashHeroesMode); + expectTypeOf(data['1v1v1v1']).toEqualTypeOf(); + expect(data['2v2']).toBeDefined(); + expect(data['2v2']).toBeInstanceOf(SmashHeroesMode); + expectTypeOf(data['2v2']).toEqualTypeOf(); + expect(data['2v2v2']).toBeDefined(); + expect(data['2v2v2']).toBeInstanceOf(SmashHeroesMode); + expectTypeOf(data['2v2v2']).toEqualTypeOf(); + expect(data.activeHero).toBeDefined(); + expectTypeOf(data.activeHero).toEqualTypeOf(); + expect(data.theBulk).toBeDefined(); + expect(data.theBulk).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.theBulk).toEqualTypeOf(); + expect(data.cakeMonster).toBeDefined(); + expect(data.cakeMonster).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.cakeMonster).toEqualTypeOf(); + expect(data.generalCluck).toBeDefined(); + expect(data.generalCluck).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.generalCluck).toEqualTypeOf(); + expect(data.botmun).toBeDefined(); + expect(data.botmun).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.botmun).toEqualTypeOf(); + expect(data.marauder).toBeDefined(); + expect(data.marauder).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.marauder).toEqualTypeOf(); + expect(data.pug).toBeDefined(); + expect(data.pug).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.pug).toEqualTypeOf(); + expect(data.tinman).toBeDefined(); + expect(data.tinman).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.tinman).toEqualTypeOf(); + expect(data.spoderman).toBeDefined(); + expect(data.spoderman).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.spoderman).toEqualTypeOf(); + expect(data.frosty).toBeDefined(); + expect(data.frosty).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.frosty).toEqualTypeOf(); + expect(data.sergeantShield).toBeDefined(); + expect(data.sergeantShield).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.sergeantShield).toEqualTypeOf(); + expect(data.skullfire).toBeDefined(); + expect(data.skullfire).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.skullfire).toEqualTypeOf(); + expect(data.goku).toBeDefined(); + expect(data.goku).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.goku).toEqualTypeOf(); + expect(data.sanic).toBeDefined(); + expect(data.sanic).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.sanic).toEqualTypeOf(); + expect(data.duskCrawler).toBeDefined(); + expect(data.duskCrawler).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.duskCrawler).toEqualTypeOf(); + expect(data.shoopDaWhoop).toBeDefined(); + expect(data.shoopDaWhoop).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.shoopDaWhoop).toEqualTypeOf(); + expect(data.greenHood).toBeDefined(); + expect(data.greenHood).toBeInstanceOf(SmashHeoresHero); + expectTypeOf(data.greenHood).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeroes.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeroes.ts new file mode 100644 index 000000000..4e46206e0 --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeroes.ts @@ -0,0 +1,73 @@ +import Divide from '../../../Utils/Divide.js'; +import SmashHeoresHero from './SmashHeoresHero.js'; +import SmashHeroesMode from './SmashHeroesMode.js'; +import type { SmashHeoresHeros } from '../../../Types/Player.js'; + +class SmashHeroes { + coins: number; + level: number; + winStreak: number; + playedGames: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + smashed: number; + '1v1v1v1': SmashHeroesMode; + '2v2': SmashHeroesMode; + '2v2v2': SmashHeroesMode; + activeHero: SmashHeoresHeros | 'None'; + theBulk: SmashHeoresHero; + cakeMonster: SmashHeoresHero; + generalCluck: SmashHeoresHero; + botmun: SmashHeoresHero; + marauder: SmashHeoresHero; + pug: SmashHeoresHero; + tinman: SmashHeoresHero; + spoderman: SmashHeoresHero; + frosty: SmashHeoresHero; + sergeantShield: SmashHeoresHero; + skullfire: SmashHeoresHero; + goku: SmashHeoresHero; + sanic: SmashHeoresHero; + duskCrawler: SmashHeoresHero; + shoopDaWhoop: SmashHeoresHero; + greenHood: SmashHeoresHero; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.level = data?.smash_level_total || 0; + this.winStreak = data?.win_streak || 0; + this.playedGames = data?.games || 0; + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.smashed = data?.smashed || 0; + this['1v1v1v1'] = new SmashHeroesMode(data, 'normal'); + this['2v2'] = new SmashHeroesMode(data, '2v2'); + this['2v2v2'] = new SmashHeroesMode(data, 'teams'); + this.activeHero = data?.active_class || 'None'; + this.theBulk = new SmashHeoresHero(data, 'THE_BULK'); + this.cakeMonster = new SmashHeoresHero(data, 'CAKE_MONSTER'); + this.generalCluck = new SmashHeoresHero(data, 'GENERAL_CLUCK'); + this.botmun = new SmashHeoresHero(data, 'BOTMUN'); + this.marauder = new SmashHeoresHero(data, 'MARAUDER'); + this.pug = new SmashHeoresHero(data, 'PUG'); + this.tinman = new SmashHeoresHero(data, 'TINMAN'); + this.spoderman = new SmashHeoresHero(data, 'SPODERMAN'); + this.frosty = new SmashHeoresHero(data, 'FROSTY'); + this.sergeantShield = new SmashHeoresHero(data, 'SERGEANT_SHIELD'); + this.skullfire = new SmashHeoresHero(data, 'SKULLFIRE'); + this.goku = new SmashHeoresHero(data, 'GOKU'); + this.sanic = new SmashHeoresHero(data, 'SANIC'); + this.duskCrawler = new SmashHeoresHero(data, 'DUSK_CRAWLER'); + this.shoopDaWhoop = new SmashHeoresHero(data, 'SHOOP_DA_WHOOP'); + this.greenHood = new SmashHeoresHero(data, 'GREEN_HOOD'); + } +} + +export default SmashHeroes; diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.test.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.test.ts new file mode 100644 index 000000000..420ba1a68 --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.test.ts @@ -0,0 +1,27 @@ +import SmashHeroesMode from './SmashHeroesMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SmashHeroesMode', () => { + const data = new SmashHeroesMode({ stats: 'meow' }, '2v2'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SmashHeroesMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.ts b/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.ts new file mode 100644 index 000000000..1943cdaea --- /dev/null +++ b/src/Structures/MiniGames/SmashHeroes/SmashHeroesMode.ts @@ -0,0 +1,21 @@ +import Divide from '../../../Utils/Divide.js'; +import type { SmashHeoresModes } from '../../../Types/Player.js'; + +class SmashHeroesMode { + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + constructor(data: Record, mode: SmashHeoresModes) { + this.kills = data?.[`kills_${mode}`] || 0; + this.deaths = data?.[`deaths_${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`wins_${mode}`] || 0; + this.losses = data?.[`losses_${mode}`] || 0; + this.WLR = Divide(this.wins, this.losses); + } +} + +export default SmashHeroesMode; diff --git a/src/Structures/MiniGames/SpeedUHC/SpeedUHC.test.ts b/src/Structures/MiniGames/SpeedUHC/SpeedUHC.test.ts new file mode 100644 index 000000000..2ea5db536 --- /dev/null +++ b/src/Structures/MiniGames/SpeedUHC/SpeedUHC.test.ts @@ -0,0 +1,73 @@ +import SpeedUHC from './SpeedUHC.js'; +import SpeedUHCMode from './SpeedUHCMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SpeedUHC', () => { + const data = new SpeedUHC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SpeedUHC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.killStreak).toBeDefined(); + expect(data.killStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killStreak).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.blocksPlaced).toBeDefined(); + expect(data.blocksPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksPlaced).toEqualTypeOf(); + expect(data.quits).toBeDefined(); + expect(data.quits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quits).toEqualTypeOf(); + expect(data.itemsEnchanted).toBeDefined(); + expect(data.itemsEnchanted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemsEnchanted).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.soloNormal).toBeDefined(); + expect(data.soloNormal).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.soloNormal).toEqualTypeOf(); + expect(data.soloInsane).toBeDefined(); + expect(data.soloInsane).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.soloInsane).toEqualTypeOf(); + expect(data.team).toBeDefined(); + expect(data.team).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.team).toEqualTypeOf(); + expect(data.teamNormal).toBeDefined(); + expect(data.teamNormal).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.teamNormal).toEqualTypeOf(); + expect(data.teamInsane).toBeDefined(); + expect(data.teamInsane).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data.teamInsane).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SpeedUHC/SpeedUHC.ts b/src/Structures/MiniGames/SpeedUHC/SpeedUHC.ts new file mode 100644 index 000000000..7c799c36d --- /dev/null +++ b/src/Structures/MiniGames/SpeedUHC/SpeedUHC.ts @@ -0,0 +1,51 @@ +import Divide from '../../../Utils/Divide.js'; +import SpeedUHCMode from './SpeedUHCMode.js'; + +class SpeedUHC { + coins: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + winStreak: number; + killStreak: number; + blocksBroken: number; + blocksPlaced: number; + quits: number; + itemsEnchanted: number; + assists: number; + solo: SpeedUHCMode; + soloNormal: SpeedUHCMode; + soloInsane: SpeedUHCMode; + team: SpeedUHCMode; + teamNormal: SpeedUHCMode; + teamInsane: SpeedUHCMode; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = data?.games || 0; + this.winStreak = data?.win_streak || 0; + this.killStreak = data?.killstreak || 0; + this.blocksBroken = data?.blocks_broken || 0; + this.blocksPlaced = data?.blocks_placed || 0; + this.quits = data?.quits || 0; + this.itemsEnchanted = data?.items_enchanted || 0; + this.assists = data?.assists || 0; + this.solo = new SpeedUHCMode(data, 'solo'); + this.soloNormal = new SpeedUHCMode(data, 'solo_normal'); + this.soloInsane = new SpeedUHCMode(data, 'solo_insane'); + this.team = new SpeedUHCMode(data, 'team'); + this.teamNormal = new SpeedUHCMode(data, 'team_normal'); + this.teamInsane = new SpeedUHCMode(data, 'team_insane'); + } +} + +export default SpeedUHC; diff --git a/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.test.ts b/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.test.ts new file mode 100644 index 000000000..3456dc36b --- /dev/null +++ b/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.test.ts @@ -0,0 +1,39 @@ +import SpeedUHCMode from './SpeedUHCMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SpeedUHCMode', () => { + const data = new SpeedUHCMode({ stats: 'meow' }, 'solo'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SpeedUHCMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.playedGames).toBeDefined(); + expect(data.playedGames).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playedGames).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.killStreak).toBeDefined(); + expect(data.killStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killStreak).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.ts b/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.ts new file mode 100644 index 000000000..ecee7f606 --- /dev/null +++ b/src/Structures/MiniGames/SpeedUHC/SpeedUHCMode.ts @@ -0,0 +1,29 @@ +import Divide from '../../../Utils/Divide.js'; +import type { SpeedUHCModes } from '../../../Types/Player.js'; + +class SpeedUHCMode { + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + playedGames: number; + winStreak: number; + killStreak: number; + assists: number; + constructor(data: Record, mode: SpeedUHCModes) { + this.kills = data?.[`kills_${mode}`] || 0; + this.deaths = data?.[`deaths_${mode}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`wins_${mode}`] || 0; + this.losses = data?.[`losses_${mode}`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.playedGames = data?.[`games_${mode}`] || 0; + this.winStreak = data?.[`win_streak_${mode}`] || 0; + this.killStreak = data?.[`killstreak_${mode}`] || 0; + this.assists = data?.[`assists_${mode}`] || 0; + } +} + +export default SpeedUHCMode; diff --git a/src/Structures/MiniGames/TNTGames/BowSpleef.test.ts b/src/Structures/MiniGames/TNTGames/BowSpleef.test.ts new file mode 100644 index 000000000..cac1dfb9d --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/BowSpleef.test.ts @@ -0,0 +1,21 @@ +import BowSpleef from './BowSpleef.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorString } from '../../../Types/Color.js'; + +test('BowSpleef', () => { + const data = new BowSpleef({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BowSpleef); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.tags).toBeDefined(); + expect(data.tags).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tags).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.prefixColor).toBeDefined(); + expectTypeOf(data.prefixColor).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/BowSpleef.ts b/src/Structures/MiniGames/TNTGames/BowSpleef.ts new file mode 100644 index 000000000..d09b35423 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/BowSpleef.ts @@ -0,0 +1,16 @@ +import type { ColorString } from '../../../Types/Color.js'; + +class BowSpleef { + wins: number; + tags: number; + deaths: number; + prefixColor: ColorString | 'Rainbow'; + constructor(data: Record) { + this.wins = data?.wins_bowspleef || 0; + this.tags = data?.tags_bowspleef || 0; + this.deaths = data?.deaths_bowspleef || 0; + this.prefixColor = data?.prefix_bowspleef || ''; + } +} + +export default BowSpleef; diff --git a/src/Structures/MiniGames/TNTGames/PVPRun.test.ts b/src/Structures/MiniGames/TNTGames/PVPRun.test.ts new file mode 100644 index 000000000..d0e6e7b9e --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/PVPRun.test.ts @@ -0,0 +1,39 @@ +import PVPRun from './PVPRun.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorString } from '../../../Types/Color.js'; + +test('PVPRun', () => { + const data = new PVPRun({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PVPRun); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.bestTime).toBeDefined(); + expect(data.bestTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestTime).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.regeneration).toBeDefined(); + expect(data.regeneration).toBeGreaterThanOrEqual(0); + expectTypeOf(data.regeneration).toEqualTypeOf(); + expect(data.notoriety).toBeDefined(); + expect(data.notoriety).toBeGreaterThanOrEqual(0); + expectTypeOf(data.notoriety).toEqualTypeOf(); + expect(data.fortitude).toBeDefined(); + expect(data.fortitude).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fortitude).toEqualTypeOf(); + expect(data.doubleJumps).toBeDefined(); + expect(data.doubleJumps).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doubleJumps).toEqualTypeOf(); + expect(data.prefixColor).toBeDefined(); + expectTypeOf(data.prefixColor).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/PVPRun.ts b/src/Structures/MiniGames/TNTGames/PVPRun.ts new file mode 100644 index 000000000..2933c7ba1 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/PVPRun.ts @@ -0,0 +1,29 @@ +import Divide from '../../../Utils/Divide.js'; +import type { ColorString } from '../../../Types/Color.js'; + +class PVPRun { + wins: number; + bestTime: number; + kills: number; + deaths: number; + KDR: number; + regeneration: number; + notoriety: number; + fortitude: number; + doubleJumps: number; + prefixColor: ColorString | 'Rainbow'; + constructor(data: Record) { + this.wins = data?.wins_pvprun || 0; + this.bestTime = data?.record_pvprun || 0; + this.kills = data?.kills_pvprun || 0; + this.deaths = data?.deaths_pvprun || 0; + this.KDR = Divide(this.kills, this.deaths); + this.regeneration = data?.new_pvprun_regeneration || 0; + this.notoriety = data?.new_pvprun_notoriety || 0; + this.fortitude = data?.new_pvprun_fortitude || 0; + this.doubleJumps = data?.new_pvprun_double_jumps || 0; + this.prefixColor = data?.prefix_pvprun || ''; + } +} + +export default PVPRun; diff --git a/src/Structures/MiniGames/TNTGames/TNTGames.test.ts b/src/Structures/MiniGames/TNTGames/TNTGames.test.ts new file mode 100644 index 000000000..ef9689ed0 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTGames.test.ts @@ -0,0 +1,38 @@ +import BowSpleef from './BowSpleef.js'; +import PVPRun from './PVPRun.js'; +import TNTGames from './TNTGames.js'; +import TNTRun from './TNTRun.js'; +import TNTTag from './TNTTag.js'; +import TNTWizards from './TNTWizards.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('TNTGames', () => { + const data = new TNTGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TNTGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.tntrun).toBeDefined(); + expect(data.tntrun).toBeInstanceOf(TNTRun); + expectTypeOf(data.tntrun).toEqualTypeOf(); + expect(data.pvpRun).toBeDefined(); + expect(data.pvpRun).toBeInstanceOf(PVPRun); + expectTypeOf(data.pvpRun).toEqualTypeOf(); + expect(data.bowSpleef).toBeDefined(); + expect(data.bowSpleef).toBeInstanceOf(BowSpleef); + expectTypeOf(data.bowSpleef).toEqualTypeOf(); + expect(data.tnttag).toBeDefined(); + expect(data.tnttag).toBeInstanceOf(TNTTag); + expectTypeOf(data.tnttag).toEqualTypeOf(); + expect(data.wizards).toBeDefined(); + expect(data.wizards).toBeInstanceOf(TNTWizards); + expectTypeOf(data.wizards).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/TNTGames.ts b/src/Structures/MiniGames/TNTGames/TNTGames.ts new file mode 100644 index 000000000..610798274 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTGames.ts @@ -0,0 +1,28 @@ +import BowSpleef from './BowSpleef.js'; +import PVPRun from './PVPRun.js'; +import TNTRun from './TNTRun.js'; +import TNTTag from './TNTTag.js'; +import TNTWizards from './TNTWizards.js'; + +class TNTGames { + coins: number; + winStreak: number; + wins: number; + tntrun: TNTRun; + pvpRun: PVPRun; + bowSpleef: BowSpleef; + tnttag: TNTTag; + wizards: TNTWizards; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.winStreak = data?.winstreak || 0; + this.wins = data?.wins || 0; + this.tntrun = new TNTRun(data); + this.pvpRun = new PVPRun(data); + this.bowSpleef = new BowSpleef(data); + this.tnttag = new TNTTag(data); + this.wizards = new TNTWizards(data); + } +} + +export default TNTGames; diff --git a/src/Structures/MiniGames/TNTGames/TNTRun.test.ts b/src/Structures/MiniGames/TNTGames/TNTRun.test.ts new file mode 100644 index 000000000..1e6cbfb29 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTRun.test.ts @@ -0,0 +1,30 @@ +import TNTRun from './TNTRun.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorString } from '../../../Types/Color.js'; + +test('TNTRun', () => { + const data = new TNTRun({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TNTRun); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.bestTime).toBeDefined(); + expect(data.bestTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestTime).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.slownessPotions).toBeDefined(); + expect(data.slownessPotions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slownessPotions).toEqualTypeOf(); + expect(data.speedPotions).toBeDefined(); + expect(data.speedPotions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speedPotions).toEqualTypeOf(); + expect(data.doubleJumps).toBeDefined(); + expect(data.doubleJumps).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doubleJumps).toEqualTypeOf(); + expect(data.prefix).toBeDefined(); + expectTypeOf(data.prefix).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/TNTRun.ts b/src/Structures/MiniGames/TNTGames/TNTRun.ts new file mode 100644 index 000000000..e48ea3332 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTRun.ts @@ -0,0 +1,22 @@ +import type { ColorString } from '../../../Types/Color.js'; + +class TNTRun { + wins: number; + bestTime: number; + deaths: number; + slownessPotions: number; + speedPotions: number; + doubleJumps: number; + prefix: ColorString | 'Rainbow'; + constructor(data: Record) { + this.wins = data?.wins_tntrun || 0; + this.bestTime = data?.record_tntrun || 0; + this.deaths = data?.deaths_tntrun || 0; + this.slownessPotions = data?.new_tntrun_slowness_potions || 0; + this.speedPotions = data?.new_tntrun_speed_potions || 0; + this.doubleJumps = data?.new_tntrun_double_jumps || 0; + this.prefix = data?.prefix_tntrun || ''; + } +} + +export default TNTRun; diff --git a/src/Structures/MiniGames/TNTGames/TNTTag.test.ts b/src/Structures/MiniGames/TNTGames/TNTTag.test.ts new file mode 100644 index 000000000..1f8080e79 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTTag.test.ts @@ -0,0 +1,36 @@ +import TNTTag from './TNTTag.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorString } from '../../../Types/Color.js'; + +test('TNTTag', () => { + const data = new TNTTag({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TNTTag); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.speed).toBeDefined(); + expect(data.speed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speed).toEqualTypeOf(); + expect(data.blastProtection).toBeDefined(); + expect(data.blastProtection).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blastProtection).toEqualTypeOf(); + expect(data.speedItUp).toBeDefined(); + expect(data.speedItUp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speedItUp).toEqualTypeOf(); + expect(data.slowItDown).toBeDefined(); + expect(data.slowItDown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slowItDown).toEqualTypeOf(); + expect(data.prefix).toBeDefined(); + expectTypeOf(data.prefix).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/TNTTag.ts b/src/Structures/MiniGames/TNTGames/TNTTag.ts new file mode 100644 index 000000000..531d80858 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTTag.ts @@ -0,0 +1,27 @@ +import Divide from '../../../Utils/Divide.js'; +import type { ColorString } from '../../../Types/Color.js'; + +class TNTTag { + wins: number; + kills: number; + deaths: number; + KDR: number; + speed: number; + blastProtection: number; + speedItUp: number; + slowItDown: number; + prefix: ColorString | 'Rainbow'; + constructor(data: Record) { + this.wins = data?.wins_tntag || 0; + this.kills = data?.kills_tntag || 0; + this.deaths = data?.deaths_tntag || 0; + this.KDR = Divide(this.kills, this.deaths); + this.speed = data?.new_tntag_speedy || 0; + this.blastProtection = data?.tag_blastprotection || 0; + this.speedItUp = data?.tag_speeditup || 0; + this.slowItDown = data?.tag_slowitdown || 0; + this.prefix = data?.prefix_tntag || ''; + } +} + +export default TNTTag; diff --git a/src/Structures/MiniGames/TNTGames/TNTWizards.test.ts b/src/Structures/MiniGames/TNTGames/TNTWizards.test.ts new file mode 100644 index 000000000..a15f70e50 --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTWizards.test.ts @@ -0,0 +1,36 @@ +import TNTWizards from './TNTWizards.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ColorString } from '../../../Types/Color.js'; + +test('TNTWizards', () => { + const data = new TNTWizards({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TNTWizards); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.points).toBeDefined(); + expect(data.points).toBeGreaterThanOrEqual(0); + expectTypeOf(data.points).toEqualTypeOf(); + expect(data.kineticHealing).toBeDefined(); + expect(data.kineticHealing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kineticHealing).toEqualTypeOf(); + expect(data.airTime).toBeDefined(); + expect(data.airTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.airTime).toEqualTypeOf(); + expect(data.prefix).toBeDefined(); + expectTypeOf(data.prefix).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TNTGames/TNTWizards.ts b/src/Structures/MiniGames/TNTGames/TNTWizards.ts new file mode 100644 index 000000000..ef23348de --- /dev/null +++ b/src/Structures/MiniGames/TNTGames/TNTWizards.ts @@ -0,0 +1,27 @@ +import Divide from '../../../Utils/Divide.js'; +import type { ColorString } from '../../../Types/Color.js'; + +class TNTWizards { + wins: number; + kills: number; + assists: number; + deaths: number; + KDR: number; + points: number; + kineticHealing: number; + airTime: number; + prefix: ColorString | 'Rainbow'; + constructor(data: Record) { + this.wins = data?.wins_capture || 0; + this.kills = data?.kills_capture || 0; + this.assists = data?.assists_capture || 0; + this.deaths = data?.deaths_capture || 0; + this.KDR = Divide(this.kills, this.deaths); + this.points = data?.points_capture || 0; + this.kineticHealing = data?.kinetic_healing_capture || 0; + this.airTime = data?.air_time_capture || 0; + this.prefix = data?.prefix_capture || ''; + } +} + +export default TNTWizards; diff --git a/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.test.ts b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.test.ts new file mode 100644 index 000000000..22a9b4419 --- /dev/null +++ b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.test.ts @@ -0,0 +1,63 @@ +import TurboKartRacers from './TurboKartRacers.js'; +import TurboKartRacersMap from './TurboKartRacersMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { TurboKartRacersHorn } from '../../../Types/Player.js'; + +test('TurboKartRacers', () => { + const data = new TurboKartRacers({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TurboKartRacers); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.completedLaps).toBeDefined(); + expect(data.completedLaps).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completedLaps).toEqualTypeOf(); + expect(data.bronzeTrophies).toBeDefined(); + expect(data.bronzeTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bronzeTrophies).toEqualTypeOf(); + expect(data.silverTrophies).toBeDefined(); + expect(data.silverTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silverTrophies).toEqualTypeOf(); + expect(data.goldTrophies).toBeDefined(); + expect(data.goldTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldTrophies).toEqualTypeOf(); + expect(data.boxPickups).toBeDefined(); + expect(data.boxPickups).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boxPickups).toEqualTypeOf(); + expect(data.horn).toBeDefined(); + expectTypeOf(data.horn).toEqualTypeOf(); + expect(data.retro).toBeDefined(); + expect(data.retro).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data.retro).toEqualTypeOf(); + expect(data.hypixelgp).toBeDefined(); + expect(data.hypixelgp).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data.hypixelgp).toEqualTypeOf(); + expect(data.olympus).toBeDefined(); + expect(data.olympus).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data.olympus).toEqualTypeOf(); + expect(data.junglerush).toBeDefined(); + expect(data.junglerush).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data.junglerush).toEqualTypeOf(); + expect(data.canyon).toBeDefined(); + expect(data.canyon).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data.canyon).toEqualTypeOf(); + expect(data.bananaHitsReceived).toBeDefined(); + expect(data.bananaHitsReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bananaHitsReceived).toEqualTypeOf(); + expect(data.bananaHitsSent).toBeDefined(); + expect(data.bananaHitsSent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bananaHitsSent).toEqualTypeOf(); + expect(data.blueTorpedoHit).toBeDefined(); + expect(data.blueTorpedoHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blueTorpedoHit).toEqualTypeOf(); + expect(data.grandPrix).toBeDefined(); + expectTypeOf(data.grandPrix).toEqualTypeOf(); + expect(data.grandPrixTokens).toBeDefined(); + expect(data.grandPrixTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grandPrixTokens).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.ts b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.ts new file mode 100644 index 000000000..f64de6d92 --- /dev/null +++ b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacers.ts @@ -0,0 +1,45 @@ +import TurboKartRacersMap from './TurboKartRacersMap.js'; +import type { TurboKartRacersHorn } from '../../../Types/Player.js'; + +class TurboKartRacers { + coins: number; + wins: number; + completedLaps: number; + bronzeTrophies: number; + silverTrophies: number; + goldTrophies: number; + boxPickups: number; + horn: TurboKartRacersHorn; + retro: TurboKartRacersMap; + hypixelgp: TurboKartRacersMap; + olympus: TurboKartRacersMap; + junglerush: TurboKartRacersMap; + canyon: TurboKartRacersMap; + bananaHitsReceived: number; + bananaHitsSent: number; + blueTorpedoHit: number; + grandPrix: boolean; + grandPrixTokens: number; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.wins = data?.wins || 0; + this.completedLaps = data?.laps_completed || 0; + this.bronzeTrophies = data?.bronze_trophy || 0; + this.silverTrophies = data?.silver_trophy || 0; + this.goldTrophies = data?.gold_trophy || 0; + this.boxPickups = data?.box_pickups || 0; + this.horn = data?.horn || 'DEFAULT'; + this.retro = new TurboKartRacersMap(data, 'retro'); + this.hypixelgp = new TurboKartRacersMap(data, 'hypixelgp'); + this.olympus = new TurboKartRacersMap(data, 'olympus'); + this.junglerush = new TurboKartRacersMap(data, 'junglerush'); + this.canyon = new TurboKartRacersMap(data, 'canyon'); + this.bananaHitsReceived = data?.banana_hits_received || 0; + this.bananaHitsSent = data?.banana_hits_sent || 0; + this.blueTorpedoHit = data?.blue_torpedo_hit || 0; + this.grandPrix = data?.grand_prix || 'false'; + this.grandPrixTokens = data?.grand_prix_tokens || 0; + } +} + +export default TurboKartRacers; diff --git a/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.test.ts b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.test.ts new file mode 100644 index 000000000..670bafc2a --- /dev/null +++ b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.test.ts @@ -0,0 +1,27 @@ +import TurboKartRacersMap from './TurboKartRacersMap.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { TurboKartRacersMaps } from '../../../Types/Player.js'; + +test('TurboKartRacersMap', () => { + const data = new TurboKartRacersMap({ stats: 'meow' }, 'canyon'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TurboKartRacersMap); + expectTypeOf(data).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.plays).toBeDefined(); + expect(data.plays).toBeGreaterThanOrEqual(0); + expectTypeOf(data.plays).toEqualTypeOf(); + expect(data.boxPickups).toBeDefined(); + expect(data.boxPickups).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boxPickups).toEqualTypeOf(); + expect(data.bronzeTrophies).toBeDefined(); + expect(data.bronzeTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bronzeTrophies).toEqualTypeOf(); + expect(data.silverTrophies).toBeDefined(); + expect(data.silverTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silverTrophies).toEqualTypeOf(); + expect(data.goldTrophies).toBeDefined(); + expect(data.goldTrophies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldTrophies).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.ts b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.ts new file mode 100644 index 000000000..b33f6cb4f --- /dev/null +++ b/src/Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.ts @@ -0,0 +1,20 @@ +import type { TurboKartRacersMaps } from '../../../Types/Player.js'; + +class TurboKartRacersMap { + map: TurboKartRacersMaps; + plays: number; + boxPickups: number; + bronzeTrophies: number; + silverTrophies: number; + goldTrophies: number; + constructor(data: Record, mapName: TurboKartRacersMaps) { + this.map = mapName; + this.plays = data?.[`${mapName}_plays`] || 0; + this.boxPickups = data?.[`box_pickups_${mapName}`] || 0; + this.bronzeTrophies = data?.[`bronze_trophy_${mapName}`] || 0; + this.silverTrophies = data?.[`silver_trophy_${mapName}`] || 0; + this.goldTrophies = data?.[`gold_trophy_${mapName}`] || 0; + } +} + +export default TurboKartRacersMap; diff --git a/src/Structures/MiniGames/UHC/UHC.test.ts b/src/Structures/MiniGames/UHC/UHC.test.ts new file mode 100644 index 000000000..e3e188390 --- /dev/null +++ b/src/Structures/MiniGames/UHC/UHC.test.ts @@ -0,0 +1,64 @@ +import UHC from './UHC.js'; +import UHCGamemode from './UHCGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UHCKits } from '../../../Types/Player.js'; + +test('UHC', () => { + const data = new UHC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(UHC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.score).toBeDefined(); + expect(data.score).toBeGreaterThanOrEqual(0); + expectTypeOf(data.score).toEqualTypeOf(); + expect(data.kit).toBeDefined(); + expectTypeOf(data.kit).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.team).toBeDefined(); + expect(data.team).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.team).toEqualTypeOf(); + expect(data.redVsBlue).toBeDefined(); + expect(data.redVsBlue).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.redVsBlue).toEqualTypeOf(); + expect(data.noDiamond).toBeDefined(); + expect(data.noDiamond).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.noDiamond).toEqualTypeOf(); + expect(data.brawl).toBeDefined(); + expect(data.brawl).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.brawl).toEqualTypeOf(); + expect(data.soloBrawl).toBeDefined(); + expect(data.soloBrawl).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.soloBrawl).toEqualTypeOf(); + expect(data.duoBrawl).toBeDefined(); + expect(data.duoBrawl).toBeInstanceOf(UHCGamemode); + expectTypeOf(data.duoBrawl).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.headsEaten).toBeDefined(); + expect(data.headsEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headsEaten).toEqualTypeOf(); + expect(data.ultimatesCrafted).toBeDefined(); + expect(data.ultimatesCrafted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ultimatesCrafted).toEqualTypeOf(); + expect(data.extraUltimatesCrafted).toBeDefined(); + expect(data.extraUltimatesCrafted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.extraUltimatesCrafted).toEqualTypeOf(); + expect(data.starLevel).toBeDefined(); + expect(data.starLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.starLevel).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/UHC/UHC.ts b/src/Structures/MiniGames/UHC/UHC.ts new file mode 100644 index 000000000..8d0edfce1 --- /dev/null +++ b/src/Structures/MiniGames/UHC/UHC.ts @@ -0,0 +1,96 @@ +import Divide from '../../../Utils/Divide.js'; +import UHCGamemode from './UHCGamemode.js'; +import type { UHCKits } from '../../../Types/Player.js'; + +function getStarLevel(kills: number, wins: number): number { + const sum = kills + wins * 10; + let starLevel = 1; + const sums = [0, 1, 6, 21, 46, 96, 171, 271, 521, 1021, 1321, 1621, 1921, 2221, 2521, Infinity]; + starLevel += sums.map((x) => x * 10 - sum).findIndex((x) => x > 0) - 1; + return starLevel; +} + +class UHC { + coins: number; + score: number; + kit: UHCKits | 'None'; + solo: UHCGamemode; + team: UHCGamemode; + redVsBlue: UHCGamemode; + noDiamond: UHCGamemode; + brawl: UHCGamemode; + soloBrawl: UHCGamemode; + duoBrawl: UHCGamemode; + wins: number; + kills: number; + deaths: number; + KDR: number; + headsEaten: number; + ultimatesCrafted: number; + extraUltimatesCrafted: number; + starLevel: number; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.score = data?.score || 0; + this.kit = data?.equippedKit || 'None'; + this.solo = new UHCGamemode(data, 'solo'); + this.team = new UHCGamemode(data); + this.redVsBlue = new UHCGamemode(data, 'red_vs_blue'); + this.noDiamond = new UHCGamemode(data, 'no_diamonds'); + this.brawl = new UHCGamemode(data, 'brawl'); + this.soloBrawl = new UHCGamemode(data, 'solo_brawl'); + this.duoBrawl = new UHCGamemode(data, 'duo_brawl'); + this.wins = + this.solo.wins + + this.team.wins + + this.redVsBlue.wins + + this.noDiamond.wins + + this.brawl.wins + + this.soloBrawl.wins + + this.duoBrawl.wins; + this.kills = + this.solo.kills + + this.team.kills + + this.redVsBlue.kills + + this.noDiamond.kills + + this.brawl.kills + + this.soloBrawl.kills + + this.duoBrawl.kills; + this.deaths = + this.solo.deaths + + this.team.deaths + + this.redVsBlue.deaths + + this.noDiamond.deaths + + this.brawl.deaths + + this.soloBrawl.deaths + + this.duoBrawl.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.headsEaten = + this.solo.headsEaten + + this.team.headsEaten + + this.redVsBlue.headsEaten + + this.noDiamond.headsEaten + + this.brawl.headsEaten + + this.soloBrawl.headsEaten + + this.duoBrawl.headsEaten; + this.ultimatesCrafted = + this.solo.ultimatesCrafted + + this.team.ultimatesCrafted + + this.redVsBlue.ultimatesCrafted + + this.noDiamond.ultimatesCrafted + + this.brawl.ultimatesCrafted + + this.soloBrawl.ultimatesCrafted + + this.duoBrawl.ultimatesCrafted; + this.extraUltimatesCrafted = + this.solo.extraUltimatesCrafted + + this.team.extraUltimatesCrafted + + this.redVsBlue.extraUltimatesCrafted + + this.noDiamond.extraUltimatesCrafted + + this.brawl.extraUltimatesCrafted + + this.soloBrawl.extraUltimatesCrafted + + this.duoBrawl.extraUltimatesCrafted; + this.starLevel = getStarLevel(this.kills, this.wins); + } +} + +export default UHC; diff --git a/src/Structures/MiniGames/UHC/UHCGamemode.test.ts b/src/Structures/MiniGames/UHC/UHCGamemode.test.ts new file mode 100644 index 000000000..d05726eb8 --- /dev/null +++ b/src/Structures/MiniGames/UHC/UHCGamemode.test.ts @@ -0,0 +1,30 @@ +import UHCGamemode from './UHCGamemode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('UHCGamemode', () => { + const data = new UHCGamemode({ stats: 'meow' }, 'brawl'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(UHCGamemode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.headsEaten).toBeDefined(); + expect(data.headsEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.headsEaten).toEqualTypeOf(); + expect(data.ultimatesCrafted).toBeDefined(); + expect(data.ultimatesCrafted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ultimatesCrafted).toEqualTypeOf(); + expect(data.extraUltimatesCrafted).toBeDefined(); + expect(data.extraUltimatesCrafted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.extraUltimatesCrafted).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/UHC/UHCGamemode.ts b/src/Structures/MiniGames/UHC/UHCGamemode.ts new file mode 100644 index 000000000..6c099655d --- /dev/null +++ b/src/Structures/MiniGames/UHC/UHCGamemode.ts @@ -0,0 +1,24 @@ +import Divide from '../../../Utils/Divide.js'; +import type { UHCModes } from '../../../Types/Player.js'; + +class UHCGamemode { + kills: number; + deaths: number; + KDR: number; + wins: number; + headsEaten: number; + ultimatesCrafted: number; + extraUltimatesCrafted: number; + constructor(data: Record, mode?: UHCModes) { + const modeName = mode ? `_${mode}` : ''; + this.kills = data?.[`kills${modeName}`] || 0; + this.deaths = data?.[`deaths${modeName}`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`wins${modeName}`] || 0; + this.headsEaten = data?.[`heads_eaten${modeName}`] || 0; + this.ultimatesCrafted = data?.[`ultimates_crafted${modeName}`] || 0; + this.extraUltimatesCrafted = data?.[`extra_ultimates_crafted${modeName}`] || 0; + } +} + +export default UHCGamemode; diff --git a/src/Structures/MiniGames/VampireZ/VampireZ.test.ts b/src/Structures/MiniGames/VampireZ/VampireZ.test.ts new file mode 100644 index 000000000..7403200c2 --- /dev/null +++ b/src/Structures/MiniGames/VampireZ/VampireZ.test.ts @@ -0,0 +1,39 @@ +import VampireZ from './VampireZ.js'; +import VampireZRole from './VampireZRole.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('VampireZ', () => { + const data = new VampireZ({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(VampireZ); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.goldBought).toBeDefined(); + expect(data.goldBought).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldBought).toEqualTypeOf(); + expect(data.blood).toBeDefined(); + expectTypeOf(data.blood).toEqualTypeOf(); + expect(data.zombieKills).toBeDefined(); + expect(data.zombieKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombieKills).toEqualTypeOf(); + expect(data.human).toBeDefined(); + expect(data.human).toBeInstanceOf(VampireZRole); + expectTypeOf(data.human).toEqualTypeOf(); + expect(data.vampire).toBeDefined(); + expect(data.vampire).toBeInstanceOf(VampireZRole); + expectTypeOf(data.vampire).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/VampireZ/VampireZ.ts b/src/Structures/MiniGames/VampireZ/VampireZ.ts new file mode 100644 index 000000000..8c250f655 --- /dev/null +++ b/src/Structures/MiniGames/VampireZ/VampireZ.ts @@ -0,0 +1,29 @@ +import Divide from '../../../Utils/Divide.js'; +import VampireZRole from './VampireZRole.js'; + +class VampireZ { + coins: number; + goldBought: number; + blood: boolean; + zombieKills: number; + human: VampireZRole; + vampire: VampireZRole; + kills: number; + deaths: number; + KDR: number; + wins: number; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.goldBought = data?.gold_bought || 0; + this.blood = data?.blood || false; + this.zombieKills = data?.zombie_kills || 0; + this.human = new VampireZRole(data, 'human'); + this.vampire = new VampireZRole(data, 'vampire'); + this.kills = this.human?.kills + this.vampire?.kills; + this.deaths = this.human?.deaths + this.vampire?.deaths; + this.KDR = Divide(this.kills, this.deaths); + this.wins = this.human?.wins + this.vampire?.wins; + } +} + +export default VampireZ; diff --git a/src/Structures/MiniGames/VampireZ/VampireZRole.test.ts b/src/Structures/MiniGames/VampireZ/VampireZRole.test.ts new file mode 100644 index 000000000..f4dfa60c8 --- /dev/null +++ b/src/Structures/MiniGames/VampireZ/VampireZRole.test.ts @@ -0,0 +1,24 @@ +import VampireZRole from './VampireZRole.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { VampireZRoles } from '../../../Types/Player.js'; + +test('VampireZRole', () => { + const data = new VampireZRole({ stats: 'meow' }, 'human'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(VampireZRole); + expectTypeOf(data).toEqualTypeOf(); + expect(data.role).toBeDefined(); + expectTypeOf(data.role).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/VampireZ/VampireZRole.ts b/src/Structures/MiniGames/VampireZ/VampireZRole.ts new file mode 100644 index 000000000..b468b3738 --- /dev/null +++ b/src/Structures/MiniGames/VampireZ/VampireZRole.ts @@ -0,0 +1,19 @@ +import Divide from '../../../Utils/Divide.js'; +import type { VampireZRoles } from '../../../Types/Player.js'; + +class VampireZRole { + role: VampireZRoles; + kills: number; + deaths: number; + KDR: number; + wins: number; + constructor(data: Record, role: VampireZRoles) { + this.role = role; + this.kills = data?.[`${role}_kills`] || 0; + this.deaths = data?.[`${role}_deaths`] || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.[`${role}_wins`] || 0; + } +} + +export default VampireZRole; diff --git a/src/Structures/MiniGames/Walls.test.ts b/src/Structures/MiniGames/Walls.test.ts new file mode 100644 index 000000000..75aea1d7c --- /dev/null +++ b/src/Structures/MiniGames/Walls.test.ts @@ -0,0 +1,33 @@ +import Walls from './Walls.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Walls', () => { + const data = new Walls({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Walls); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Walls.ts b/src/Structures/MiniGames/Walls.ts new file mode 100644 index 000000000..425f7000e --- /dev/null +++ b/src/Structures/MiniGames/Walls.ts @@ -0,0 +1,24 @@ +import Divide from '../../Utils/Divide.js'; + +class Walls { + coins: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + assists: number; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.assists = data?.assists || 0; + } +} + +export default Walls; diff --git a/src/Structures/MiniGames/Warlords/Warlords.test.ts b/src/Structures/MiniGames/Warlords/Warlords.test.ts new file mode 100644 index 000000000..30e255817 --- /dev/null +++ b/src/Structures/MiniGames/Warlords/Warlords.test.ts @@ -0,0 +1,88 @@ +import Warlords from './Warlords.js'; +import WarlordsClass from './WarlordsClass.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WarlordsClasses } from '../../../Types/Player.js'; + +test('Warlords', () => { + const data = new Warlords({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Warlords); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDR).toBeDefined(); + expect(data.KDR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDR).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.winStreak).toBeDefined(); + expect(data.winStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.winStreak).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.class).toBeDefined(); + expectTypeOf(data.class).toEqualTypeOf(); + expect(data.pyromancer).toBeDefined(); + expect(data.pyromancer).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.pyromancer).toEqualTypeOf(); + expect(data.mage).toBeDefined(); + expect(data.mage).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.mage).toEqualTypeOf(); + expect(data.thunderlord).toBeDefined(); + expect(data.thunderlord).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.thunderlord).toEqualTypeOf(); + expect(data.shaman).toBeDefined(); + expect(data.shaman).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.shaman).toEqualTypeOf(); + expect(data.earthwarden).toBeDefined(); + expect(data.earthwarden).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.earthwarden).toEqualTypeOf(); + expect(data.aquamancer).toBeDefined(); + expect(data.aquamancer).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.aquamancer).toEqualTypeOf(); + expect(data.paladin).toBeDefined(); + expect(data.paladin).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.paladin).toEqualTypeOf(); + expect(data.avenger).toBeDefined(); + expect(data.avenger).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.avenger).toEqualTypeOf(); + expect(data.warrior).toBeDefined(); + expect(data.warrior).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.warrior).toEqualTypeOf(); + expect(data.defender).toBeDefined(); + expect(data.defender).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.defender).toEqualTypeOf(); + expect(data.cryomancer).toBeDefined(); + expect(data.cryomancer).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.cryomancer).toEqualTypeOf(); + expect(data.crusader).toBeDefined(); + expect(data.crusader).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.crusader).toEqualTypeOf(); + expect(data.berserker).toBeDefined(); + expect(data.berserker).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.berserker).toEqualTypeOf(); + expect(data.protector).toBeDefined(); + expect(data.protector).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.protector).toEqualTypeOf(); + expect(data.revenant).toBeDefined(); + expect(data.revenant).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.revenant).toEqualTypeOf(); + expect(data.spiritguard).toBeDefined(); + expect(data.spiritguard).toBeInstanceOf(WarlordsClass); + expectTypeOf(data.spiritguard).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Warlords/Warlords.ts b/src/Structures/MiniGames/Warlords/Warlords.ts new file mode 100644 index 000000000..fee24672e --- /dev/null +++ b/src/Structures/MiniGames/Warlords/Warlords.ts @@ -0,0 +1,62 @@ +import Divide from '../../../Utils/Divide.js'; +import WarlordsClass from './WarlordsClass.js'; +import type { WarlordsClasses } from '../../../Types/Player.js'; + +class Warlords { + coins: number; + kills: number; + deaths: number; + KDR: number; + wins: number; + losses: number; + WLR: number; + winStreak: number; + assists: number; + class: WarlordsClasses | 'None'; + pyromancer: WarlordsClass; + mage: WarlordsClass; + thunderlord: WarlordsClass; + shaman: WarlordsClass; + earthwarden: WarlordsClass; + aquamancer: WarlordsClass; + paladin: WarlordsClass; + avenger: WarlordsClass; + warrior: WarlordsClass; + defender: WarlordsClass; + cryomancer: WarlordsClass; + crusader: WarlordsClass; + berserker: WarlordsClass; + protector: WarlordsClass; + revenant: WarlordsClass; + spiritguard: WarlordsClass; + constructor(data: Record) { + this.coins = data?.coins || data?.tokens || 0; + this.kills = data?.kills || 0; + this.deaths = data?.deaths || 0; + this.KDR = Divide(this.kills, this.deaths); + this.wins = data?.wins || 0; + this.losses = data?.losses || 0; + this.WLR = Divide(this.wins, this.losses); + this.winStreak = data?.win_streak || 0; + this.assists = data?.assists || 0; + this.class = data?.chosen_class || 'None'; + this.pyromancer = new WarlordsClass(data, 'pyromancer'); + this.mage = new WarlordsClass(data, 'mage'); + this.thunderlord = new WarlordsClass(data, 'thunderlord'); + this.shaman = new WarlordsClass(data, 'shaman'); + this.earthwarden = new WarlordsClass(data, 'earthwarden'); + this.aquamancer = new WarlordsClass(data, 'aquamancer'); + this.paladin = new WarlordsClass(data, 'paladin'); + this.avenger = new WarlordsClass(data, 'avenger'); + this.warrior = new WarlordsClass(data, 'warrior'); + this.defender = new WarlordsClass(data, 'defender'); + this.cryomancer = new WarlordsClass(data, 'cryomancer'); + this.crusader = new WarlordsClass(data, 'crusader'); + this.berserker = new WarlordsClass(data, 'berserker'); + this.protector = new WarlordsClass(data, 'protector'); + this.revenant = new WarlordsClass(data, 'revenant'); + this.spiritguard = new WarlordsClass(data, 'spiritguard'); + } +} + +export default Warlords; diff --git a/src/Structures/MiniGames/Warlords/WarlordsClass.test.ts b/src/Structures/MiniGames/Warlords/WarlordsClass.test.ts new file mode 100644 index 000000000..9cb117edc --- /dev/null +++ b/src/Structures/MiniGames/Warlords/WarlordsClass.test.ts @@ -0,0 +1,30 @@ +import WarlordsClass from './WarlordsClass.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('WarlordsClass', () => { + const data = new WarlordsClass({ stats: 'meow' }, 'aquamancer'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WarlordsClass); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLR).toBeDefined(); + expect(data.WLR).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLR).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.damage).toBeDefined(); + expect(data.damage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damage).toEqualTypeOf(); + expect(data.heal).toBeDefined(); + expect(data.heal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.heal).toEqualTypeOf(); + expect(data.damagePrevented).toBeDefined(); + expect(data.damagePrevented).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damagePrevented).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/Warlords/WarlordsClass.ts b/src/Structures/MiniGames/Warlords/WarlordsClass.ts new file mode 100644 index 000000000..dc2a052a2 --- /dev/null +++ b/src/Structures/MiniGames/Warlords/WarlordsClass.ts @@ -0,0 +1,23 @@ +import Divide from '../../../Utils/Divide.js'; +import type { WarlordsClasses } from '../../../Types/Player.js'; + +class WarlordsClass { + wins: number; + losses: number; + WLR: number; + gamesPlayed: number; + damage: number; + heal: number; + damagePrevented: number; + constructor(data: Record, className: WarlordsClasses) { + this.wins = data?.[`wins_${className}`] || 0; + this.losses = data?.[`losses_${className}`] || 0; + this.WLR = Divide(this.wins, this.losses); + this.gamesPlayed = data?.[`${className}_plays`] || 0; + this.damage = data?.[`damage_${className}`] || 0; + this.heal = data?.[`heal_${className}`] || 0; + this.damagePrevented = data?.[`damage_prevented_${className}`] || 0; + } +} + +export default WarlordsClass; diff --git a/src/Structures/MiniGames/WoolGames/CaptureTheWool.test.ts b/src/Structures/MiniGames/WoolGames/CaptureTheWool.test.ts new file mode 100644 index 000000000..d6f780921 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/CaptureTheWool.test.ts @@ -0,0 +1,39 @@ +import CaptureTheWool from './CaptureTheWool.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('CaptureTheWool', () => { + const data = new CaptureTheWool({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(CaptureTheWool); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDRatio).toBeDefined(); + expect(data.KDRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatio).toEqualTypeOf(); + expect(data.killsWithWool).toBeDefined(); + expect(data.killsWithWool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsWithWool).toEqualTypeOf(); + expect(data.deathsWithWool).toBeDefined(); + expect(data.deathsWithWool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsWithWool).toEqualTypeOf(); + expect(data.KDRatioWithWool).toBeDefined(); + expect(data.KDRatioWithWool).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatioWithWool).toEqualTypeOf(); + expect(data.woolCaptured).toBeDefined(); + expect(data.woolCaptured).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolCaptured).toEqualTypeOf(); + expect(data.woolStolen).toBeDefined(); + expect(data.woolStolen).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolStolen).toEqualTypeOf(); + expect(data.woolCaptureStolenRatio).toBeDefined(); + expect(data.woolCaptureStolenRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolCaptureStolenRatio).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/WoolGames/CaptureTheWool.ts b/src/Structures/MiniGames/WoolGames/CaptureTheWool.ts new file mode 100644 index 000000000..f640cccc0 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/CaptureTheWool.ts @@ -0,0 +1,28 @@ +import Divide from '../../../Utils/Divide.js'; + +class CaptureTheWool { + kills: number; + assists: number; + deaths: number; + KDRatio: number; + killsWithWool: number; + deathsWithWool: number; + KDRatioWithWool: number; + woolCaptured: number; + woolStolen: number; + woolCaptureStolenRatio: number; + constructor(data: Record) { + this.kills = data?.stats?.kills || 0; + this.assists = data?.stats?.assists || 0; + this.deaths = data?.stats?.deaths || 0; + this.KDRatio = Divide(this.kills, this.deaths); + this.killsWithWool = data?.stats?.kills_with_wool || 0; + this.deathsWithWool = data?.stats?.deaths_with_wool || 0; + this.KDRatioWithWool = Divide(this.killsWithWool, this.deathsWithWool); + this.woolCaptured = data?.stats?.wools_captured || 0; + this.woolStolen = data?.stats?.wools_stolen || 0; + this.woolCaptureStolenRatio = Divide(this.woolCaptured, this.woolStolen); + } +} + +export default CaptureTheWool; diff --git a/src/Structures/MiniGames/WoolGames/SheepWars.test.ts b/src/Structures/MiniGames/WoolGames/SheepWars.test.ts new file mode 100644 index 000000000..42f9b1253 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/SheepWars.test.ts @@ -0,0 +1,57 @@ +import SheepWars from './SheepWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SheepWars', () => { + const data = new SheepWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SheepWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.killsVoid).toBeDefined(); + expect(data.killsVoid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsVoid).toEqualTypeOf(); + expect(data.killsBow).toBeDefined(); + expect(data.killsBow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsBow).toEqualTypeOf(); + expect(data.killsExplosive).toBeDefined(); + expect(data.killsExplosive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.killsExplosive).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.deathsVoid).toBeDefined(); + expect(data.deathsVoid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsVoid).toEqualTypeOf(); + expect(data.deathsMelee).toBeDefined(); + expect(data.deathsMelee).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsMelee).toEqualTypeOf(); + expect(data.deathsExplosive).toBeDefined(); + expect(data.deathsExplosive).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathsExplosive).toEqualTypeOf(); + expect(data.KDRatio).toBeDefined(); + expect(data.KDRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatio).toEqualTypeOf(); + expect(data.losses).toBeDefined(); + expect(data.losses).toBeGreaterThanOrEqual(0); + expectTypeOf(data.losses).toEqualTypeOf(); + expect(data.WLRatio).toBeDefined(); + expect(data.WLRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.WLRatio).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); + expect(data.sheepThrown).toBeDefined(); + expect(data.sheepThrown).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sheepThrown).toEqualTypeOf(); + expect(data.magicWoolHit).toBeDefined(); + expect(data.magicWoolHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magicWoolHit).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/WoolGames/SheepWars.ts b/src/Structures/MiniGames/WoolGames/SheepWars.ts new file mode 100644 index 000000000..1784d246d --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/SheepWars.ts @@ -0,0 +1,40 @@ +import Divide from '../../../Utils/Divide.js'; + +class SheepWars { + wins: number; + kills: number; + killsVoid: number; + killsBow: number; + killsExplosive: number; + deaths: number; + deathsVoid: number; + deathsMelee: number; + deathsExplosive: number; + KDRatio: number; + losses: number; + WLRatio: number; + gamesPlayed: number; + damageDealt: number; + sheepThrown: number; + magicWoolHit: number; + constructor(data: Record) { + this.wins = data?.stats?.wins || 0; + this.kills = data?.stats?.kills || 0; + this.killsVoid = data?.stats?.kills_void || 0; + this.killsBow = data?.stats?.kills_bow || 0; + this.killsExplosive = data?.stats?.kills_explosive || 0; + this.deaths = data?.stats?.deaths || 0; + this.deathsVoid = data?.stats?.deaths_void || 0; + this.deathsMelee = data?.stats?.deaths_melee || 0; + this.deathsExplosive = data?.stats?.deaths_explosive || 0; + this.KDRatio = Divide(this.wins, this.deaths); + this.losses = data?.stats?.losses || 0; + this.WLRatio = Divide(this.wins, this.losses); + this.gamesPlayed = data?.stats?.games_played || 0; + this.damageDealt = data?.stats?.damage_dealt || 0; + this.sheepThrown = data?.stats?.sheep_thrown || 0; + this.magicWoolHit = data?.stats?.magic_wool_hit || 0; + } +} + +export default SheepWars; diff --git a/src/Structures/MiniGames/WoolGames/WoolGames.test.ts b/src/Structures/MiniGames/WoolGames/WoolGames.test.ts new file mode 100644 index 000000000..3a292d045 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolGames.test.ts @@ -0,0 +1,44 @@ +import CaptureTheWool from './CaptureTheWool.js'; +import SheepWars from './SheepWars.js'; +import WoolGames from './WoolGames.js'; +import WoolWars from './WoolWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WoolGamesPrivateGameConfig } from '../../../Types/Player.js'; + +test('WoolGames', () => { + const data = new WoolGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WoolGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.layers).toBeDefined(); + expect(data.layers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.layers).toEqualTypeOf(); + expect(data.xp).toBeDefined(); + expect(data.xp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xp).toEqualTypeOf(); + expect(data.exactLevel).toBeDefined(); + expect(data.exactLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.exactLevel).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.coins).toBeDefined(); + expect(data.coins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coins).toEqualTypeOf(); + expect(data.ownedCosmetics).toBeDefined(); + expectTypeOf(data.ownedCosmetics).toEqualTypeOf(); + expect(data.privateGamesConfig).toBeDefined(); + expectTypeOf(data.privateGamesConfig).toEqualTypeOf(); + expect(data.playtime).toBeDefined(); + expect(data.playtime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playtime).toEqualTypeOf(); + expect(data.woolWars).toBeDefined(); + expect(data.woolWars).toBeInstanceOf(WoolWars); + expectTypeOf(data.woolWars).toEqualTypeOf(); + expect(data.captureTheWool).toBeDefined(); + expect(data.captureTheWool).toBeInstanceOf(CaptureTheWool); + expectTypeOf(data.captureTheWool).toEqualTypeOf(); + expect(data.sheepWars).toBeDefined(); + expect(data.sheepWars).toBeInstanceOf(SheepWars); + expectTypeOf(data.sheepWars).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/WoolGames/WoolGames.ts b/src/Structures/MiniGames/WoolGames/WoolGames.ts new file mode 100644 index 000000000..af73f9f12 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolGames.ts @@ -0,0 +1,44 @@ +import CaptureTheWool from './CaptureTheWool.js'; +import SheepWars from './SheepWars.js'; +import WoolWars from './WoolWars.js'; +import type { WoolGamesPrivateGameConfig } from '../../../Types/Player.js'; + +class WoolGames { + layers: number; + xp: number; + exactLevel: number; + level: number; + coins: number; + ownedCosmetics: string[]; + privateGamesConfig: WoolGamesPrivateGameConfig; + playtime: number; + woolWars: WoolWars; + captureTheWool: CaptureTheWool; + sheepWars: SheepWars; + constructor(data: Record) { + this.layers = data?.progression?.available_layers || 0; + this.xp = data?.progression?.experience || 0; + this.exactLevel = this.convertXPToLevel(this.xp); + this.level = Math?.floor(this.exactLevel); + this.coins = data?.coins || data?.tokens || 0; + this.ownedCosmetics = data?.packages || []; + this.privateGamesConfig = data?.privategames || {}; + this.playtime = data?.playtime || 0; + this.woolWars = new WoolWars(data?.wool_wars); + this.captureTheWool = new CaptureTheWool(data?.capture_the_wool); + this.sheepWars = new SheepWars(data?.sheep_wars); + } + + convertXPToLevel(exp: number): number { + const minimalExp = [0, 1e3, 3e3, 6e3, 1e4, 15e3]; + const baseLevel = minimalExp?.length; + const baseExp: number = minimalExp[minimalExp?.length - 1] || 0; + const expToLevel100 = 49e4; + if (exp < baseExp) return minimalExp?.findIndex((x) => exp < x); + const theoreticalLevel = (exp - baseExp) / 5e3 + baseLevel; + if (theoreticalLevel > 100) return 100 + this.convertXPToLevel(exp - expToLevel100); + return theoreticalLevel; + } +} + +export default WoolGames; diff --git a/src/Structures/MiniGames/WoolGames/WoolWars.test.ts b/src/Structures/MiniGames/WoolGames/WoolWars.test.ts new file mode 100644 index 000000000..6fc29b07c --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolWars.test.ts @@ -0,0 +1,61 @@ +import WoolWars from './WoolWars.js'; +import WoolWarsClass from './WoolWarsClass.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WoolWarsClassNames } from '../../../Types/Player.js'; + +test('WoolWars', () => { + const data = new WoolWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WoolWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selectedClass).toBeDefined(); + expectTypeOf(data.selectedClass).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDRatio).toBeDefined(); + expect(data.KDRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatio).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.woolsPlaced).toBeDefined(); + expect(data.woolsPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolsPlaced).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.placeBreakRatio).toBeDefined(); + expect(data.placeBreakRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.placeBreakRatio).toEqualTypeOf(); + expect(data.powerUps).toBeDefined(); + expect(data.powerUps).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powerUps).toEqualTypeOf(); + expect(data.assault).toBeDefined(); + expect(data.assault).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.assault).toEqualTypeOf(); + expect(data.tank).toBeDefined(); + expect(data.tank).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.tank).toEqualTypeOf(); + expect(data.golem).toBeDefined(); + expect(data.golem).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.golem).toEqualTypeOf(); + expect(data.swordsman).toBeDefined(); + expect(data.swordsman).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.swordsman).toEqualTypeOf(); + expect(data.engineer).toBeDefined(); + expect(data.engineer).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.engineer).toEqualTypeOf(); + expect(data.archer).toBeDefined(); + expect(data.archer).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data.archer).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/WoolGames/WoolWars.ts b/src/Structures/MiniGames/WoolGames/WoolWars.ts new file mode 100644 index 000000000..c2a71a4eb --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolWars.ts @@ -0,0 +1,44 @@ +import Divide from '../../../Utils/Divide.js'; +import WoolWarsClass from './WoolWarsClass.js'; +import type { WoolWarsClassNames } from '../../../Types/Player.js'; + +class WoolWars { + selectedClass: WoolWarsClassNames | 'None'; + wins: number; + kills: number; + assists: number; + deaths: number; + KDRatio: number; + gamesPlayed: number; + woolsPlaced: number; + blocksBroken: number; + placeBreakRatio: number; + powerUps: number; + assault: WoolWarsClass; + tank: WoolWarsClass; + golem: WoolWarsClass; + swordsman: WoolWarsClass; + engineer: WoolWarsClass; + archer: WoolWarsClass; + constructor(data: Record) { + this.selectedClass = data?.selected_class || 'None'; + this.wins = data?.stats?.wins || 0; + this.kills = data?.stats?.kills || 0; + this.assists = data?.stats?.assists || 0; + this.deaths = data?.stats?.deaths || 0; + this.KDRatio = Divide(this.kills, this.deaths); + this.gamesPlayed = data?.stats?.games_played || 0; + this.woolsPlaced = data?.stats?.wool_placed || 0; + this.blocksBroken = data?.stats?.blocks_broken || 0; + this.placeBreakRatio = Divide(this.woolsPlaced, this.blocksBroken); + this.powerUps = data?.powerups_gotten || 0; + this.assault = new WoolWarsClass(data?.stats?.classes, 'ASSAULT'); + this.tank = new WoolWarsClass(data?.stats?.classes, 'TANK'); + this.golem = new WoolWarsClass(data?.stats?.classes, 'GOLEM'); + this.swordsman = new WoolWarsClass(data?.stats?.classes, 'SWORDSMAN'); + this.engineer = new WoolWarsClass(data?.stats?.classes, 'ENGINEER'); + this.archer = new WoolWarsClass(data?.stats?.classes, 'ARCHER'); + } +} + +export default WoolWars; diff --git a/src/Structures/MiniGames/WoolGames/WoolWarsClass.test.ts b/src/Structures/MiniGames/WoolGames/WoolWarsClass.test.ts new file mode 100644 index 000000000..dcc0a6b6b --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolWarsClass.test.ts @@ -0,0 +1,39 @@ +import WoolWarsClass from './WoolWarsClass.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('WoolWarsClass', () => { + const data = new WoolWarsClass({ stats: 'meow' }, 'ARCHER'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WoolWarsClass); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wins).toBeDefined(); + expect(data.wins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wins).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.assists).toBeDefined(); + expect(data.assists).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assists).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.KDRatio).toBeDefined(); + expect(data.KDRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.KDRatio).toEqualTypeOf(); + expect(data.gamesPlayed).toBeDefined(); + expect(data.gamesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamesPlayed).toEqualTypeOf(); + expect(data.woolsPlaced).toBeDefined(); + expect(data.woolsPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolsPlaced).toEqualTypeOf(); + expect(data.blocksBroken).toBeDefined(); + expect(data.blocksBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blocksBroken).toEqualTypeOf(); + expect(data.placeBreakRatio).toBeDefined(); + expect(data.placeBreakRatio).toBeGreaterThanOrEqual(0); + expectTypeOf(data.placeBreakRatio).toEqualTypeOf(); + expect(data.powerUps).toBeDefined(); + expect(data.powerUps).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powerUps).toEqualTypeOf(); +}); diff --git a/src/Structures/MiniGames/WoolGames/WoolWarsClass.ts b/src/Structures/MiniGames/WoolGames/WoolWarsClass.ts new file mode 100644 index 000000000..5742fb213 --- /dev/null +++ b/src/Structures/MiniGames/WoolGames/WoolWarsClass.ts @@ -0,0 +1,30 @@ +import Divide from '../../../Utils/Divide.js'; +import type { WoolWarsClassNames } from '../../../Types/Player.js'; + +class WoolWarsClass { + wins: number; + kills: number; + assists: number; + deaths: number; + KDRatio: number; + gamesPlayed: number; + woolsPlaced: number; + blocksBroken: number; + placeBreakRatio: number; + powerUps: number; + constructor(data: Record, classInput: WoolWarsClassNames) { + const className = classInput.toLowerCase(); + this.wins = data?.[className]?.wins || 0; + this.kills = data?.[className]?.kills || 0; + this.assists = data?.[className]?.assists || 0; + this.deaths = data?.[className]?.deaths || 0; + this.KDRatio = Divide(this.kills, this.deaths); + this.gamesPlayed = data?.[className]?.games_played || 0; + this.woolsPlaced = data?.[className]?.wool_placed || 0; + this.blocksBroken = data?.[className]?.blocks_broken || 0; + this.placeBreakRatio = Divide(this.woolsPlaced, this.blocksBroken); + this.powerUps = data?.[className]?.powerups_gotten || 0; + } +} + +export default WoolWarsClass; diff --git a/src/Structures/Player/Player.test.ts b/src/Structures/Player/Player.test.ts new file mode 100644 index 000000000..701626a90 --- /dev/null +++ b/src/Structures/Player/Player.test.ts @@ -0,0 +1,91 @@ +import Guild from '../Guild/Guild.js'; +import House from '../House.js'; +import Player from './Player.js'; +import PlayerAchievements from './PlayerAchievements/PlayerAchievements.js'; +import PlayerAdventRewards from './PlayerAdventRewards/PlayerAdventRewards.js'; +import PlayerCosmetics from './PlayerCosmetics/PlayerCosmetics.js'; +import PlayerGifting from './PlayerGifting.js'; +import PlayerHousing from './PlayerHousing/PlayerHousing.js'; +import PlayerParkour from './PlayerParkour.js'; +import PlayerQuests from './PlayerQuests/PlayerQuests.js'; +import PlayerRankPurchase from './PlayerRankPurchase.js'; +import PlayerRewards from './PlayerRewards/PlayerRewards.js'; +import PlayerScorpiusBribe from './PlayerScorpiusBribe.js'; +import PlayerSocialMedia from './PlayerSocialMedia.js'; +import PlayerStats from './PlayerStats.js'; +import RecentGame from '../RecentGame.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ChatChannel, Language, LevelProgress, PlayerRank } from '../../Types/Player.js'; + +test('Player', () => { + const data = new Player({ stats: 'meow' }, {}); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Player); + expectTypeOf(data).toEqualTypeOf(); + expect(data.nickname).toBeDefined(); + expectTypeOf(data.nickname).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.rank).toBeDefined(); + expectTypeOf(data.rank).toEqualTypeOf(); + expect(data.firstLoginAt).toBeDefined(); + expectTypeOf(data.firstLoginAt).toEqualTypeOf(); + expect(data.lastLoginAt).toBeDefined(); + expectTypeOf(data.lastLoginAt).toEqualTypeOf(); + expect(data.lastLogoutAt).toBeDefined(); + expectTypeOf(data.lastLogoutAt).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expect(data.achievements).toBeInstanceOf(PlayerAchievements); + expectTypeOf(data.achievements).toEqualTypeOf(); + expect(data.karma).toBeDefined(); + expect(data.karma).toBeGreaterThanOrEqual(0); + expectTypeOf(data.karma).toEqualTypeOf(); + expect(data.stats).toBeDefined(); + expect(data.stats).toBeInstanceOf(PlayerStats); + expectTypeOf(data.stats).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.claimedCenturyCakeAt).toBeDefined(); + expectTypeOf(data.claimedCenturyCakeAt).toEqualTypeOf(); + expect(data.language).toBeDefined(); + expectTypeOf(data.language).toEqualTypeOf(); + expect(data.cosmetics).toBeDefined(); + expect(data.cosmetics).toBeInstanceOf(PlayerCosmetics); + expectTypeOf(data.cosmetics).toEqualTypeOf(); + expect(data.rankPurchase).toBeDefined(); + expect(data.rankPurchase).toBeInstanceOf(PlayerRankPurchase); + expectTypeOf(data.rankPurchase).toEqualTypeOf(); + expect(data.challenges).toBeDefined(); + expectTypeOf(data.challenges).toEqualTypeOf>>(); + expect(data.quests).toBeDefined(); + expect(data.quests).toBeInstanceOf(PlayerQuests); + expectTypeOf(data.quests).toEqualTypeOf(); + expect(data.rewards).toBeDefined(); + expect(data.rewards).toBeInstanceOf(PlayerRewards); + expectTypeOf(data.rewards).toEqualTypeOf(); + expect(data.parkour).toBeDefined(); + expectTypeOf(data.parkour).toEqualTypeOf(); + expect(data.channel).toBeDefined(); + expectTypeOf(data.channel).toEqualTypeOf(); + expect(data.skyBlockFreeCookieAt).toBeDefined(); + expectTypeOf(data.skyBlockFreeCookieAt).toEqualTypeOf(); + expect(data.housing).toBeDefined(); + expect(data.housing).toBeInstanceOf(PlayerHousing); + expectTypeOf(data.housing).toEqualTypeOf(); + expect(data.adventRewards).toBeDefined(); + expectTypeOf(data.adventRewards).toEqualTypeOf(); + expect(data.gifting).toBeDefined(); + expect(data.gifting).toBeInstanceOf(PlayerGifting); + expectTypeOf(data.gifting).toEqualTypeOf(); + expect(data.socialMedia).toBeDefined(); + expect(data.socialMedia).toBeInstanceOf(PlayerSocialMedia); + expectTypeOf(data.socialMedia).toEqualTypeOf(); + expect(data.scorpiusBribes).toBeDefined(); + expectTypeOf(data.scorpiusBribes).toEqualTypeOf(); + expect(data.guild).toBeDefined(); + expectTypeOf(data.guild).toEqualTypeOf(); + expect(data.houses).toBeDefined(); + expectTypeOf(data.houses).toEqualTypeOf(); + expect(data.recentGames).toBeDefined(); + expectTypeOf(data.recentGames).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/Player.ts b/src/Structures/Player/Player.ts new file mode 100644 index 000000000..86088a759 --- /dev/null +++ b/src/Structures/Player/Player.ts @@ -0,0 +1,181 @@ +import Guild from '../Guild/Guild.js'; +import House from '../House.js'; +import PlayerAchievements from './PlayerAchievements/PlayerAchievements.js'; +import PlayerAdventRewards from './PlayerAdventRewards/PlayerAdventRewards.js'; +import PlayerCosmetics from './PlayerCosmetics/PlayerCosmetics.js'; +import PlayerGifting from './PlayerGifting.js'; +import PlayerHousing from './PlayerHousing/PlayerHousing.js'; +import PlayerParkour from './PlayerParkour.js'; +import PlayerQuests from './PlayerQuests/PlayerQuests.js'; +import PlayerRankPurchase from './PlayerRankPurchase.js'; +import PlayerRewards from './PlayerRewards/PlayerRewards.js'; +import PlayerScorpiusBribe from './PlayerScorpiusBribe.js'; +import PlayerSocialMedia from './PlayerSocialMedia.js'; +import PlayerStats from './PlayerStats.js'; +import RecentGame from '../RecentGame.js'; +import type RequestData from '../../Private/RequestData.js'; +import type { ChatChannel, Language, LevelProgress, PlayerRank } from '../../Types/Player.js'; + +class Player { + nickname: string; + uuid: string; + rank: PlayerRank; + firstLoginAt: Date | null; + lastLoginAt: Date | null; + lastLogoutAt: Date | null; + achievements: PlayerAchievements; + karma: number; + stats: PlayerStats; + level: LevelProgress; + claimedCenturyCakeAt: Date | null; + language: Language; + cosmetics: PlayerCosmetics; + rankPurchase: PlayerRankPurchase; + challenges: Record>; + quests: PlayerQuests; + rewards: PlayerRewards; + parkour: PlayerParkour[]; + channel: ChatChannel; + skyBlockFreeCookieAt: Date | null; + housing: PlayerHousing; + adventRewards: PlayerAdventRewards[]; + gifting: PlayerGifting; + socialMedia: PlayerSocialMedia; + scorpiusBribes: PlayerScorpiusBribe[]; + + guild: Guild | null; + houses: House[] | null; + recentGames: RecentGame[] | null; + constructor( + data: Record, + extra: { guild?: Guild | null; houses?: House[] | null; recentGames?: RecentGame[] | null } + ) { + this.nickname = data?.displayname || 'UNKNOWN'; + this.uuid = data?.uuid || 'UNKNOWN'; + this.rank = this.getRank(data); + this.firstLoginAt = data?.firstLogin ? new Date(data?.firstLogin) : null; + this.lastLoginAt = data?.lastLogin ? new Date(data?.lastLogin) : null; + this.lastLogoutAt = data?.lastLogout ? new Date(data?.lastLogout) : null; + this.achievements = new PlayerAchievements(data || {}); + this.karma = data?.karma || 0; + this.stats = new PlayerStats(data?.stats || {}); + this.level = this.getPlayerLevelProgress(data?.networkExp || 0); + this.claimedCenturyCakeAt = data?.claimed_century_cake ? new Date(data?.claimed_century_cake) : null; + this.language = data?.userLanguage || 'ENGLISH'; + this.cosmetics = new PlayerCosmetics(data || {}); + this.rankPurchase = new PlayerRankPurchase(data || {}); + this.challenges = data?.challenges || {}; + this.quests = new PlayerQuests(data?.quests || {}, data?.questSettings?.autoActivate || false); + this.rewards = new PlayerRewards(data || {}); + this.parkour = Object.keys(data?.parkourCompletions || {}).map( + (location) => new PlayerParkour(data?.parkourCompletions || {}, data?.parkourCheckpointBests || {}, location) + ); + this.channel = data?.channel || 'ALL'; + this.skyBlockFreeCookieAt = data?.skyblock_free_cookie ? new Date(data?.skyblock_free_cookie) : null; + this.housing = new PlayerHousing(data?.housingMeta || {}); + this.adventRewards = Object.keys(data) + .filter((key) => key.startsWith('adventRewards')) + .map( + (adventReward) => + new PlayerAdventRewards(data[adventReward], adventReward.split('adventRewards')[1] || 'UNKNOWN') + ); + this.gifting = new PlayerGifting(data?.giftingMeta || {}); + this.socialMedia = new PlayerSocialMedia(data?.socialMedia?.links || {}); + this.scorpiusBribes = + Object.keys(data) + .filter((key) => key.startsWith('scorpius_bribe_')) + .map((bribe) => new PlayerScorpiusBribe(data[bribe], bribe.split('scorpius_bribe_')[1] || 'UNKNOWN')) || []; + + this.guild = extra.guild || null; + this.houses = extra.houses || null; + this.recentGames = extra.recentGames || null; + } + + private getRank(player: Record): PlayerRank { + if (player.prefix) { + switch (player.prefix.replace(/§[0-9|a-z]|\[|\]/g, '')) { + case 'EVENTS': + return 'Events'; + case 'MOJANG': + return 'Mojang'; + case 'PIG+++': + return 'PIG+++'; + case 'INNIT': + return 'Innit'; + default: + return null; + } + } else if (player.rank) { + switch (player.rank) { + case 'STAFF': + return 'Staff'; + case 'YOUTUBER': + return 'YouTube'; + default: + return null; + } + } else { + switch (player.newPackageRank) { + case 'MVP_PLUS': + return player.monthlyPackageRank !== 'SUPERSTAR' ? 'MVP+' : 'MVP++'; + case 'MVP': + return 'MVP'; + case 'VIP_PLUS': + return 'VIP+'; + case 'VIP': + return 'VIP'; + default: + return null; + } + } + } + + private getPlayerLevel(exp: number): number { + const base = 10000; + const growth = 2500; + const reversePqPrefix = -(base - 0.5 * growth) / growth; + const reverseConst = reversePqPrefix * reversePqPrefix; + const growthDivides2 = 2 / growth; + const num = 1 + reversePqPrefix + Math.sqrt(reverseConst + growthDivides2 * exp); + const level = Math.round(num * 100) / 100; + return level; + } + + private xpToNextLevel(xp: number): number { + const lvl = this.getPlayerLevel(xp); + const xpToNext = 2500 * Math.floor(lvl) + 5000; + if (xp < 10000) return 10000; + return xpToNext; + } + + private levelToXP(xp: number): number { + let level = Number(Math.floor(this.getPlayerLevel(xp))); + level = level - 1; + return 1250 * level ** 2 + 8750 * level; + } + + private getPlayerLevelProgress(totalXp: number): LevelProgress { + const xpFromLevel = this.levelToXP(totalXp); + let currentXP = totalXp - xpFromLevel; + const xpToNext = this.xpToNextLevel(totalXp); + const remainingXP = xpToNext - currentXP + 2500; + currentXP = currentXP - 2500; + const percent = Math.round((currentXP / xpToNext) * 100 * 100) / 100; + const percentRemaining = Math.round((100 - percent) * 100) / 100; + return { + level: this.getPlayerLevel(totalXp), + totalXp, + xpToNext, + remainingXP, + currentXP, + percent, + percentRemaining + }; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Player; diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievements.test.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievements.test.ts new file mode 100644 index 000000000..fc3d2ff2b --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievements.test.ts @@ -0,0 +1,29 @@ +import PlayerAchievements from './PlayerAchievements.js'; +import PlayerAchievementsRewards from './PlayerAchievementsRewards.js'; +import PlayerAchievementsTotem from './PlayerAchievementsTotem.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerAchievementsOneTimeSort } from '../../../Types/Player.js'; + +test('PlayerAchievements', () => { + const data = new PlayerAchievements({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerAchievements); + expectTypeOf(data).toEqualTypeOf(); + expect(data.points).toBeDefined(); + expect(data.points).toBeGreaterThanOrEqual(0); + expectTypeOf(data.points).toEqualTypeOf(); + expect(data.rewards).toBeDefined(); + expect(data.rewards).toBeInstanceOf(PlayerAchievementsRewards); + expectTypeOf(data.rewards).toEqualTypeOf(); + expect(data.tracking).toBeDefined(); + expectTypeOf(data.tracking).toEqualTypeOf(); + expect(data.achievements).toBeDefined(); + expectTypeOf(data.achievements).toEqualTypeOf>(); + expect(data.oneTime).toBeDefined(); + expectTypeOf(data.oneTime).toEqualTypeOf(); + expect(data.oneTimeAchievementMenuSort).toBeDefined(); + expectTypeOf(data.oneTimeAchievementMenuSort).toEqualTypeOf(); + expect(data.totem).toBeDefined(); + expect(data.totem).toBeInstanceOf(PlayerAchievementsTotem); + expectTypeOf(data.totem).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievements.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievements.ts new file mode 100644 index 000000000..19acef290 --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievements.ts @@ -0,0 +1,24 @@ +import PlayerAchievementsRewards from './PlayerAchievementsRewards.js'; +import PlayerAchievementsTotem from './PlayerAchievementsTotem.js'; +import type { PlayerAchievementsOneTimeSort } from '../../../Types/Player.js'; + +class PlayerAchievements { + points: number; + rewards: PlayerAchievementsRewards; + tracking: string[]; + achievements: Record; + oneTime: string[]; + oneTimeAchievementMenuSort: PlayerAchievementsOneTimeSort; + totem: PlayerAchievementsTotem; + constructor(data: Record) { + this.points = data?.achievementPoints || 0; + this.rewards = new PlayerAchievementsRewards(data?.achievementRewardsNew || {}); + this.tracking = data?.achievementTracking || []; + this.achievements = data?.achievements || {}; + this.oneTime = data?.achievementsOneTime || []; + this.oneTimeAchievementMenuSort = data?.onetime_achievement_menu_sort || 'a_to_z'; + this.totem = new PlayerAchievementsTotem(data?.achievementTotem || {}); + } +} + +export default PlayerAchievements; diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.test.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.test.ts new file mode 100644 index 000000000..902e500a0 --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.test.ts @@ -0,0 +1,9 @@ +import PlayerAchievementsRewards from './PlayerAchievementsRewards.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerAchievementsRewards', () => { + const data = new PlayerAchievementsRewards({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerAchievementsRewards); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.ts new file mode 100644 index 000000000..f0b7e366f --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievementsRewards.ts @@ -0,0 +1,19 @@ +class PlayerAchievementsRewards { + [key: string]: number; + constructor(data: Record) { + Object.keys(data) + .filter((key) => key.startsWith('for_points_')) + .map((key) => ({ [key.replace('for_points_', '')]: data[key] })) + .sort((a, b) => { + const keyA = Object.keys(a)?.[0] || ''; + const keyB = Object.keys(b)?.[0] || ''; + return parseInt(keyA) - parseInt(keyB); + }) + .forEach((item) => { + const key: string = Object.keys(item)?.[0] || 'UNKNOWN'; + this[key] = item[key]; + }); + } +} + +export default PlayerAchievementsRewards; diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.test.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.test.ts new file mode 100644 index 000000000..be7f72a79 --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.test.ts @@ -0,0 +1,23 @@ +import PlayerAchievementsTotem from './PlayerAchievementsTotem.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerAchievementsTotemColors, PlayerAchievementsTotemParts } from '../../../Types/Player.js'; + +test('PlayerAchievementsTotem', () => { + const data = new PlayerAchievementsTotem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerAchievementsTotem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.canCustomize).toBeDefined(); + expectTypeOf(data.canCustomize).toEqualTypeOf(); + expect(data.allowedMaxHeight).toBeDefined(); + expect(data.allowedMaxHeight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.allowedMaxHeight).toEqualTypeOf(); + expect(data.unlockedParts).toBeDefined(); + expectTypeOf(data.unlockedParts).toEqualTypeOf(); + expect(data.selectedParts).toBeDefined(); + expectTypeOf(data.selectedParts).toEqualTypeOf>(); + expect(data.unlockedColors).toBeDefined(); + expectTypeOf(data.unlockedColors).toEqualTypeOf(); + expect(data.selectedColors).toBeDefined(); + expectTypeOf(data.selectedColors).toEqualTypeOf>(); +}); diff --git a/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.ts b/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.ts new file mode 100644 index 000000000..6315ab90e --- /dev/null +++ b/src/Structures/Player/PlayerAchievements/PlayerAchievementsTotem.ts @@ -0,0 +1,20 @@ +import type { PlayerAchievementsTotemColors, PlayerAchievementsTotemParts } from '../../../Types/Player.js'; + +class PlayerAchievementsTotem { + canCustomize: boolean; + allowedMaxHeight: number; + unlockedParts: PlayerAchievementsTotemParts[]; + selectedParts: Record; + unlockedColors: PlayerAchievementsTotemColors[]; + selectedColors: Record; + constructor(data: Record) { + this.canCustomize = data?.canCustomize || false; + this.allowedMaxHeight = data?.allowed_max_height || 0; + this.unlockedParts = data?.unlockedParts || []; + this.selectedParts = data?.selectedParts || {}; + this.unlockedColors = data?.unlockedColors || []; + this.selectedColors = data?.selectedColors || {}; + } +} + +export default PlayerAchievementsTotem; diff --git a/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.test.ts b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.test.ts new file mode 100644 index 000000000..72d37f05e --- /dev/null +++ b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.test.ts @@ -0,0 +1,88 @@ +import PlayerAdventRewards from './PlayerAdventRewards.js'; +import PlayerAdventRewardsDay from './PlayerAdventRewardsDay.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerAdventRewards', () => { + const data = new PlayerAdventRewards({ stats: 'meow' }, '100'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerAdventRewards); + expectTypeOf(data).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expect(data.year).toBeGreaterThanOrEqual(0); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.day1).toBeDefined(); + expect(data.day1).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day1).toEqualTypeOf(); + expect(data.day2).toBeDefined(); + expect(data.day2).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day2).toEqualTypeOf(); + expect(data.day3).toBeDefined(); + expect(data.day3).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day3).toEqualTypeOf(); + expect(data.day4).toBeDefined(); + expect(data.day4).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day4).toEqualTypeOf(); + expect(data.day5).toBeDefined(); + expect(data.day5).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day5).toEqualTypeOf(); + expect(data.day6).toBeDefined(); + expect(data.day6).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day6).toEqualTypeOf(); + expect(data.day7).toBeDefined(); + expect(data.day7).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day7).toEqualTypeOf(); + expect(data.day8).toBeDefined(); + expect(data.day8).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day8).toEqualTypeOf(); + expect(data.day9).toBeDefined(); + expect(data.day9).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day9).toEqualTypeOf(); + expect(data.day10).toBeDefined(); + expect(data.day10).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day10).toEqualTypeOf(); + expect(data.day11).toBeDefined(); + expect(data.day11).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day11).toEqualTypeOf(); + expect(data.day12).toBeDefined(); + expect(data.day12).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day12).toEqualTypeOf(); + expect(data.day13).toBeDefined(); + expect(data.day13).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day13).toEqualTypeOf(); + expect(data.day14).toBeDefined(); + expect(data.day14).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day14).toEqualTypeOf(); + expect(data.day15).toBeDefined(); + expect(data.day15).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day15).toEqualTypeOf(); + expect(data.day16).toBeDefined(); + expect(data.day16).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day16).toEqualTypeOf(); + expect(data.day17).toBeDefined(); + expect(data.day17).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day17).toEqualTypeOf(); + expect(data.day18).toBeDefined(); + expect(data.day18).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day18).toEqualTypeOf(); + expect(data.day19).toBeDefined(); + expect(data.day19).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day19).toEqualTypeOf(); + expect(data.day20).toBeDefined(); + expect(data.day20).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day20).toEqualTypeOf(); + expect(data.day21).toBeDefined(); + expect(data.day21).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day21).toEqualTypeOf(); + expect(data.day22).toBeDefined(); + expect(data.day22).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day22).toEqualTypeOf(); + expect(data.day23).toBeDefined(); + expect(data.day23).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day23).toEqualTypeOf(); + expect(data.day24).toBeDefined(); + expect(data.day24).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day24).toEqualTypeOf(); + expect(data.day25).toBeDefined(); + expect(data.day25).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data.day25).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.ts b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.ts new file mode 100644 index 000000000..d76c3643a --- /dev/null +++ b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewards.ts @@ -0,0 +1,60 @@ +import PlayerAdventRewardsDay from './PlayerAdventRewardsDay.js'; + +class PlayerAdventRewards { + year: number; + day1: PlayerAdventRewardsDay; + day2: PlayerAdventRewardsDay; + day3: PlayerAdventRewardsDay; + day4: PlayerAdventRewardsDay; + day5: PlayerAdventRewardsDay; + day6: PlayerAdventRewardsDay; + day7: PlayerAdventRewardsDay; + day8: PlayerAdventRewardsDay; + day9: PlayerAdventRewardsDay; + day10: PlayerAdventRewardsDay; + day11: PlayerAdventRewardsDay; + day12: PlayerAdventRewardsDay; + day13: PlayerAdventRewardsDay; + day14: PlayerAdventRewardsDay; + day15: PlayerAdventRewardsDay; + day16: PlayerAdventRewardsDay; + day17: PlayerAdventRewardsDay; + day18: PlayerAdventRewardsDay; + day19: PlayerAdventRewardsDay; + day20: PlayerAdventRewardsDay; + day21: PlayerAdventRewardsDay; + day22: PlayerAdventRewardsDay; + day23: PlayerAdventRewardsDay; + day24: PlayerAdventRewardsDay; + day25: PlayerAdventRewardsDay; + constructor(data: Record, year: string) { + this.year = Number(year); + this.day1 = new PlayerAdventRewardsDay(data, '1'); + this.day2 = new PlayerAdventRewardsDay(data, '2'); + this.day3 = new PlayerAdventRewardsDay(data, '3'); + this.day4 = new PlayerAdventRewardsDay(data, '4'); + this.day5 = new PlayerAdventRewardsDay(data, '5'); + this.day6 = new PlayerAdventRewardsDay(data, '6'); + this.day7 = new PlayerAdventRewardsDay(data, '7'); + this.day8 = new PlayerAdventRewardsDay(data, '8'); + this.day9 = new PlayerAdventRewardsDay(data, '9'); + this.day10 = new PlayerAdventRewardsDay(data, '10'); + this.day11 = new PlayerAdventRewardsDay(data, '11'); + this.day12 = new PlayerAdventRewardsDay(data, '12'); + this.day13 = new PlayerAdventRewardsDay(data, '13'); + this.day14 = new PlayerAdventRewardsDay(data, '14'); + this.day15 = new PlayerAdventRewardsDay(data, '15'); + this.day16 = new PlayerAdventRewardsDay(data, '16'); + this.day17 = new PlayerAdventRewardsDay(data, '17'); + this.day18 = new PlayerAdventRewardsDay(data, '18'); + this.day19 = new PlayerAdventRewardsDay(data, '19'); + this.day20 = new PlayerAdventRewardsDay(data, '20'); + this.day21 = new PlayerAdventRewardsDay(data, '21'); + this.day22 = new PlayerAdventRewardsDay(data, '22'); + this.day23 = new PlayerAdventRewardsDay(data, '23'); + this.day24 = new PlayerAdventRewardsDay(data, '24'); + this.day25 = new PlayerAdventRewardsDay(data, '25'); + } +} + +export default PlayerAdventRewards; diff --git a/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.test.ts b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.test.ts new file mode 100644 index 000000000..6745dd11e --- /dev/null +++ b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.test.ts @@ -0,0 +1,18 @@ +import PlayerAdventRewardsDay from './PlayerAdventRewardsDay.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerAdventRewardsDay', () => { + const data = new PlayerAdventRewardsDay({ stats: 'meow' }, '0'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerAdventRewardsDay); + expectTypeOf(data).toEqualTypeOf(); + expect(data.day).toBeDefined(); + expect(data.day).toBeGreaterThanOrEqual(0); + expectTypeOf(data.day).toEqualTypeOf(); + expect(data.claimed).toBeDefined(); + expectTypeOf(data.claimed).toEqualTypeOf(); + expect(data.claimedTimestamp).toBeDefined(); + expectTypeOf(data.claimedTimestamp).toEqualTypeOf(); + expect(data.claimedAt).toBeDefined(); + expectTypeOf(data.claimedAt).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.ts b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.ts new file mode 100644 index 000000000..45eb769ee --- /dev/null +++ b/src/Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.ts @@ -0,0 +1,14 @@ +class PlayerAdventRewardsDay { + day: number; + claimed: boolean; + claimedTimestamp: number | null; + claimedAt: Date | null; + constructor(data: Record, day: string) { + this.day = Number(day); + this.claimed = Boolean(data?.[`day${day}`]); + this.claimedTimestamp = this.claimed ? data?.[`day${day}`] : null; + this.claimedAt = this.claimedTimestamp ? new Date(this.claimedTimestamp) : null; + } +} + +export default PlayerAdventRewardsDay; diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.test.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.test.ts new file mode 100644 index 000000000..234741a69 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.test.ts @@ -0,0 +1,42 @@ +import PlayerCosmeticsPet from './PlayerCosmeticsPet.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerCosmeticsPetName } from '../../../../Types/Player.js'; + +test('PlayerCosmeticsPet', () => { + const data = new PlayerCosmeticsPet('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerCosmeticsPet); + expectTypeOf(data).toEqualTypeOf(); + expect(data.isFavorite).toBeDefined(); + expectTypeOf(data.isFavorite).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.active).toBeDefined(); + expectTypeOf(data.active).toEqualTypeOf(); + expect(data.hunger).toBeDefined(); + expect(data.hunger).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hunger).toEqualTypeOf(); + expect(data.lastFed).toBeDefined(); + expectTypeOf(data.lastFed).toEqualTypeOf(); + expect(data.lastFedAt).toBeDefined(); + expectTypeOf(data.lastFedAt).toEqualTypeOf(); + expect(data.thirst).toBeDefined(); + expect(data.thirst).toBeGreaterThanOrEqual(0); + expectTypeOf(data.thirst).toEqualTypeOf(); + expect(data.lastDrank).toBeDefined(); + expectTypeOf(data.lastDrank).toEqualTypeOf(); + expect(data.lastDrankAt).toBeDefined(); + expectTypeOf(data.lastDrankAt).toEqualTypeOf(); + expect(data.exercise).toBeDefined(); + expect(data.exercise).toBeGreaterThanOrEqual(0); + expectTypeOf(data.exercise).toEqualTypeOf(); + expect(data.lastExercised).toBeDefined(); + expectTypeOf(data.lastExercised).toEqualTypeOf(); + expect(data.lastExercisedAt).toBeDefined(); + expectTypeOf(data.lastExercisedAt).toEqualTypeOf(); + expect(data.nickname).toBeDefined(); + expectTypeOf(data.nickname).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experience).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.ts new file mode 100644 index 000000000..afdd9fb71 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.ts @@ -0,0 +1,38 @@ +import type { PlayerCosmeticsPetName } from '../../../../Types/Player.js'; + +class PlayerCosmeticsPet { + isFavorite: boolean; + name: PlayerCosmeticsPetName | 'UNKNOWN'; + active: boolean; + hunger: number; + lastFed: number | null; + lastFedAt: Date | null; + thirst: number; + lastDrank: number | null; + lastDrankAt: Date | null; + exercise: number; + lastExercised: number | null; + lastExercisedAt: Date | null; + nickname: string; + experience: number; + constructor(name: string, data: Record) { + this.isFavorite = data?.vanityFavorites ? Boolean(name.toUpperCase() === data?.vanityFavorites) : false; + name = name.replace('pet_', ''); + this.name = name as PlayerCosmeticsPetName; + this.active = data?.currentPet === name.toUpperCase(); + const stats = data?.petStats?.[name.toUpperCase()] || {}; + this.hunger = stats?.HUNGER?.value || 0; + this.lastFed = stats?.HUNGER?.timestamp || null; + this.lastFedAt = this.lastFed ? new Date(this.lastFed) : null; + this.thirst = stats?.THIRST?.value || 0; + this.lastDrank = stats?.THIRST?.timestamp || null; + this.lastDrankAt = this.lastDrank ? new Date(this.lastDrank) : null; + this.exercise = stats?.EXERCISE?.value || 0; + this.lastExercised = stats?.EXERCISE ? stats?.EXERCISE?.timestamp : null; + this.lastExercisedAt = this.lastExercised ? new Date(this.lastExercised) : null; + this.nickname = stats?.name || ''; + this.experience = stats?.experience || 0; + } +} + +export default PlayerCosmeticsPet; diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.test.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.test.ts new file mode 100644 index 000000000..134871b52 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.test.ts @@ -0,0 +1,20 @@ +import PlayerCosmeticsPet from './PlayerCosmeticsPet.js'; +import PlayerCosmeticsPets from './PlayerCosmeticsPets.js'; +import PlayerCosmeticsPetsConsumables from './PlayerCosmeticsPetsConsumables.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerCosmeticsPets', () => { + const data = new PlayerCosmeticsPets({ stats: 'meow' }, []); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerCosmeticsPets); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastJourney).toBeDefined(); + expectTypeOf(data.lastJourney).toEqualTypeOf(); + expect(data.lastJourneyAt).toBeDefined(); + expectTypeOf(data.lastJourneyAt).toEqualTypeOf(); + expect(data.consumables).toBeDefined(); + expect(data.consumables).toBeInstanceOf(PlayerCosmeticsPetsConsumables); + expectTypeOf(data.consumables).toEqualTypeOf(); + expect(data.pets).toBeDefined(); + expectTypeOf(data.pets).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.ts new file mode 100644 index 000000000..0d406af6d --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.ts @@ -0,0 +1,17 @@ +import PlayerCosmeticsPet from './PlayerCosmeticsPet.js'; +import PlayerCosmeticsPetsConsumables from './PlayerCosmeticsPetsConsumables.js'; + +class PlayerCosmeticsPets { + lastJourney: number | null; + lastJourneyAt: Date | null; + consumables: PlayerCosmeticsPetsConsumables; + pets: PlayerCosmeticsPet[]; + constructor(data: Record, pets: string[]) { + this.lastJourney = data.petJourneyTimestamp || null; + this.lastJourneyAt = this.lastJourney ? new Date(this.lastJourney) : null; + this.consumables = new PlayerCosmeticsPetsConsumables(data?.petConsumables || {}); + this.pets = pets.map((petName) => new PlayerCosmeticsPet(petName, data)); + } +} + +export default PlayerCosmeticsPets; diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.test.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.test.ts new file mode 100644 index 000000000..7802a1bc1 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.test.ts @@ -0,0 +1,90 @@ +import PlayerCosmeticsPetsConsumables from './PlayerCosmeticsPetsConsumables.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerCosmeticsPetsConsumables', () => { + const data = new PlayerCosmeticsPetsConsumables({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerCosmeticsPetsConsumables); + expectTypeOf(data).toEqualTypeOf(); + expect(data.cake).toBeDefined(); + expect(data.cake).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cake).toEqualTypeOf(); + expect(data.cookie).toBeDefined(); + expect(data.cookie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cookie).toEqualTypeOf(); + expect(data.feather).toBeDefined(); + expect(data.feather).toBeGreaterThanOrEqual(0); + expectTypeOf(data.feather).toEqualTypeOf(); + expect(data.goldRecord).toBeDefined(); + expect(data.goldRecord).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldRecord).toEqualTypeOf(); + expect(data.hayBlock).toBeDefined(); + expect(data.hayBlock).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hayBlock).toEqualTypeOf(); + expect(data.lavaBucket).toBeDefined(); + expect(data.lavaBucket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lavaBucket).toEqualTypeOf(); + expect(data.leash).toBeDefined(); + expect(data.leash).toBeGreaterThanOrEqual(0); + expectTypeOf(data.leash).toEqualTypeOf(); + expect(data.magmaCream).toBeDefined(); + expect(data.magmaCream).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magmaCream).toEqualTypeOf(); + expect(data.melon).toBeDefined(); + expect(data.melon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.melon).toEqualTypeOf(); + expect(data.milkBucket).toBeDefined(); + expect(data.milkBucket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.milkBucket).toEqualTypeOf(); + expect(data.mushroomSoup).toBeDefined(); + expect(data.mushroomSoup).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mushroomSoup).toEqualTypeOf(); + expect(data.pork).toBeDefined(); + expect(data.pork).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pork).toEqualTypeOf(); + expect(data.pumpkinPie).toBeDefined(); + expect(data.pumpkinPie).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pumpkinPie).toEqualTypeOf(); + expect(data.rawFish).toBeDefined(); + expect(data.rawFish).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rawFish).toEqualTypeOf(); + expect(data.slimeBall).toBeDefined(); + expect(data.slimeBall).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slimeBall).toEqualTypeOf(); + expect(data.stick).toBeDefined(); + expect(data.stick).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stick).toEqualTypeOf(); + expect(data.waterBucket).toBeDefined(); + expect(data.waterBucket).toBeGreaterThanOrEqual(0); + expectTypeOf(data.waterBucket).toEqualTypeOf(); + expect(data.woodSword).toBeDefined(); + expect(data.woodSword).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woodSword).toEqualTypeOf(); + expect(data.apple).toBeDefined(); + expect(data.apple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.apple).toEqualTypeOf(); + expect(data.bakedPotato).toBeDefined(); + expect(data.bakedPotato).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bakedPotato).toEqualTypeOf(); + expect(data.cookedBeef).toBeDefined(); + expect(data.cookedBeef).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cookedBeef).toEqualTypeOf(); + expect(data.redRose).toBeDefined(); + expect(data.redRose).toBeGreaterThanOrEqual(0); + expectTypeOf(data.redRose).toEqualTypeOf(); + expect(data.wheat).toBeDefined(); + expect(data.wheat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wheat).toEqualTypeOf(); + expect(data.bread).toBeDefined(); + expect(data.bread).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bread).toEqualTypeOf(); + expect(data.carrot).toBeDefined(); + expect(data.carrot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.carrot).toEqualTypeOf(); + expect(data.rottenFlesh).toBeDefined(); + expect(data.rottenFlesh).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rottenFlesh).toEqualTypeOf(); + expect(data.bone).toBeDefined(); + expect(data.bone).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bone).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.ts b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.ts new file mode 100644 index 000000000..3af428562 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.ts @@ -0,0 +1,60 @@ +class PlayerCosmeticsPetsConsumables { + cake: number; + cookie: number; + feather: number; + goldRecord: number; + hayBlock: number; + lavaBucket: number; + leash: number; + magmaCream: number; + melon: number; + milkBucket: number; + mushroomSoup: number; + pork: number; + pumpkinPie: number; + rawFish: number; + slimeBall: number; + stick: number; + waterBucket: number; + woodSword: number; + apple: number; + bakedPotato: number; + cookedBeef: number; + redRose: number; + wheat: number; + bread: number; + carrot: number; + rottenFlesh: number; + bone: number; + constructor(data: Record) { + this.cake = data?.CAKE || 0; + this.cookie = data?.COOKIE || 0; + this.feather = data?.FEATHER || 0; + this.goldRecord = data?.GOLD_RECORD || 0; + this.hayBlock = data?.HAY_BLOCK || 0; + this.lavaBucket = data?.LAVA_BUCKET || 0; + this.leash = data?.LEASH || 0; + this.magmaCream = data?.MAGMA_CREAM || 0; + this.melon = data?.MELON || 0; + this.milkBucket = data?.MILK_BUCKET || 0; + this.mushroomSoup = data?.MUSHROOM_SOUP || 0; + this.pork = data?.PORK || 0; + this.pumpkinPie = data?.PUMPKIN_PIE || 0; + this.rawFish = data?.RAW_FISH || 0; + this.slimeBall = data?.SLIME_BALL || 0; + this.stick = data?.STICK || 0; + this.waterBucket = data?.WATER_BUCKET || 0; + this.woodSword = data?.WOOD_SWORD || 0; + this.apple = data?.APPLE || 0; + this.bakedPotato = data?.BAKED_POTATO || 0; + this.cookedBeef = data?.COOKED_BEEF || 0; + this.redRose = data?.RED_ROSE || 0; + this.wheat = data?.WHEAT || 0; + this.bread = data?.BREAD || 0; + this.carrot = data?.CARROT_ITEM || 0; + this.rottenFlesh = data?.ROTTEN_FLESH || 0; + this.bone = data?.BONE || 0; + } +} + +export default PlayerCosmeticsPetsConsumables; diff --git a/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.test.ts b/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.test.ts new file mode 100644 index 000000000..a1bc4cc70 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.test.ts @@ -0,0 +1,56 @@ +import Color from '../../Color.js'; +import PlayerCosmetics from './PlayerCosmetics.js'; +import PlayerCosmeticsPets from './Pets/PlayerCosmeticsPets.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + PlayerCosmeticsClickEffects, + PlayerCosmeticsCloak, + PlayerCosmeticsGadget, + PlayerCosmeticsHat, + PlayerCosmeticsMorph, + PlayerCosmeticsParticlePack, + PlayerCosmeticsRankColor, + PlayerCosmeticsSuit, + PlayerCosmeticsTaunt +} from '../../../Types/Player.js'; +import type { SortName } from '../../../Types/Global.js'; + +test('PlayerCosmetics', () => { + const data = new PlayerCosmetics({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerCosmetics); + expectTypeOf(data).toEqualTypeOf(); + expect(data.menuSort).toBeDefined(); + expectTypeOf(data.menuSort).toEqualTypeOf(); + expect(data.rankPlusColor).toBeDefined(); + expectTypeOf(data.rankPlusColor).toEqualTypeOf(); + expect(data.monthlyRankColor).toBeDefined(); + expectTypeOf(data.monthlyRankColor).toEqualTypeOf(); + expect(data.cosmetics).toBeDefined(); + expectTypeOf(data.cosmetics).toEqualTypeOf(); + expect(data.pets).toBeDefined(); + expect(data.pets).toBeInstanceOf(PlayerCosmeticsPets); + expectTypeOf(data.pets).toEqualTypeOf(); + expect(data.unlockedSuits).toBeDefined(); + expectTypeOf(data.unlockedSuits).toEqualTypeOf(); + expect(data.unlockedHats).toBeDefined(); + expectTypeOf(data.unlockedHats).toEqualTypeOf(); + expect(data.selectedGadget).toBeDefined(); + expectTypeOf(data.selectedGadget).toEqualTypeOf(); + expect(data.unlockedGadgets).toBeDefined(); + expectTypeOf(data.unlockedGadgets).toEqualTypeOf(); + expect(data.unlockedMorphs).toBeDefined(); + expectTypeOf(data.unlockedMorphs).toEqualTypeOf(); + expect(data.unlockedCloaks).toBeDefined(); + expectTypeOf(data.unlockedCloaks).toEqualTypeOf(); + expect(data.unlockedTaunts).toBeDefined(); + expectTypeOf(data.unlockedTaunts).toEqualTypeOf(); + expect(data.unlockedRankColors).toBeDefined(); + expectTypeOf(data.unlockedRankColors).toEqualTypeOf(); + expect(data.selectedParticlePack).toBeDefined(); + expectTypeOf(data.selectedParticlePack).toEqualTypeOf(); + expect(data.unlockedParticlePacks).toBeDefined(); + expectTypeOf(data.unlockedParticlePacks).toEqualTypeOf(); + expect(data.unlockedClickEffects).toBeDefined(); + expectTypeOf(data.unlockedClickEffects).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.ts b/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.ts new file mode 100644 index 000000000..501456494 --- /dev/null +++ b/src/Structures/Player/PlayerCosmetics/PlayerCosmetics.ts @@ -0,0 +1,83 @@ +import Color from '../../Color.js'; +import PlayerCosmeticsPets from './Pets/PlayerCosmeticsPets.js'; +import type { + PlayerCosmeticsClickEffects, + PlayerCosmeticsCloak, + PlayerCosmeticsGadget, + PlayerCosmeticsHat, + PlayerCosmeticsMorph, + PlayerCosmeticsParticlePack, + PlayerCosmeticsRankColor, + PlayerCosmeticsSuit, + PlayerCosmeticsTaunt +} from '../../../Types/Player.js'; +import type { SortName } from '../../../Types/Global.js'; + +class PlayerCosmetics { + menuSort: SortName | 'UNKNOWN'; + rankPlusColor: Color | null; + monthlyRankColor: Color | null; + cosmetics: string[]; + pets: PlayerCosmeticsPets; + unlockedSuits: PlayerCosmeticsSuit[]; + unlockedHats: PlayerCosmeticsHat[]; + selectedGadget: PlayerCosmeticsGadget | null; + unlockedGadgets: PlayerCosmeticsGadget[]; + unlockedMorphs: PlayerCosmeticsMorph[]; + unlockedCloaks: PlayerCosmeticsCloak[]; + unlockedTaunts: PlayerCosmeticsTaunt[]; + unlockedRankColors: PlayerCosmeticsRankColor[]; + selectedParticlePack: PlayerCosmeticsParticlePack | 'UNKNOWN'; + unlockedParticlePacks: PlayerCosmeticsParticlePack[]; + unlockedClickEffects: PlayerCosmeticsClickEffects[]; + constructor(data: Record) { + this.menuSort = data?.collectibles_menu_sort || 'UNKNOWN'; + this.rankPlusColor = data?.rankPlusColor ? new Color(data?.rankPlusColor) : null; + this.monthlyRankColor = data?.monthlyRankColor ? new Color(data?.monthlyRankColor) : null; + this.cosmetics = data?.vanityMeta?.packages || []; + this.pets = new PlayerCosmeticsPets( + data, + this.cosmetics.filter((x) => x.startsWith('pet_')) + ); + + this.unlockedSuits = this.cosmetics + .filter((x) => x.startsWith('suit_')) + .map((x) => x.replace('suit_', '') as PlayerCosmeticsSuit); + + this.unlockedHats = this.cosmetics + .filter((x) => x.startsWith('hat_')) + .map((x) => x.replace('hat_', '') as PlayerCosmeticsHat); + + this.selectedGadget = data?.currentGadget || null; + this.unlockedGadgets = this.cosmetics + .filter((x) => x.startsWith('gadget_')) + .map((x) => x.replace('gadget_', '') as PlayerCosmeticsGadget); + + this.unlockedMorphs = this.cosmetics + .filter((x) => x.startsWith('morph_')) + .map((x) => x.replace('morph_', '') as PlayerCosmeticsMorph); + + this.unlockedCloaks = this.cosmetics + .filter((x) => x.startsWith('cloak_')) + .map((x) => x.replace('cloak_', '') as PlayerCosmeticsCloak); + + this.unlockedTaunts = this.cosmetics + .filter((x) => x.startsWith('taunt_')) + .map((x) => x.replace('taunt_', '') as PlayerCosmeticsTaunt); + + this.unlockedRankColors = this.cosmetics + .filter((x) => x.startsWith('rankcolor_')) + .map((x) => x.replace('rankcolor_', '') as PlayerCosmeticsRankColor); + + this.selectedParticlePack = data?.particlePack || null; + this.unlockedParticlePacks = this.cosmetics + .filter((x) => x.startsWith('particlepack_')) + .map((x) => x.replace('particlepack_', '') as PlayerCosmeticsParticlePack); + + this.unlockedClickEffects = this.cosmetics + .filter((x) => x.startsWith('clickeffects_')) + .map((x) => x.replace('clickeffects_', '') as PlayerCosmeticsClickEffects); + } +} + +export default PlayerCosmetics; diff --git a/src/Structures/Player/PlayerGifting.test.ts b/src/Structures/Player/PlayerGifting.test.ts new file mode 100644 index 000000000..5660f6ba9 --- /dev/null +++ b/src/Structures/Player/PlayerGifting.test.ts @@ -0,0 +1,25 @@ +import PlayerGifting from './PlayerGifting.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerGifting', () => { + const data = new PlayerGifting({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerGifting); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bundlesReceived).toBeDefined(); + expect(data.bundlesReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bundlesReceived).toEqualTypeOf(); + expect(data.bundlesGiven).toBeDefined(); + expect(data.bundlesGiven).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bundlesGiven).toEqualTypeOf(); + expect(data.milestones).toBeDefined(); + expectTypeOf(data.milestones).toEqualTypeOf(); + expect(data.giftsGiven).toBeDefined(); + expect(data.giftsGiven).toBeGreaterThanOrEqual(0); + expectTypeOf(data.giftsGiven).toEqualTypeOf(); + expect(data.ranksGiven).toBeDefined(); + expect(data.ranksGiven).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ranksGiven).toEqualTypeOf(); + expect(data.ranksGivenMilestones).toBeDefined(); + expectTypeOf(data.ranksGivenMilestones).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerGifting.ts b/src/Structures/Player/PlayerGifting.ts new file mode 100644 index 000000000..55051f69b --- /dev/null +++ b/src/Structures/Player/PlayerGifting.ts @@ -0,0 +1,18 @@ +class PlayerGifting { + bundlesReceived: number; + bundlesGiven: number; + milestones: string[]; + giftsGiven: number; + ranksGiven: number; + ranksGivenMilestones: string[]; + constructor(data: Record) { + this.bundlesReceived = data.realBundlesReceived || 0; + this.bundlesGiven = data.realBundlesGiven || 0; + this.milestones = (data.milestones || []).reverse(); + this.giftsGiven = data.giftsGiven || 0; + this.ranksGiven = data.ranksGiven || 0; + this.ranksGivenMilestones = (data.rankgiftingmilestones || []).reverse(); + } +} + +export default PlayerGifting; diff --git a/src/Structures/Player/PlayerHousing/PlayerHousing.test.ts b/src/Structures/Player/PlayerHousing/PlayerHousing.test.ts new file mode 100644 index 000000000..ae300f4c4 --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousing.test.ts @@ -0,0 +1,29 @@ +import PlayerHousing from './PlayerHousing.js'; +import PlayerHousingGivenCookies from './PlayerHousingGivenCookies.js'; +import PlayerHousingPlayerSettings from './PlayerHousingPlayerSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerHousingPlotSize, PlayerHousingTutorialStage } from '../../../Types/Player.js'; + +test('PlayerHousing', () => { + const data = new PlayerHousing({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerHousing); + expectTypeOf(data).toEqualTypeOf(); + expect(data.allowedBlocks).toBeDefined(); + expectTypeOf(data.allowedBlocks).toEqualTypeOf(); + expect(data.packages).toBeDefined(); + expectTypeOf(data.packages).toEqualTypeOf(); + expect(data.tutorialStage).toBeDefined(); + expectTypeOf(data.tutorialStage).toEqualTypeOf(); + expect(data.firstHouseJoinTimestamp).toBeDefined(); + expectTypeOf(data.firstHouseJoinTimestamp).toEqualTypeOf(); + expect(data.firstHouseJoinAt).toBeDefined(); + expectTypeOf(data.firstHouseJoinAt).toEqualTypeOf(); + expect(data.plotSize).toBeDefined(); + expectTypeOf(data.plotSize).toEqualTypeOf(); + expect(data.playerSettings).toBeDefined(); + expect(data.playerSettings).toBeInstanceOf(PlayerHousingPlayerSettings); + expectTypeOf(data.playerSettings).toEqualTypeOf(); + expect(data.givenCookies).toBeDefined(); + expectTypeOf(data.givenCookies).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerHousing/PlayerHousing.ts b/src/Structures/Player/PlayerHousing/PlayerHousing.ts new file mode 100644 index 000000000..7f047d06c --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousing.ts @@ -0,0 +1,31 @@ +import PlayerHousingGivenCookies from './PlayerHousingGivenCookies.js'; +import PlayerHousingPlayerSettings from './PlayerHousingPlayerSettings.js'; +import type { PlayerHousingPlotSize, PlayerHousingTutorialStage } from '../../../Types/Player.js'; + +class PlayerHousing { + allowedBlocks: string[]; + packages: string[]; + tutorialStage: PlayerHousingTutorialStage | 'UNKNOWN'; + firstHouseJoinTimestamp: number | null; + firstHouseJoinAt: Date | null; + plotSize: PlayerHousingPlotSize | 'UNKNOWN'; + playerSettings: PlayerHousingPlayerSettings; + givenCookies: PlayerHousingGivenCookies[]; + constructor(data: Record) { + this.allowedBlocks = data?.allowedBlocks || []; + this.packages = data?.packages || []; + this.playerSettings = new PlayerHousingPlayerSettings(data?.playerSettings || {}); + this.tutorialStage = data?.tutorialStep || 'UNKNOWN'; + this.firstHouseJoinTimestamp = data.firstHouseJoinMs || null; + this.firstHouseJoinAt = this.firstHouseJoinTimestamp ? new Date(this.firstHouseJoinTimestamp) : null; + this.plotSize = data?.plotSize || 'UNKNOWN'; + this.givenCookies = []; + Object.keys(data) + .filter((key) => key.startsWith('given_cookies_')) + .map((key) => { + this.givenCookies.push(new PlayerHousingGivenCookies(key, data[key])); + }); + } +} + +export default PlayerHousing; diff --git a/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.test.ts b/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.test.ts new file mode 100644 index 000000000..9a22da885 --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.test.ts @@ -0,0 +1,13 @@ +import PlayerHousingGivenCookies from './PlayerHousingGivenCookies.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerHousingGivenCookies', () => { + const data = new PlayerHousingGivenCookies('mrrp', ['meow']); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerHousingGivenCookies); + expectTypeOf(data).toEqualTypeOf(); + expect(data.date).toBeDefined(); + expectTypeOf(data.date).toEqualTypeOf(); + expect(data.houses).toBeDefined(); + expectTypeOf(data.houses).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.ts b/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.ts new file mode 100644 index 000000000..2f8eb33e2 --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousingGivenCookies.ts @@ -0,0 +1,10 @@ +class PlayerHousingGivenCookies { + date: string; + houses: string[]; + constructor(date: string, houses: string[]) { + this.date = date; + this.houses = houses; + } +} + +export default PlayerHousingGivenCookies; diff --git a/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.test.ts b/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.test.ts new file mode 100644 index 000000000..eb882243e --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.test.ts @@ -0,0 +1,25 @@ +import PlayerHousingPlayerSettings from './PlayerHousingPlayerSettings.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerHousingSettingsTextInputType } from '../../../Types/Player.js'; + +test('PlayerHousingPlayerSettings', () => { + const data = new PlayerHousingPlayerSettings({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerHousingPlayerSettings); + expectTypeOf(data).toEqualTypeOf(); + expect(data.playerVisibility).toBeDefined(); + expect(data.playerVisibility).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playerVisibility).toEqualTypeOf(); + expect(data.showBorder).toBeDefined(); + expectTypeOf(data.showBorder).toEqualTypeOf(); + expect(data.playJukeboxMusic).toBeDefined(); + expectTypeOf(data.playJukeboxMusic).toEqualTypeOf(); + expect(data.showTips).toBeDefined(); + expectTypeOf(data.showTips).toEqualTypeOf(); + expect(data.showProToolsParticles).toBeDefined(); + expectTypeOf(data.showProToolsParticles).toEqualTypeOf(); + expect(data.showHousingPlusPrefix).toBeDefined(); + expectTypeOf(data.showHousingPlusPrefix).toEqualTypeOf(); + expect(data.textInputType).toBeDefined(); + expectTypeOf(data.textInputType).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.ts b/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.ts new file mode 100644 index 000000000..06e2e2743 --- /dev/null +++ b/src/Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.ts @@ -0,0 +1,22 @@ +import type { PlayerHousingSettingsTextInputType } from '../../../Types/Player.js'; + +class PlayerHousingPlayerSettings { + playerVisibility: number; + showBorder: boolean; + playJukeboxMusic: boolean; + showTips: boolean; + showProToolsParticles: boolean; + showHousingPlusPrefix: boolean; + textInputType: PlayerHousingSettingsTextInputType | 'UNKNOWN'; + constructor(data: Record) { + this.playerVisibility = data?.VISIBILITY ? Number(data?.VISIBILITY.split('-')[1]) : 4; + this.showBorder = data?.BORDER ? Boolean(data?.BORDER.split('-')[1]) : true; + this.playJukeboxMusic = data?.JUKEBOX_MUSIC ? Boolean(data?.JUKEBOX_MUSIC.split('-')[1]) : true; + this.showTips = data?.TIPS ? Boolean(data?.TIPS.split('-')[1]) : false; + this.showProToolsParticles = data?.PRO_TOOLS_PARTICLES ? Boolean(data?.PRO_TOOLS_PARTICLES.split('-')[1]) : false; + this.showHousingPlusPrefix = data?.HOUSING_PLUS_PREFIX ? Boolean(data?.HOUSING_PLUS_PREFIX.split('-')[1]) : false; + this.textInputType = data?.TEXT_INPUT_TYPE ? data?.TEXT_INPUT_TYPE.split('-')[1] : 'UNKNOWN'; + } +} + +export default PlayerHousingPlayerSettings; diff --git a/src/Structures/Player/PlayerParkour.test.ts b/src/Structures/Player/PlayerParkour.test.ts new file mode 100644 index 000000000..beb7b00be --- /dev/null +++ b/src/Structures/Player/PlayerParkour.test.ts @@ -0,0 +1,19 @@ +import PlayerParkour from './PlayerParkour.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerParkour', () => { + const data = new PlayerParkour({ stats: 'meow' }, { stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerParkour); + expectTypeOf(data).toEqualTypeOf(); + expect(data.location).toBeDefined(); + expectTypeOf(data.location).toEqualTypeOf(); + expect(data.timeStart).toBeDefined(); + expect(data.timeStart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timeStart).toEqualTypeOf(); + expect(data.timeTook).toBeDefined(); + expect(data.timeTook).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timeTook).toEqualTypeOf(); + expect(data.checkPoints).toBeDefined(); + expectTypeOf(data.checkPoints).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerParkour.ts b/src/Structures/Player/PlayerParkour.ts new file mode 100644 index 000000000..d69d578ae --- /dev/null +++ b/src/Structures/Player/PlayerParkour.ts @@ -0,0 +1,16 @@ +class PlayerParkour { + location: string; + timeStart: number; + timeTook: number; + checkPoints: number[]; + constructor(data: Record, checkPoints: Record, location: string) { + this.location = location; + this.timeStart = data?.[location]?.[0].timeStart || 0; + this.timeTook = data?.[location]?.[0].timeTook || 0; + this.checkPoints = Object.keys(checkPoints?.[location] || {}).map( + (checkPoint: string) => checkPoints?.[location]?.[checkPoint] + ); + } +} + +export default PlayerParkour; diff --git a/src/Structures/Player/PlayerQuests/PlayerQuest.test.ts b/src/Structures/Player/PlayerQuests/PlayerQuest.test.ts new file mode 100644 index 000000000..7911325b0 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuest.test.ts @@ -0,0 +1,15 @@ +import PlayerQuest from './PlayerQuest.js'; +import PlayerQuestCompletions from './PlayerQuestCompletions.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerQuest', () => { + const data = new PlayerQuest({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerQuest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.completions).toBeDefined(); + expect(data.completions).toBeInstanceOf(PlayerQuestCompletions); + expectTypeOf(data.completions).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerQuests/PlayerQuest.ts b/src/Structures/Player/PlayerQuests/PlayerQuest.ts new file mode 100644 index 000000000..1c94b0888 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuest.ts @@ -0,0 +1,12 @@ +import PlayerQuestCompletions from './PlayerQuestCompletions.js'; + +class PlayerQuest { + name: string; + completions: PlayerQuestCompletions; + constructor(data: Record, name: string) { + this.name = name; + this.completions = new PlayerQuestCompletions(data?.completions || []); + } +} + +export default PlayerQuest; diff --git a/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.test.ts b/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.test.ts new file mode 100644 index 000000000..c5eb4559c --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.test.ts @@ -0,0 +1,16 @@ +import PlayerQuestCompletion from './PlayerQuestCompletion.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerQuestCompletion', () => { + const data = new PlayerQuestCompletion({ stats: 0 }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerQuestCompletion); + expectTypeOf(data).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.timestampAt).toBeDefined(); + expectTypeOf(data.timestampAt).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.ts b/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.ts new file mode 100644 index 000000000..d477ba924 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuestCompletion.ts @@ -0,0 +1,12 @@ +class PlayerQuestCompletion { + amount: number; + timestamp: number | null; + timestampAt: Date | null; + constructor(data: Record) { + this.amount = data.length || 0; + this.timestamp = data?.time ? data.time : null; + this.timestampAt = this.timestamp ? new Date(this.timestamp) : null; + } +} + +export default PlayerQuestCompletion; diff --git a/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.test.ts b/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.test.ts new file mode 100644 index 000000000..5ac238d33 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.test.ts @@ -0,0 +1,15 @@ +import PlayerQuestCompletion from './PlayerQuestCompletion.js'; +import PlayerQuestCompletions from './PlayerQuestCompletions.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerQuestCompletions', () => { + const data = new PlayerQuestCompletions([{ stats: 0 }]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerQuestCompletions); + expectTypeOf(data).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.completions).toBeDefined(); + expectTypeOf(data.completions).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.ts b/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.ts new file mode 100644 index 000000000..565517b0f --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuestCompletions.ts @@ -0,0 +1,15 @@ +import PlayerQuestCompletion from './PlayerQuestCompletion.js'; + +class PlayerQuestCompletions { + amount: number; + completions: PlayerQuestCompletion[]; + constructor(data: Record[]) { + this.amount = data.length || 0; + this.completions = []; + data.forEach((completion: Record) => { + this.completions.push(new PlayerQuestCompletion(completion)); + }); + } +} + +export default PlayerQuestCompletions; diff --git a/src/Structures/Player/PlayerQuests/PlayerQuests.test.ts b/src/Structures/Player/PlayerQuests/PlayerQuests.test.ts new file mode 100644 index 000000000..5d0c91293 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuests.test.ts @@ -0,0 +1,14 @@ +import PlayerQuest from './PlayerQuest.js'; +import PlayerQuests from './PlayerQuests.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerQuests', () => { + const data = new PlayerQuests({ stats: 'meow' }, false); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerQuests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.quests).toBeDefined(); + expectTypeOf(data.quests).toEqualTypeOf(); + expect(data.autoActivate).toBeDefined(); + expectTypeOf(data.autoActivate).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerQuests/PlayerQuests.ts b/src/Structures/Player/PlayerQuests/PlayerQuests.ts new file mode 100644 index 000000000..9761ed434 --- /dev/null +++ b/src/Structures/Player/PlayerQuests/PlayerQuests.ts @@ -0,0 +1,12 @@ +import PlayerQuest from './PlayerQuest.js'; + +class PlayerQuests { + quests: PlayerQuest[]; + autoActivate: boolean; + constructor(data: Record, autoActivate: boolean) { + this.quests = Object.keys(data).map((quest) => new PlayerQuest(data[quest], quest)); + this.autoActivate = autoActivate; + } +} + +export default PlayerQuests; diff --git a/src/Structures/Player/PlayerRankPurchase.test.ts b/src/Structures/Player/PlayerRankPurchase.test.ts new file mode 100644 index 000000000..622ad9862 --- /dev/null +++ b/src/Structures/Player/PlayerRankPurchase.test.ts @@ -0,0 +1,25 @@ +import PlayerRankPurchase from './PlayerRankPurchase.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerRankPurchase', () => { + const data = new PlayerRankPurchase({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerRankPurchase); + expectTypeOf(data).toEqualTypeOf(); + expect(data.vip).toBeDefined(); + expectTypeOf(data.vip).toEqualTypeOf(); + expect(data.vipAt).toBeDefined(); + expectTypeOf(data.vipAt).toEqualTypeOf(); + expect(data.vipPlus).toBeDefined(); + expectTypeOf(data.vipPlus).toEqualTypeOf(); + expect(data.vipPlusAt).toBeDefined(); + expectTypeOf(data.vipPlusAt).toEqualTypeOf(); + expect(data.mvp).toBeDefined(); + expectTypeOf(data.mvp).toEqualTypeOf(); + expect(data.mvpAt).toBeDefined(); + expectTypeOf(data.mvpAt).toEqualTypeOf(); + expect(data.mvpPlus).toBeDefined(); + expectTypeOf(data.mvpPlus).toEqualTypeOf(); + expect(data.mvpPlusAt).toBeDefined(); + expectTypeOf(data.mvpPlusAt).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerRankPurchase.ts b/src/Structures/Player/PlayerRankPurchase.ts new file mode 100644 index 000000000..deac4dcb9 --- /dev/null +++ b/src/Structures/Player/PlayerRankPurchase.ts @@ -0,0 +1,22 @@ +class PlayerRankPurchase { + vip: number | null; + vipAt: Date | null; + vipPlus: number | null; + vipPlusAt: Date | null; + mvp: number | null; + mvpAt: Date | null; + mvpPlus: number | null; + mvpPlusAt: Date | null; + constructor(data: Record) { + this.vip = data?.levelUp_VIP || null; + this.vipAt = this.vip ? new Date(this.vip) : null; + this.vipPlus = data?.levelUp_VIP_PLUS || null; + this.vipPlusAt = this.vipPlus ? new Date(this.vipPlus) : null; + this.mvp = data?.levelUp_MVP || null; + this.mvpAt = this.mvp ? new Date(this.mvp) : null; + this.mvpPlus = data?.levelUp_MVP_PLUS || null; + this.mvpPlusAt = this.mvpPlus ? new Date(this.mvpPlus) : null; + } +} + +export default PlayerRankPurchase; diff --git a/src/Structures/Player/PlayerRewards/PlayerRewards.test.ts b/src/Structures/Player/PlayerRewards/PlayerRewards.test.ts new file mode 100644 index 000000000..fe1cc6c9d --- /dev/null +++ b/src/Structures/Player/PlayerRewards/PlayerRewards.test.ts @@ -0,0 +1,38 @@ +import PlayerRewards from './PlayerRewards.js'; +import PlayerRewardsMonthlyCrate from './PlayerRewardsMonthlyCrate.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerRewards', () => { + const data = new PlayerRewards({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerRewards); + expectTypeOf(data).toEqualTypeOf(); + expect(data.adsenseTokens).toBeDefined(); + expect(data.adsenseTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.adsenseTokens).toEqualTypeOf(); + expect(data.lastAdsenseGenerateTimeAt).toBeDefined(); + expectTypeOf(data.lastAdsenseGenerateTimeAt).toEqualTypeOf(); + expect(data.lastClaimedReward).toBeDefined(); + expect(data.lastClaimedReward).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastClaimedReward).toEqualTypeOf(); + expect(data.rewardHighScore).toBeDefined(); + expect(data.rewardHighScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rewardHighScore).toEqualTypeOf(); + expect(data.rewardScore).toBeDefined(); + expect(data.rewardScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rewardScore).toEqualTypeOf(); + expect(data.rewardStreak).toBeDefined(); + expect(data.rewardStreak).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rewardStreak).toEqualTypeOf(); + expect(data.rewardTokens).toBeDefined(); + expect(data.rewardTokens).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rewardTokens).toEqualTypeOf(); + expect(data.totalDailyRewards).toBeDefined(); + expect(data.totalDailyRewards).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalDailyRewards).toEqualTypeOf(); + expect(data.totalRewards).toBeDefined(); + expect(data.totalRewards).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalRewards).toEqualTypeOf(); + expect(data.monthlyCrates).toBeDefined(); + expectTypeOf(data.monthlyCrates).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerRewards/PlayerRewards.ts b/src/Structures/Player/PlayerRewards/PlayerRewards.ts new file mode 100644 index 000000000..b6c6031b5 --- /dev/null +++ b/src/Structures/Player/PlayerRewards/PlayerRewards.ts @@ -0,0 +1,30 @@ +import PlayerRewardsMonthlyCrate from './PlayerRewardsMonthlyCrate.js'; + +class PlayerRewards { + adsenseTokens: number; + lastAdsenseGenerateTimeAt: Date | null; + lastClaimedReward: number; + rewardHighScore: number; + rewardScore: number; + rewardStreak: number; + rewardTokens: number; + totalDailyRewards: number; + totalRewards: number; + monthlyCrates: PlayerRewardsMonthlyCrate[]; + constructor(data: Record) { + this.adsenseTokens = data?.adsense_tokens || 0; + this.lastAdsenseGenerateTimeAt = data?.lastAdsenseGenerateTime ? new Date(data?.lastAdsenseGenerateTime) : null; + this.lastClaimedReward = data?.lastClaimedReward || 0; + this.rewardHighScore = data?.rewardHighScore || 0; + this.rewardScore = data?.rewardScore || 0; + this.rewardStreak = data?.rewardStreak || 0; + this.rewardTokens = data?.adsence_tokens || 0; + this.totalDailyRewards = data?.totalDailyRewards || 0; + this.totalRewards = data?.totalRewards || 0; + this.monthlyCrates = Object.keys(data?.monthlycrates || {}).map( + (key) => new PlayerRewardsMonthlyCrate(data?.monthlycrates?.[key], key) + ); + } +} + +export default PlayerRewards; diff --git a/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.test.ts b/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.test.ts new file mode 100644 index 000000000..e8915c092 --- /dev/null +++ b/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.test.ts @@ -0,0 +1,21 @@ +import PlayerRewardsMonthlyCrate from './PlayerRewardsMonthlyCrate.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerRewardsMonthlyCrate', () => { + const data = new PlayerRewardsMonthlyCrate({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerRewardsMonthlyCrate); + expectTypeOf(data).toEqualTypeOf(); + expect(data.date).toBeDefined(); + expectTypeOf(data.date).toEqualTypeOf(); + expect(data.REGULAR).toBeDefined(); + expectTypeOf(data.REGULAR).toEqualTypeOf(); + expect(data.VIP).toBeDefined(); + expectTypeOf(data.VIP).toEqualTypeOf(); + expect(data.VIP_PLUS).toBeDefined(); + expectTypeOf(data.VIP_PLUS).toEqualTypeOf(); + expect(data.MVP).toBeDefined(); + expectTypeOf(data.MVP).toEqualTypeOf(); + expect(data.MVP_PLUS).toBeDefined(); + expectTypeOf(data.MVP_PLUS).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.ts b/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.ts new file mode 100644 index 000000000..537c1f641 --- /dev/null +++ b/src/Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.ts @@ -0,0 +1,18 @@ +class PlayerRewardsMonthlyCrate { + date: string; + REGULAR: boolean; + VIP: boolean; + VIP_PLUS: boolean; + MVP: boolean; + MVP_PLUS: boolean; + constructor(data: Record, date: string) { + this.date = date; + this.REGULAR = data?.REGULAR || data?.NORMAL || false; + this.VIP = data?.VIP || false; + this.VIP_PLUS = data?.VIP_PLUS || false; + this.MVP = data?.MVP || false; + this.MVP_PLUS = data?.MVP_PLUS || false; + } +} + +export default PlayerRewardsMonthlyCrate; diff --git a/src/Structures/Player/PlayerScorpiusBribe.test.ts b/src/Structures/Player/PlayerScorpiusBribe.test.ts new file mode 100644 index 000000000..1b41a56d9 --- /dev/null +++ b/src/Structures/Player/PlayerScorpiusBribe.test.ts @@ -0,0 +1,18 @@ +import PlayerScorpiusBribe from './PlayerScorpiusBribe.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerScorpiusBribe', () => { + const data = new PlayerScorpiusBribe(0, '100'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerScorpiusBribe); + expectTypeOf(data).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expect(data.year).toBeGreaterThanOrEqual(0); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.claimedTimestamp).toBeDefined(); + expect(data.claimedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.claimedTimestamp).toEqualTypeOf(); + expect(data.claimedAt).toBeDefined(); + expect(data.claimedAt).toBeInstanceOf(Date); + expectTypeOf(data.claimedAt).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerScorpiusBribe.ts b/src/Structures/Player/PlayerScorpiusBribe.ts new file mode 100644 index 000000000..59b90c465 --- /dev/null +++ b/src/Structures/Player/PlayerScorpiusBribe.ts @@ -0,0 +1,12 @@ +class PlayerScorpiusBribe { + year: number; + claimedTimestamp: number; + claimedAt: Date; + constructor(timestamp: number, year: string) { + this.year = Number(year); + this.claimedTimestamp = timestamp; + this.claimedAt = new Date(this.claimedTimestamp); + } +} + +export default PlayerScorpiusBribe; diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.test.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.test.ts new file mode 100644 index 000000000..76d5ebb2c --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.test.ts @@ -0,0 +1,22 @@ +import PlayerSeasonalChristmasYear from './PlayerSeasonalChristmasYear.js'; +import PlayerSeasonalChristmasYearAdventRewards from './PlayerSeasonalChristmasYearAdventRewards.js'; +import PlayerSeasonalChristmasYearLeveling from './PlayerSeasonalChristmasYearLeveling.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerSeasonalChristmasYear', () => { + const data = new PlayerSeasonalChristmasYear({ stats: 'meow' }, 100); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerSeasonalChristmasYear); + expectTypeOf(data).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expect(data.year).toBeGreaterThanOrEqual(0); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.adventRewards).toBeDefined(); + expect(data.adventRewards).toBeInstanceOf(PlayerSeasonalChristmasYearAdventRewards); + expectTypeOf(data.adventRewards).toEqualTypeOf(); + expect(data.presents).toBeDefined(); + expectTypeOf(data.presents).toEqualTypeOf>(); + expect(data.leveling).toBeDefined(); + expect(data.leveling).toBeInstanceOf(PlayerSeasonalChristmasYearLeveling); + expectTypeOf(data.leveling).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.ts new file mode 100644 index 000000000..6529da5d7 --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.ts @@ -0,0 +1,17 @@ +import PlayerSeasonalChristmasYearAdventRewards from './PlayerSeasonalChristmasYearAdventRewards.js'; +import PlayerSeasonalChristmasYearLeveling from './PlayerSeasonalChristmasYearLeveling.js'; + +class PlayerSeasonalChristmasYear { + year: number; + adventRewards: PlayerSeasonalChristmasYearAdventRewards; + presents: Record; + leveling: PlayerSeasonalChristmasYearLeveling; + constructor(data: Record, year: number) { + this.year = year; + this.adventRewards = new PlayerSeasonalChristmasYearAdventRewards(data?.adventRewards || {}); + this.presents = data?.presents || {}; + this.leveling = new PlayerSeasonalChristmasYearLeveling(data?.leveling || {}); + } +} + +export default PlayerSeasonalChristmasYear; diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.test.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.test.ts new file mode 100644 index 000000000..e6bca9327 --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.test.ts @@ -0,0 +1,72 @@ +import PlayerSeasonalChristmasYearAdventRewards from './PlayerSeasonalChristmasYearAdventRewards.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerSeasonalChristmasYearAdventRewards', () => { + const data = new PlayerSeasonalChristmasYearAdventRewards({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerSeasonalChristmasYearAdventRewards); + expectTypeOf(data).toEqualTypeOf(); + expect(data.day1).toBeDefined(); + expectTypeOf(data.day1).toEqualTypeOf(); + expect(data.day2).toBeDefined(); + expectTypeOf(data.day2).toEqualTypeOf(); + expect(data.day3).toBeDefined(); + expectTypeOf(data.day3).toEqualTypeOf(); + expect(data.day4).toBeDefined(); + expectTypeOf(data.day4).toEqualTypeOf(); + expect(data.day5).toBeDefined(); + expectTypeOf(data.day5).toEqualTypeOf(); + expect(data.day6).toBeDefined(); + expectTypeOf(data.day6).toEqualTypeOf(); + expect(data.day7).toBeDefined(); + expectTypeOf(data.day7).toEqualTypeOf(); + expect(data.day8).toBeDefined(); + expectTypeOf(data.day8).toEqualTypeOf(); + expect(data.day9).toBeDefined(); + expectTypeOf(data.day9).toEqualTypeOf(); + expect(data.day10).toBeDefined(); + expectTypeOf(data.day10).toEqualTypeOf(); + expect(data.day11).toBeDefined(); + expectTypeOf(data.day11).toEqualTypeOf(); + expect(data.day12).toBeDefined(); + expectTypeOf(data.day12).toEqualTypeOf(); + expect(data.day13).toBeDefined(); + expectTypeOf(data.day13).toEqualTypeOf(); + expect(data.day14).toBeDefined(); + expectTypeOf(data.day14).toEqualTypeOf(); + expect(data.day15).toBeDefined(); + expectTypeOf(data.day15).toEqualTypeOf(); + expect(data.day16).toBeDefined(); + expectTypeOf(data.day16).toEqualTypeOf(); + expect(data.day17).toBeDefined(); + expectTypeOf(data.day17).toEqualTypeOf(); + expect(data.day18).toBeDefined(); + expectTypeOf(data.day18).toEqualTypeOf(); + expect(data.day19).toBeDefined(); + expectTypeOf(data.day19).toEqualTypeOf(); + expect(data.day20).toBeDefined(); + expectTypeOf(data.day20).toEqualTypeOf(); + expect(data.day21).toBeDefined(); + expectTypeOf(data.day21).toEqualTypeOf(); + expect(data.day22).toBeDefined(); + expectTypeOf(data.day22).toEqualTypeOf(); + expect(data.day23).toBeDefined(); + expectTypeOf(data.day23).toEqualTypeOf(); + expect(data.day24).toBeDefined(); + expectTypeOf(data.day24).toEqualTypeOf(); + expect(data.day25).toBeDefined(); + expectTypeOf(data.day25).toEqualTypeOf(); +}); + +test('PlayerSeasonalChristmasYearAdventRewards (Valid Dates)', () => { + const input: Record = {}; + for (let i = 1; i <= 25; i++) { + input[`day${i}`] = `2025-12-${String(i).padStart(2, '0')}T00:00:00.000Z`; + } + const data = new PlayerSeasonalChristmasYearAdventRewards(input); + for (let i = 1; i <= 25; i++) { + const key = `day${i}` as keyof PlayerSeasonalChristmasYearAdventRewards; + expect(data[key]).toBeInstanceOf(Date); + expect((data[key] as Date).toISOString()).toBe(`2025-12-${String(i).padStart(2, '0')}T00:00:00.000Z`); + } +}); diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.ts new file mode 100644 index 000000000..b6834b927 --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.ts @@ -0,0 +1,56 @@ +class PlayerSeasonalChristmasYearAdventRewards { + day1: Date | null; + day2: Date | null; + day3: Date | null; + day4: Date | null; + day5: Date | null; + day6: Date | null; + day7: Date | null; + day8: Date | null; + day9: Date | null; + day10: Date | null; + day11: Date | null; + day12: Date | null; + day13: Date | null; + day14: Date | null; + day15: Date | null; + day16: Date | null; + day17: Date | null; + day18: Date | null; + day19: Date | null; + day20: Date | null; + day21: Date | null; + day22: Date | null; + day23: Date | null; + day24: Date | null; + day25: Date | null; + constructor(data: Record) { + this.day1 = data.day1 ? new Date(data?.day1) : null; + this.day2 = data.day2 ? new Date(data?.day2) : null; + this.day3 = data.day3 ? new Date(data?.day3) : null; + this.day4 = data.day4 ? new Date(data?.day4) : null; + this.day5 = data.day5 ? new Date(data?.day5) : null; + this.day6 = data.day6 ? new Date(data?.day6) : null; + this.day7 = data.day7 ? new Date(data?.day7) : null; + this.day8 = data.day8 ? new Date(data?.day8) : null; + this.day9 = data.day9 ? new Date(data?.day9) : null; + this.day10 = data.day10 ? new Date(data?.day10) : null; + this.day11 = data.day11 ? new Date(data?.day11) : null; + this.day12 = data.day12 ? new Date(data?.day12) : null; + this.day13 = data.day13 ? new Date(data?.day13) : null; + this.day14 = data.day14 ? new Date(data?.day14) : null; + this.day15 = data.day15 ? new Date(data?.day15) : null; + this.day16 = data.day16 ? new Date(data?.day16) : null; + this.day17 = data.day17 ? new Date(data?.day17) : null; + this.day18 = data.day18 ? new Date(data?.day18) : null; + this.day19 = data.day19 ? new Date(data?.day19) : null; + this.day20 = data.day20 ? new Date(data?.day20) : null; + this.day21 = data.day21 ? new Date(data?.day21) : null; + this.day22 = data.day22 ? new Date(data?.day22) : null; + this.day23 = data.day23 ? new Date(data?.day23) : null; + this.day24 = data.day24 ? new Date(data?.day24) : null; + this.day25 = data.day25 ? new Date(data?.day25) : null; + } +} + +export default PlayerSeasonalChristmasYearAdventRewards; diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.test.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.test.ts new file mode 100644 index 000000000..d5b4513f1 --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.test.ts @@ -0,0 +1,12 @@ +import PlayerSeasonalChristmasYearLeveling from './PlayerSeasonalChristmasYearLeveling.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerSeasonalChristmasYearLeveling', () => { + const data = new PlayerSeasonalChristmasYearLeveling({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerSeasonalChristmasYearLeveling); + expectTypeOf(data).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experience).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.ts b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.ts new file mode 100644 index 000000000..e0f4cc61c --- /dev/null +++ b/src/Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.ts @@ -0,0 +1,8 @@ +class PlayerSeasonalChristmasYearLeveling { + experience: number; + constructor(data: Record) { + this.experience = data?.experience || 0; + } +} + +export default PlayerSeasonalChristmasYearLeveling; diff --git a/src/Structures/Player/PlayerSocialMedia.test.ts b/src/Structures/Player/PlayerSocialMedia.test.ts new file mode 100644 index 000000000..aa031c5c9 --- /dev/null +++ b/src/Structures/Player/PlayerSocialMedia.test.ts @@ -0,0 +1,24 @@ +import PlayerSocialMedia from './PlayerSocialMedia.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UserInput } from '../../Types/Global.js'; + +test('PlayerSocialMedia', () => { + const data = new PlayerSocialMedia({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerSocialMedia); + expectTypeOf(data).toEqualTypeOf(); + expect(data.discord).toBeDefined(); + expectTypeOf(data.discord).toEqualTypeOf(); + expect(data.youtube).toBeDefined(); + expectTypeOf(data.youtube).toEqualTypeOf(); + expect(data.twitch).toBeDefined(); + expectTypeOf(data.twitch).toEqualTypeOf(); + expect(data.hypixel).toBeDefined(); + expectTypeOf(data.hypixel).toEqualTypeOf(); + expect(data.twitter).toBeDefined(); + expectTypeOf(data.twitter).toEqualTypeOf(); + expect(data.instagram).toBeDefined(); + expectTypeOf(data.instagram).toEqualTypeOf(); + expect(data.tiktok).toBeDefined(); + expectTypeOf(data.tiktok).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerSocialMedia.ts b/src/Structures/Player/PlayerSocialMedia.ts new file mode 100644 index 000000000..129c40668 --- /dev/null +++ b/src/Structures/Player/PlayerSocialMedia.ts @@ -0,0 +1,22 @@ +import type { UserInput } from '../../Types/Global.js'; + +class PlayerSocialMedia { + discord: UserInput | null; + youtube: UserInput | null; + twitch: UserInput | null; + hypixel: UserInput | null; + twitter: UserInput | null; + instagram: UserInput | null; + tiktok: UserInput | null; + constructor(data: Record) { + this.discord = data?.DISCORD || null; + this.youtube = data?.YOUTUBE || null; + this.twitch = data?.TWITCH || null; + this.hypixel = data?.HYPIXEL || null; + this.twitter = data?.TWITTER || null; + this.instagram = data?.INSTAGRAM || null; + this.tiktok = data?.TIKTOK || null; + } +} + +export default PlayerSocialMedia; diff --git a/src/Structures/Player/PlayerStats.test.ts b/src/Structures/Player/PlayerStats.test.ts new file mode 100644 index 000000000..2bbf1b800 --- /dev/null +++ b/src/Structures/Player/PlayerStats.test.ts @@ -0,0 +1,97 @@ +import Arcade from '../MiniGames/Arcade/Arcade.js'; +import ArenaBrawl from '../MiniGames/ArenaBrawl/ArenaBrawl.js'; +import BedWars from '../MiniGames/BedWars/BedWars.js'; +import BlitzSurvivalGames from '../MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.js'; +import BuildBattle from '../MiniGames/BuildBattle/BuildBattle.js'; +import CopsAndCrims from '../MiniGames/CopsAndCrims/CopsAndCrims.js'; +import Duels from '../MiniGames/Duels/Duels.js'; +import MegaWalls from '../MiniGames/MegaWalls/MegaWalls.js'; +import MurderMystery from '../MiniGames/MurderMystery/MurderMystery.js'; +import Paintball from '../MiniGames/Paintball.js'; +import Pit from '../MiniGames/Pit/Pit.js'; +import PlayerStats from './PlayerStats.js'; +import Quakecraft from '../MiniGames/Quakecraft/Quakecraft.js'; +import SkyWars from '../MiniGames/SkyWars/SkyWars.js'; +import SmashHeroes from '../MiniGames/SmashHeroes/SmashHeroes.js'; +import SpeedUHC from '../MiniGames/SpeedUHC/SpeedUHC.js'; +import TNTGames from '../MiniGames/TNTGames/TNTGames.js'; +import TurboKartRacers from '../MiniGames/TurboKartRacers/TurboKartRacers.js'; +import UHC from '../MiniGames/UHC/UHC.js'; +import VampireZ from '../MiniGames/VampireZ/VampireZ.js'; +import Walls from '../MiniGames/Walls.js'; +import Warlords from '../MiniGames/Warlords/Warlords.js'; +import WoolGames from '../MiniGames/WoolGames/WoolGames.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerStats', () => { + const data = new PlayerStats({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.Arcade).toBeDefined(); + expect(data.Arcade).toBeInstanceOf(Arcade); + expectTypeOf(data.Arcade).toEqualTypeOf(); + expect(data.ArenaBrawl).toBeDefined(); + expect(data.ArenaBrawl).toBeInstanceOf(ArenaBrawl); + expectTypeOf(data.ArenaBrawl).toEqualTypeOf(); + expect(data.BedWars).toBeDefined(); + expect(data.BedWars).toBeInstanceOf(BedWars); + expectTypeOf(data.BedWars).toEqualTypeOf(); + expect(data.BlitzSurvivalGames).toBeDefined(); + expect(data.BlitzSurvivalGames).toBeInstanceOf(BlitzSurvivalGames); + expectTypeOf(data.BlitzSurvivalGames).toEqualTypeOf(); + expect(data.BuildBattle).toBeDefined(); + expect(data.BuildBattle).toBeInstanceOf(BuildBattle); + expectTypeOf(data.BuildBattle).toEqualTypeOf(); + expect(data.CopsAndCrims).toBeDefined(); + expect(data.CopsAndCrims).toBeInstanceOf(CopsAndCrims); + expectTypeOf(data.CopsAndCrims).toEqualTypeOf(); + expect(data.Duels).toBeDefined(); + expect(data.Duels).toBeInstanceOf(Duels); + expectTypeOf(data.Duels).toEqualTypeOf(); + expect(data.MegaWalls).toBeDefined(); + expect(data.MegaWalls).toBeInstanceOf(MegaWalls); + expectTypeOf(data.MegaWalls).toEqualTypeOf(); + expect(data.MurderMystery).toBeDefined(); + expect(data.MurderMystery).toBeInstanceOf(MurderMystery); + expectTypeOf(data.MurderMystery).toEqualTypeOf(); + expect(data.Paintball).toBeDefined(); + expect(data.Paintball).toBeInstanceOf(Paintball); + expectTypeOf(data.Paintball).toEqualTypeOf(); + expect(data.Pit).toBeDefined(); + expect(data.Pit).toBeInstanceOf(Pit); + expectTypeOf(data.Pit).toEqualTypeOf(); + expect(data.QuakeCraft).toBeDefined(); + expect(data.QuakeCraft).toBeInstanceOf(Quakecraft); + expectTypeOf(data.QuakeCraft).toEqualTypeOf(); + expect(data.SkyWars).toBeDefined(); + expect(data.SkyWars).toBeInstanceOf(SkyWars); + expectTypeOf(data.SkyWars).toEqualTypeOf(); + expect(data.SmashHeroes).toBeDefined(); + expect(data.SmashHeroes).toBeInstanceOf(SmashHeroes); + expectTypeOf(data.SmashHeroes).toEqualTypeOf(); + expect(data.SpeedUHC).toBeDefined(); + expect(data.SpeedUHC).toBeInstanceOf(SpeedUHC); + expectTypeOf(data.SpeedUHC).toEqualTypeOf(); + expect(data.TNTGames).toBeDefined(); + expect(data.TNTGames).toBeInstanceOf(TNTGames); + expectTypeOf(data.TNTGames).toEqualTypeOf(); + expect(data.TurboKartRacers).toBeDefined(); + expect(data.TurboKartRacers).toBeInstanceOf(TurboKartRacers); + expectTypeOf(data.TurboKartRacers).toEqualTypeOf(); + expect(data.UHC).toBeDefined(); + expect(data.UHC).toBeInstanceOf(UHC); + expectTypeOf(data.UHC).toEqualTypeOf(); + expect(data.VampireZ).toBeDefined(); + expect(data.VampireZ).toBeInstanceOf(VampireZ); + expectTypeOf(data.VampireZ).toEqualTypeOf(); + expect(data.Walls).toBeDefined(); + expect(data.Walls).toBeInstanceOf(Walls); + expectTypeOf(data.Walls).toEqualTypeOf(); + expect(data.Warlords).toBeDefined(); + expect(data.Warlords).toBeInstanceOf(Warlords); + expectTypeOf(data.Warlords).toEqualTypeOf(); + expect(data.WoolGames).toBeDefined(); + expect(data.WoolGames).toBeInstanceOf(WoolGames); + expectTypeOf(data.WoolGames).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerStats.ts b/src/Structures/Player/PlayerStats.ts new file mode 100644 index 000000000..4cce0ca06 --- /dev/null +++ b/src/Structures/Player/PlayerStats.ts @@ -0,0 +1,73 @@ +import Arcade from '../MiniGames/Arcade/Arcade.js'; +import ArenaBrawl from '../MiniGames/ArenaBrawl/ArenaBrawl.js'; +import BedWars from '../MiniGames/BedWars/BedWars.js'; +import BlitzSurvivalGames from '../MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.js'; +import BuildBattle from '../MiniGames/BuildBattle/BuildBattle.js'; +import CopsAndCrims from '../MiniGames/CopsAndCrims/CopsAndCrims.js'; +import Duels from '../MiniGames/Duels/Duels.js'; +import MegaWalls from '../MiniGames/MegaWalls/MegaWalls.js'; +import MurderMystery from '../MiniGames/MurderMystery/MurderMystery.js'; +import Paintball from '../MiniGames/Paintball.js'; +import Pit from '../MiniGames/Pit/Pit.js'; +import Quakecraft from '../MiniGames/Quakecraft/Quakecraft.js'; +import SkyWars from '../MiniGames/SkyWars/SkyWars.js'; +import SmashHeroes from '../MiniGames/SmashHeroes/SmashHeroes.js'; +import SpeedUHC from '../MiniGames/SpeedUHC/SpeedUHC.js'; +import TNTGames from '../MiniGames/TNTGames/TNTGames.js'; +import TurboKartRacers from '../MiniGames/TurboKartRacers/TurboKartRacers.js'; +import UHC from '../MiniGames/UHC/UHC.js'; +import VampireZ from '../MiniGames/VampireZ/VampireZ.js'; +import Walls from '../MiniGames/Walls.js'; +import Warlords from '../MiniGames/Warlords/Warlords.js'; +import WoolGames from '../MiniGames/WoolGames/WoolGames.js'; + +class PlayerStats { + Arcade: Arcade; + ArenaBrawl: ArenaBrawl; + BedWars: BedWars; + BlitzSurvivalGames: BlitzSurvivalGames; + BuildBattle: BuildBattle; + CopsAndCrims: CopsAndCrims; + Duels: Duels; + MegaWalls: MegaWalls; + MurderMystery: MurderMystery; + Paintball: Paintball; + Pit: Pit; + QuakeCraft: Quakecraft; + SkyWars: SkyWars; + SmashHeroes: SmashHeroes; + SpeedUHC: SpeedUHC; + TNTGames: TNTGames; + TurboKartRacers: TurboKartRacers; + UHC: UHC; + VampireZ: VampireZ; + Walls: Walls; + Warlords: Warlords; + WoolGames: WoolGames; + constructor(data: Record) { + this.Arcade = new Arcade(data?.Arcade); + this.ArenaBrawl = new ArenaBrawl(data?.Arena); + this.BedWars = new BedWars(data?.Bedwars); + this.BlitzSurvivalGames = new BlitzSurvivalGames(data?.HungerGames); + this.BuildBattle = new BuildBattle(data?.BuildBattle); + this.CopsAndCrims = new CopsAndCrims(data?.MCGO); + this.Duels = new Duels(data?.Duels); + this.MegaWalls = new MegaWalls(data?.Walls3); + this.MurderMystery = new MurderMystery(data?.MurderMystery); + this.Paintball = new Paintball(data?.Paintball); + this.Pit = new Pit(data?.Pit); + this.QuakeCraft = new Quakecraft(data?.Quake); + this.SkyWars = new SkyWars(data?.SkyWars); + this.SmashHeroes = new SmashHeroes(data?.SuperSmash); + this.SpeedUHC = new SpeedUHC(data?.SpeedUHC); + this.TNTGames = new TNTGames(data?.TNTGames); + this.TurboKartRacers = new TurboKartRacers(data?.GingerBread); + this.UHC = new UHC(data?.UHC); + this.VampireZ = new VampireZ(data?.VampireZ); + this.Walls = new Walls(data?.Walls); + this.Warlords = new Warlords(data?.Battleground); + this.WoolGames = new WoolGames(data?.WoolGames); + } +} + +export default PlayerStats; diff --git a/src/Structures/Player/PlayerTourney/PlayerTourney.test.ts b/src/Structures/Player/PlayerTourney/PlayerTourney.test.ts new file mode 100644 index 000000000..c73da7669 --- /dev/null +++ b/src/Structures/Player/PlayerTourney/PlayerTourney.test.ts @@ -0,0 +1,24 @@ +import PlayerTourney from './PlayerTourney.js'; +import PlayerTourneyData from './PlayerTourneyData.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { PlayerTourneyShopSort } from '../../../Types/Player.js'; + +test('PlayerTourney', () => { + const data = new PlayerTourney({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerTourney); + expectTypeOf(data).toEqualTypeOf(); + expect(data.firstJoinLobbyTimestamp).toBeDefined(); + expectTypeOf(data.firstJoinLobbyTimestamp).toEqualTypeOf(); + expect(data.firstJoinLobbyAt).toBeDefined(); + expectTypeOf(data.firstJoinLobbyAt).toEqualTypeOf(); + expect(data.totalTributes).toBeDefined(); + expect(data.totalTributes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalTributes).toEqualTypeOf(); + expect(data.shopSort).toBeDefined(); + expectTypeOf(data.shopSort).toEqualTypeOf(); + expect(data.hidePurchased).toBeDefined(); + expectTypeOf(data.hidePurchased).toEqualTypeOf(); + expect(data.tourneyData).toBeDefined(); + expectTypeOf(data.tourneyData).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerTourney/PlayerTourney.ts b/src/Structures/Player/PlayerTourney/PlayerTourney.ts new file mode 100644 index 000000000..fd632a97a --- /dev/null +++ b/src/Structures/Player/PlayerTourney/PlayerTourney.ts @@ -0,0 +1,24 @@ +import PlayerTourneyData from './PlayerTourneyData.js'; +import type { PlayerTourneyShopSort } from '../../../Types/Player.js'; + +class PlayerTourney { + firstJoinLobbyTimestamp: number | null; + firstJoinLobbyAt: Date | null; + totalTributes: number; + shopSort: PlayerTourneyShopSort | 'UNKNOWN'; + hidePurchased: boolean; + tourneyData: PlayerTourneyData[]; + constructor(data: Record) { + this.firstJoinLobbyTimestamp = data?.first_join_lobby || null; + this.firstJoinLobbyAt = this.firstJoinLobbyTimestamp ? new Date(this.firstJoinLobbyTimestamp) : null; + this.totalTributes = data?.total_tributes || 0; + this.shopSort = data?.shop_sort || 'UNKNOWN'; + this.hidePurchased = data?.hide_purchased || false; + this.tourneyData = []; + Object.keys(data) + .filter((key) => ['first_join_lobby', 'total_tributes', 'shop_sort', 'hide_purchased'].includes(key)) + .forEach((key) => this.tourneyData.push(new PlayerTourneyData(data[key], key))); + } +} + +export default PlayerTourney; diff --git a/src/Structures/Player/PlayerTourney/PlayerTourneyData.test.ts b/src/Structures/Player/PlayerTourney/PlayerTourneyData.test.ts new file mode 100644 index 000000000..c02ed218c --- /dev/null +++ b/src/Structures/Player/PlayerTourney/PlayerTourneyData.test.ts @@ -0,0 +1,24 @@ +import PlayerTourneyData from './PlayerTourneyData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('PlayerTourneyData', () => { + const data = new PlayerTourneyData({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(PlayerTourneyData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tourneyName).toBeDefined(); + expectTypeOf(data.tourneyName).toEqualTypeOf(); + expect(data.playtime).toBeDefined(); + expect(data.playtime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playtime).toEqualTypeOf(); + expect(data.tributes).toBeDefined(); + expect(data.tributes).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tributes).toEqualTypeOf(); + expect(data.firstWinTimestamp).toBeDefined(); + expectTypeOf(data.firstWinTimestamp).toEqualTypeOf(); + expect(data.firstWinAt).toBeDefined(); + expectTypeOf(data.firstWinAt).toEqualTypeOf(); + expect(data.claimedReward).toBeDefined(); + expect(data.claimedReward).toBeGreaterThanOrEqual(0); + expectTypeOf(data.claimedReward).toEqualTypeOf(); +}); diff --git a/src/Structures/Player/PlayerTourney/PlayerTourneyData.ts b/src/Structures/Player/PlayerTourney/PlayerTourneyData.ts new file mode 100644 index 000000000..a7cd2e634 --- /dev/null +++ b/src/Structures/Player/PlayerTourney/PlayerTourneyData.ts @@ -0,0 +1,18 @@ +class PlayerTourneyData { + tourneyName: string; + playtime: number; + tributes: number; + firstWinTimestamp: number | null; + firstWinAt: Date | null; + claimedReward: number; + constructor(data: Record, tourneyName: string) { + this.tourneyName = tourneyName; + this.playtime = data?.playtime || 0; + this.tributes = data?.tributes_earned || 0; + this.firstWinTimestamp = data?.first_win || null; + this.firstWinAt = this.firstWinTimestamp ? new Date(this.firstWinTimestamp) : null; + this.claimedReward = data?.claimed_ranking_reward || 0; + } +} + +export default PlayerTourneyData; diff --git a/src/Structures/RecentGame.test.ts b/src/Structures/RecentGame.test.ts new file mode 100644 index 000000000..8760b0f1e --- /dev/null +++ b/src/Structures/RecentGame.test.ts @@ -0,0 +1,31 @@ +import Game from './Game.js'; +import RecentGame from './RecentGame.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('RecentGame', () => { + const data = new RecentGame({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RecentGame); + expectTypeOf(data).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.dateTimestamp).toBeDefined(); + expectTypeOf(data.dateTimestamp).toEqualTypeOf(); + expect(data.dateAt).toBeDefined(); + expectTypeOf(data.dateAt).toEqualTypeOf(); + expect(data.mode).toBeDefined(); + expectTypeOf(data.mode).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.ongoing).toBeDefined(); + expectTypeOf(data.ongoing).toEqualTypeOf(); + expect(data.endedTimestamp).toBeDefined(); + expectTypeOf(data.endedTimestamp).toEqualTypeOf(); + expect(data.endedAt).toBeDefined(); + expectTypeOf(data.endedAt).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string | null>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.mode); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/RecentGame.ts b/src/Structures/RecentGame.ts new file mode 100644 index 000000000..671b994fe --- /dev/null +++ b/src/Structures/RecentGame.ts @@ -0,0 +1,33 @@ +import Game from './Game.js'; +import type RequestData from '../Private/RequestData.js'; + +class RecentGame { + game: Game | null; + dateTimestamp: number | null; + dateAt: Date | null; + mode: string | null; + map: string | null; + ongoing: boolean; + endedTimestamp: number | null; + endedAt: Date | null; + constructor(data: Record) { + this.game = data?.gameType ? new Game(data.gameType) : null; + this.dateTimestamp = data?.date || null; + this.dateAt = this.dateTimestamp ? new Date(this.dateTimestamp) : null; + this.mode = data?.mode || null; + this.map = data?.map || null; + this.ongoing = Boolean(!data?.ended || 0) || false; + this.endedTimestamp = data?.ended ? data?.ended : null; + this.endedAt = this.endedTimestamp ? new Date(this.endedTimestamp) : null; + } + + toString(): string | null { + return this.mode; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default RecentGame; diff --git a/src/Structures/RecentGames.test.ts b/src/Structures/RecentGames.test.ts new file mode 100644 index 000000000..37e68e849 --- /dev/null +++ b/src/Structures/RecentGames.test.ts @@ -0,0 +1,29 @@ +import Game from './Game.js'; +import RecentGame from './RecentGame.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('RecentGame', () => { + const data = new RecentGame({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(RecentGame); + expectTypeOf(data).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.dateTimestamp).toBeDefined(); + expectTypeOf(data.dateTimestamp).toEqualTypeOf(); + expect(data.dateAt).toBeDefined(); + expectTypeOf(data.dateAt).toEqualTypeOf(); + expect(data.mode).toBeDefined(); + expectTypeOf(data.mode).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.ongoing).toBeDefined(); + expectTypeOf(data.ongoing).toEqualTypeOf(); + expect(data.endedTimestamp).toBeDefined(); + expectTypeOf(data.endedTimestamp).toEqualTypeOf(); + expect(data.endedAt).toBeDefined(); + expectTypeOf(data.endedAt).toEqualTypeOf(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toEqual(data.mode); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuction.test.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuction.test.ts new file mode 100644 index 000000000..204890ea0 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuction.test.ts @@ -0,0 +1,47 @@ +import SkyBlockAuction from './SkyBlockAuction.js'; +import SkyBlockAuctionBid from './SkyBlockAuctionBid.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { Rarity } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +test('SkyBlockAuction', () => { + const data = new SkyBlockAuction({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockAuction); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coop).toBeDefined(); + expectTypeOf(data.coop).toEqualTypeOf(); + expect(data.auctionStartTimestamp).toBeDefined(); + expect(data.auctionStartTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.auctionStartTimestamp).toEqualTypeOf(); + expect(data.auctionStartAt).toBeDefined(); + expect(data.auctionStartAt).toBeInstanceOf(Date); + expectTypeOf(data.auctionStartAt).toEqualTypeOf(); + expect(data.auctionEndTimestamp).toBeDefined(); + expectTypeOf(data.auctionEndTimestamp).toEqualTypeOf(); + expect(data.auctionEndAt).toBeDefined(); + expectTypeOf(data.auctionEndAt).toEqualTypeOf(); + expect(data.item).toBeDefined(); + expectTypeOf(data.item).toEqualTypeOf(); + expect(data.itemLore).toBeDefined(); + expectTypeOf(data.itemLore).toEqualTypeOf(); + expect(data.rarity).toBeDefined(); + expectTypeOf(data.rarity).toEqualTypeOf(); + expect(data.startingBid).toBeDefined(); + expect(data.startingBid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startingBid).toEqualTypeOf(); + expect(data.highestBid).toBeDefined(); + expect(data.highestBid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestBid).toEqualTypeOf(); + expect(data.bids).toBeDefined(); + expectTypeOf(data.bids).toEqualTypeOf(); + expect(data.claimed).toBeDefined(); + expectTypeOf(data.claimed).toEqualTypeOf(); + expect(data.claimedBidders).toBeDefined(); + expectTypeOf(data.claimedBidders).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.item); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuction.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuction.ts new file mode 100644 index 000000000..99b0c8f11 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuction.ts @@ -0,0 +1,42 @@ +import SkyBlockAuctionBid from './SkyBlockAuctionBid.js'; +import SkyBlockBaseAuction from './SkyBlockBaseAuction.js'; +import type { Rarity } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockAuction extends SkyBlockBaseAuction { + coop: UUID[]; + auctionStartTimestamp: number; + auctionStartAt: Date; + auctionEndTimestamp: number | null; + auctionEndAt: Date | null; + item: string; + itemLore: string; + rarity: Rarity | 'UNKNOWN'; + startingBid: number; + highestBid: number; + bids: SkyBlockAuctionBid[]; + claimed: boolean; + claimedBidders: string[]; + constructor(data: Record, includeItemBytes: boolean = false) { + super(data, includeItemBytes); + this.coop = data?.coop || []; + this.auctionStartTimestamp = data?.start || 0; + this.auctionStartAt = new Date(this.auctionStartTimestamp); + this.auctionEndTimestamp = data.end || null; + this.auctionEndAt = this.auctionEndTimestamp ? new Date(this.auctionEndTimestamp) : null; + this.item = data?.item_name || 'UNKNOWN'; + this.itemLore = data?.item_lore || 'UNKNOWN'; + this.rarity = data?.tier || 'UNKNOWN'; + this.startingBid = data?.starting_bid || 0; + this.highestBid = this.bin ? data.starting_bid : data.highest_bid_amount || 0; + this.bids = (data?.bids || []).map((bid: any) => new SkyBlockAuctionBid(bid)); + this.claimed = data.claimed || false; + this.claimedBidders = this.claimed ? data.claimed_bidders : []; + } + + override toString(): string { + return this.item; + } +} + +export default SkyBlockAuction; diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.test.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.test.ts new file mode 100644 index 000000000..3f4291dc4 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.test.ts @@ -0,0 +1,30 @@ +import SkyBlockAuctionBid from './SkyBlockAuctionBid.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UUID } from '../../../Types/Global.js'; + +test('SkyBlockAuctionBid', () => { + const data = new SkyBlockAuctionBid({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockAuctionBid); + expectTypeOf(data).toEqualTypeOf(); + expect(data.auctionId).toBeDefined(); + expectTypeOf(data.auctionId).toEqualTypeOf(); + expect(data.profileId).toBeDefined(); + expectTypeOf(data.profileId).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expect(data.timestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.at).toBeDefined(); + expect(data.at).toBeInstanceOf(Date); + expectTypeOf(data.at).toEqualTypeOf(); + expect(data.bidder).toBeDefined(); + expectTypeOf(data.bidder).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.amount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.ts new file mode 100644 index 000000000..bae501858 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionBid.ts @@ -0,0 +1,24 @@ +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockAuctionBid { + auctionId: UUID | 'UNKNOWN'; + profileId: UUID | 'UNKNOWN'; + amount: number; + timestamp: number; + at: Date; + bidder: string; + constructor(data: Record) { + this.auctionId = data?.auction_id || 'UNKNOWN'; + this.profileId = data?.profile_id || 'UNKNOWN'; + this.amount = data?.amount || 0; + this.timestamp = data?.timestamp || 0; + this.at = new Date(this.timestamp); + this.bidder = data?.bidder || 'UNKNOWN'; + } + + toString(): number { + return this.amount; + } +} + +export default SkyBlockAuctionBid; diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.test.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.test.ts new file mode 100644 index 000000000..7d011d277 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.test.ts @@ -0,0 +1,18 @@ +import SkyBlockAuctionInfo from './SkyBlockAuctionInfo.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockAuctionInfo', () => { + const data = new SkyBlockAuctionInfo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockAuctionInfo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.page).toBeDefined(); + expect(data.page).toBeGreaterThanOrEqual(0); + expectTypeOf(data.page).toEqualTypeOf(); + expect(data.totalPages).toBeDefined(); + expect(data.totalPages).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalPages).toEqualTypeOf(); + expect(data.totalAuctions).toBeDefined(); + expect(data.totalAuctions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalAuctions).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.ts b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.ts new file mode 100644 index 000000000..68ac01ee8 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.ts @@ -0,0 +1,15 @@ +import SkyBlockBaseAuctionInfo from './SkyBlockBaseAuctionInfo.js'; + +class SkyBlockAuctionInfo extends SkyBlockBaseAuctionInfo { + page: number; + totalPages: number; + totalAuctions: number; + constructor(data: Record) { + super(data); + this.page = data?.page || 0; + this.totalPages = data?.totalPages || 0; + this.totalAuctions = data?.totalAuctions || 0; + } +} + +export default SkyBlockAuctionInfo; diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.test.ts b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.test.ts new file mode 100644 index 000000000..1b5baba4f --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.test.ts @@ -0,0 +1,25 @@ +import ItemBytes from '../../ItemBytes.js'; +import SkyBlockBaseAuction from './SkyBlockBaseAuction.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockBaseAuction', () => { + const data = new SkyBlockBaseAuction({ stats: 'meow' }, false); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBaseAuction); + expectTypeOf(data).toEqualTypeOf(); + expect(data.auctionId).toBeDefined(); + expectTypeOf(data.auctionId).toEqualTypeOf(); + expect(data.auctioneerUuid).toBeDefined(); + expectTypeOf(data.auctioneerUuid).toEqualTypeOf(); + expect(data.auctioneerProfile).toBeDefined(); + expectTypeOf(data.auctioneerProfile).toEqualTypeOf(); + expect(data.bin).toBeDefined(); + expectTypeOf(data.bin).toEqualTypeOf(); + expect(data.itemBytes).toBeDefined(); + expectTypeOf(data.itemBytes).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.auctionId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.ts b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.ts new file mode 100644 index 000000000..d33a292ad --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuction.ts @@ -0,0 +1,22 @@ +import ItemBytes from '../../ItemBytes.js'; + +class SkyBlockBaseAuction { + auctionId: string; + auctioneerUuid: string; + auctioneerProfile: string; + bin: boolean; + itemBytes: ItemBytes | null; + constructor(data: Record, includeItemBytes: boolean) { + this.auctionId = data.uuid || data.auction_id || 'UNKNOWN'; + this.auctioneerUuid = data.auctioneer || data.seller || 'UNKNOWN'; + this.auctioneerProfile = data.profile_id || data.seller_profile || 'UNKNOWN'; + this.bin = data?.bin || false; + this.itemBytes = includeItemBytes ? new ItemBytes(data.item_bytes || 'UNKNOWN') : null; + } + + toString(): string { + return this.auctionId; + } +} + +export default SkyBlockBaseAuction; diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.test.ts b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.test.ts new file mode 100644 index 000000000..e814611f5 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.test.ts @@ -0,0 +1,15 @@ +import SkyBlockBaseAuctionInfo from './SkyBlockBaseAuctionInfo.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockBaseAuctionInfo', () => { + const data = new SkyBlockBaseAuctionInfo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBaseAuctionInfo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.ts b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.ts new file mode 100644 index 000000000..bb71ec3d1 --- /dev/null +++ b/src/Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.ts @@ -0,0 +1,10 @@ +class SkyBlockBaseAuctionInfo { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + constructor(data: Record) { + this.lastUpdatedTimestamp = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + } +} + +export default SkyBlockBaseAuctionInfo; diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.test.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.test.ts new file mode 100644 index 000000000..4b5a9fe22 --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.test.ts @@ -0,0 +1,18 @@ +import SkyBlockBazaar from './SkyBlockBazaar.js'; +import SkyBlockBazaarProduct from './SkyBlockBazaarProduct.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockBazaar', () => { + const data = new SkyBlockBazaar({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBazaar); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdated).toBeDefined(); + expect(data.lastUpdated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.products).toBeDefined(); + expectTypeOf(data.products).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.ts new file mode 100644 index 000000000..172d10dfd --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaar.ts @@ -0,0 +1,20 @@ +import SkyBlockBazaarProduct from './SkyBlockBazaarProduct.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockBazaar { + lastUpdated: number; + lastUpdatedAt: Date; + products: SkyBlockBazaarProduct[]; + constructor(data: Record) { + this.lastUpdated = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdated); + const products = data?.products || {}; + this.products = Object.keys(products).map((product) => new SkyBlockBazaarProduct(products[product])); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockBazaar; diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.test.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.test.ts new file mode 100644 index 000000000..faadac7a2 --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.test.ts @@ -0,0 +1,26 @@ +import SkyBlockBazaarProduct from './SkyBlockBazaarProduct.js'; +import SkyBlockBazaarProductOrder from './SkyBlockBazaarProductOrder.js'; +import SkyBlockBazaarQuickStatus from './SkyBlockBazaarQuickStatus.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BazaarProduct } from '../../../Types/SkyBlock.js'; + +test('SkyBlockBazaarProduct', () => { + const data = new SkyBlockBazaarProduct({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBazaarProduct); + expectTypeOf(data).toEqualTypeOf(); + expect(data.productId).toBeDefined(); + expectTypeOf(data.productId).toEqualTypeOf(); + expect(data.sellSummary).toBeDefined(); + expectTypeOf(data.sellSummary).toEqualTypeOf(); + expect(data.buySummary).toBeDefined(); + expectTypeOf(data.buySummary).toEqualTypeOf(); + expect(data.quickStatus).toBeDefined(); + expect(data.quickStatus).toBeInstanceOf(SkyBlockBazaarQuickStatus); + expectTypeOf(data.quickStatus).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => BazaarProduct | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.productId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.ts new file mode 100644 index 000000000..23a33d41b --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.ts @@ -0,0 +1,26 @@ +import SkyBlockBazaarProductOrder from './SkyBlockBazaarProductOrder.js'; +import SkyBlockBazaarQuickStatus from './SkyBlockBazaarQuickStatus.js'; +import type { BazaarProduct } from '../../../Types/SkyBlock.js'; + +class SkyBlockBazaarProduct { + productId: BazaarProduct | 'UNKNOWN'; + sellSummary: SkyBlockBazaarProductOrder[]; + buySummary: SkyBlockBazaarProductOrder[]; + quickStatus: SkyBlockBazaarQuickStatus; + constructor(data: Record) { + this.productId = data?.product_id || 'UNKNOWN'; + this.sellSummary = (data?.sell_summary || []).map( + (summary: Record) => new SkyBlockBazaarProductOrder(summary) + ); + this.buySummary = (data?.buy_summary || []).map( + (summary: Record) => new SkyBlockBazaarProductOrder(summary) + ); + this.quickStatus = new SkyBlockBazaarQuickStatus(data?.quick_status || {}); + } + + toString(): BazaarProduct | 'UNKNOWN' { + return this.productId; + } +} + +export default SkyBlockBazaarProduct; diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.test.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.test.ts new file mode 100644 index 000000000..93443593f --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.test.ts @@ -0,0 +1,23 @@ +import SkyBlockBazaarProductOrder from './SkyBlockBazaarProductOrder.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockBazaarProductOrder', () => { + const data = new SkyBlockBazaarProductOrder({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBazaarProductOrder); + expectTypeOf(data).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.pricePerUnit).toBeDefined(); + expect(data.pricePerUnit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pricePerUnit).toEqualTypeOf(); + expect(data.orders).toBeDefined(); + expect(data.orders).toBeGreaterThanOrEqual(0); + expectTypeOf(data.orders).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.amount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.ts new file mode 100644 index 000000000..0ed3b01be --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.ts @@ -0,0 +1,16 @@ +class SkyBlockBazaarProductOrder { + amount: number; + pricePerUnit: number; + orders: number; + constructor(data: Record) { + this.amount = data?.amount || 0; + this.pricePerUnit = data?.pricePerUnit || 0; + this.orders = data?.orders || 0; + } + + toString(): number { + return this.amount; + } +} + +export default SkyBlockBazaarProductOrder; diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.test.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.test.ts new file mode 100644 index 000000000..079f42df1 --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.test.ts @@ -0,0 +1,41 @@ +import SkyBlockBazaarQuickStatus from './SkyBlockBazaarQuickStatus.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BazaarProduct } from '../../../Types/SkyBlock.js'; + +test('SkyBlockBazaarQuickStatus', () => { + const data = new SkyBlockBazaarQuickStatus({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBazaarQuickStatus); + expectTypeOf(data).toEqualTypeOf(); + expect(data.productId).toBeDefined(); + expectTypeOf(data.productId).toEqualTypeOf(); + expect(data.sellPrice).toBeDefined(); + expect(data.sellPrice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sellPrice).toEqualTypeOf(); + expect(data.sellVolume).toBeDefined(); + expect(data.sellVolume).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sellVolume).toEqualTypeOf(); + expect(data.sellMovingWeek).toBeDefined(); + expect(data.sellMovingWeek).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sellMovingWeek).toEqualTypeOf(); + expect(data.sellOrders).toBeDefined(); + expect(data.sellOrders).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sellOrders).toEqualTypeOf(); + expect(data.buyPrice).toBeDefined(); + expect(data.buyPrice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.buyPrice).toEqualTypeOf(); + expect(data.buyVolume).toBeDefined(); + expect(data.buyVolume).toBeGreaterThanOrEqual(0); + expectTypeOf(data.buyVolume).toEqualTypeOf(); + expect(data.buyMovingWeek).toBeDefined(); + expect(data.buyMovingWeek).toBeGreaterThanOrEqual(0); + expectTypeOf(data.buyMovingWeek).toEqualTypeOf(); + expect(data.buyOrders).toBeDefined(); + expect(data.buyOrders).toBeGreaterThanOrEqual(0); + expectTypeOf(data.buyOrders).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => BazaarProduct | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.productId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.ts b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.ts new file mode 100644 index 000000000..afa8ae384 --- /dev/null +++ b/src/Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.ts @@ -0,0 +1,30 @@ +import type { BazaarProduct } from '../../../Types/SkyBlock.js'; + +class SkyBlockBazaarQuickStatus { + productId: BazaarProduct | 'UNKNOWN'; + sellPrice: number; + sellVolume: number; + sellMovingWeek: number; + sellOrders: number; + buyPrice: number; + buyVolume: number; + buyMovingWeek: number; + buyOrders: number; + constructor(data: Record) { + this.productId = data?.productId || 'UNKNOWN'; + this.sellPrice = data?.sellPrice || 0; + this.sellVolume = data?.sellVolume || 0; + this.sellMovingWeek = data?.sellMovingWeek || 0; + this.sellOrders = data?.sellOrders || 0; + this.buyPrice = data?.buyPrice || 0; + this.buyVolume = data?.buyVolume || 0; + this.buyMovingWeek = data?.buyMovingWeek || 0; + this.buyOrders = data?.buyOrders || 0; + } + + toString(): BazaarProduct | 'UNKNOWN' { + return this.productId; + } +} + +export default SkyBlockBazaarQuickStatus; diff --git a/src/Structures/SkyBlock/Bingo/SkyBlockBingo.test.ts b/src/Structures/SkyBlock/Bingo/SkyBlockBingo.test.ts new file mode 100644 index 000000000..aacc52fa5 --- /dev/null +++ b/src/Structures/SkyBlock/Bingo/SkyBlockBingo.test.ts @@ -0,0 +1,39 @@ +import SkyBlockBingo from './SkyBlockBingo.js'; +import SkyBlockBingoGoal from './SkyBlockBingoGoal.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockBingo', () => { + const data = new SkyBlockBingo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBingo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.start).toBeDefined(); + expect(data.start).toBeGreaterThanOrEqual(0); + expectTypeOf(data.start).toEqualTypeOf(); + expect(data.startAt).toBeDefined(); + expect(data.startAt).toBeInstanceOf(Date); + expectTypeOf(data.startAt).toEqualTypeOf(); + expect(data.end).toBeDefined(); + expect(data.end).toBeGreaterThanOrEqual(0); + expectTypeOf(data.end).toEqualTypeOf(); + expect(data.endAt).toBeDefined(); + expect(data.endAt).toBeInstanceOf(Date); + expectTypeOf(data.endAt).toEqualTypeOf(); + expect(data.goals).toBeDefined(); + expectTypeOf(data.goals).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number | null>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.id); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bingo/SkyBlockBingo.ts b/src/Structures/SkyBlock/Bingo/SkyBlockBingo.ts new file mode 100644 index 000000000..c1a3b2305 --- /dev/null +++ b/src/Structures/SkyBlock/Bingo/SkyBlockBingo.ts @@ -0,0 +1,35 @@ +import SkyBlockBingoGoal from './SkyBlockBingoGoal.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockBingo { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + id: number | null; + name: string; + start: number; + startAt: Date; + end: number; + endAt: Date; + goals: SkyBlockBingoGoal[] | null; + constructor(data: Record) { + this.lastUpdatedTimestamp = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.id = data?.id || null; + this.name = data?.name || 'UNKNOWN'; + this.start = data?.start || 0; + this.startAt = new Date(this.start); + this.end = data?.end || 0; + this.endAt = new Date(this.end); + this.goals = Array.isArray(data.goals) ? data.goals.map((goal, index) => new SkyBlockBingoGoal(goal, index)) : null; + } + + toString(): number | null { + return this.id; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockBingo; diff --git a/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.test.ts b/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.test.ts new file mode 100644 index 000000000..bb74384ec --- /dev/null +++ b/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.test.ts @@ -0,0 +1,34 @@ +import SkyBlockBingoGoal from './SkyBlockBingoGoal.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockBingoGoalType } from '../../../Types/SkyBlock.js'; + +test('SkyBlockBingoGoal', () => { + const data = new SkyBlockBingoGoal({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockBingoGoal); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.row).toBeDefined(); + expectTypeOf(data.row).toEqualTypeOf(); + expect(data.column).toBeDefined(); + expectTypeOf(data.column).toEqualTypeOf(); + expect(data.lore).toBeDefined(); + expectTypeOf(data.lore).toEqualTypeOf(); + expect(data.progress).toBeDefined(); + expect(data.progress).toBeGreaterThanOrEqual(0); + expectTypeOf(data.progress).toEqualTypeOf(); + expect(data.tiers).toBeDefined(); + expectTypeOf(data.tiers).toEqualTypeOf(); + expect(data.requiredAmount).toBeDefined(); + expectTypeOf(data.requiredAmount).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.id); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.ts b/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.ts new file mode 100644 index 000000000..d8aac7fa0 --- /dev/null +++ b/src/Structures/SkyBlock/Bingo/SkyBlockBingoGoal.ts @@ -0,0 +1,37 @@ +import type { SkyBlockBingoGoalType } from '../../../Types/SkyBlock.js'; + +function parsePosition(position: number): [number, number] { + const x = (position % 5) + 1; + const y = Math.floor(position / 5) + 1; + return [x, y]; +} + +class SkyBlockBingoGoal { + name: string; + id: string; + row: number | null; + column: number | null; + lore: string; + progress: number; + tiers: number[]; + requiredAmount: number | null; + type: SkyBlockBingoGoalType; + constructor(data: Record, position: number = 0) { + this.id = data?.id || 'UNKNOWN'; + this.name = data?.name || 'UNKNOWN'; + const [row, column] = parsePosition(position); + this.row = row; + this.column = column; + this.lore = data?.lore || 'UNKNOWN'; + this.progress = data?.progress || 0; + this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : []; + this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null; + this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME'; + } + + toString(): string { + return this.id; + } +} + +export default SkyBlockBingoGoal; diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollection.test.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollection.test.ts new file mode 100644 index 000000000..564e9a321 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollection.test.ts @@ -0,0 +1,24 @@ +import SkyBlockCollection from './SkyBlockCollection.js'; +import SkyBlockCollectionTier from './SkyBlockCollectionTier.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockCollection', () => { + const data = new SkyBlockCollection({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockCollection); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.maxTiers).toBeDefined(); + expect(data.maxTiers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxTiers).toEqualTypeOf(); + expect(data.tiers).toBeDefined(); + expectTypeOf(data.tiers).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.id); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollection.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollection.ts new file mode 100644 index 000000000..2072ae859 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollection.ts @@ -0,0 +1,20 @@ +import SkyBlockCollectionTier from './SkyBlockCollectionTier.js'; + +class SkyBlockCollection { + id: string; + name: string; + maxTiers: number; + tiers: SkyBlockCollectionTier[]; + constructor(data: Record, id: string) { + this.id = id; + this.name = data?.name || 'UNKNOWN'; + this.maxTiers = data?.maxTiers || 0; + this.tiers = (data?.tiers || []).map((tier: Record) => new SkyBlockCollectionTier(tier)); + } + + toString(): string { + return this.id; + } +} + +export default SkyBlockCollection; diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.test.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.test.ts new file mode 100644 index 000000000..6cd138dd9 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.test.ts @@ -0,0 +1,17 @@ +import SkyBlockCollectionTier from './SkyBlockCollectionTier.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockCollectionTier', () => { + const data = new SkyBlockCollectionTier({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockCollectionTier); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.amountRequired).toBeDefined(); + expect(data.amountRequired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amountRequired).toEqualTypeOf(); + expect(data.unlocks).toBeDefined(); + expectTypeOf(data.unlocks).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.ts new file mode 100644 index 000000000..d0eda1e87 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollectionTier.ts @@ -0,0 +1,12 @@ +class SkyBlockCollectionTier { + tier: number; + amountRequired: number; + unlocks: string[]; + constructor(data: Record) { + this.tier = data?.tier || 0; + this.amountRequired = data?.amountRequired || 0; + this.unlocks = data?.unlocks || []; + } +} + +export default SkyBlockCollectionTier; diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollections.test.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollections.test.ts new file mode 100644 index 000000000..34b326351 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollections.test.ts @@ -0,0 +1,35 @@ +import SkyBlockCollection from './SkyBlockCollection.js'; +import SkyBlockCollections from './SkyBlockCollections.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockCollections', () => { + const data = new SkyBlockCollections({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockCollections); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdated).toBeDefined(); + expect(data.lastUpdated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.version).toBeDefined(); + expectTypeOf(data.version).toEqualTypeOf(); + expect(data.farming).toBeDefined(); + expectTypeOf(data.farming).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.combat).toBeDefined(); + expectTypeOf(data.combat).toEqualTypeOf(); + expect(data.foraging).toBeDefined(); + expectTypeOf(data.foraging).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.rift).toBeDefined(); + expectTypeOf(data.rift).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.version); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Collections/SkyBlockCollections.ts b/src/Structures/SkyBlock/Collections/SkyBlockCollections.ts new file mode 100644 index 000000000..d2fed7b51 --- /dev/null +++ b/src/Structures/SkyBlock/Collections/SkyBlockCollections.ts @@ -0,0 +1,53 @@ +import SkyBlockCollection from './SkyBlockCollection.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockCollections { + lastUpdated: number; + lastUpdatedAt: Date; + version: string; + farming: SkyBlockCollection[]; + mining: SkyBlockCollection[]; + combat: SkyBlockCollection[]; + foraging: SkyBlockCollection[]; + fishing: SkyBlockCollection[]; + rift: SkyBlockCollection[]; + constructor(data: Record) { + this.lastUpdated = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdated); + this.version = data?.version || 'UNKNOWN'; + const farmingCollections = data?.collections?.FARMING?.items || {}; + this.farming = Object.keys(farmingCollections).map( + (collection) => new SkyBlockCollection(farmingCollections?.[collection], collection) + ); + const miningCollections = data?.collections?.MINING?.items || {}; + this.mining = Object.keys(miningCollections).map( + (collection) => new SkyBlockCollection(miningCollections?.[collection], collection) + ); + const combatCollections = data?.collections?.COMBAT?.items || {}; + this.combat = Object.keys(combatCollections).map( + (collection) => new SkyBlockCollection(combatCollections?.[collection], collection) + ); + const foragingCollections = data?.collections?.FORAGING?.items || {}; + this.foraging = Object.keys(foragingCollections).map( + (collection) => new SkyBlockCollection(foragingCollections?.[collection], collection) + ); + const fishingCollections = data?.collections?.FISHING?.items || {}; + this.fishing = Object.keys(fishingCollections).map( + (collection) => new SkyBlockCollection(fishingCollections?.[collection], collection) + ); + const riftCollections = data?.collections?.RIFT?.items || {}; + this.rift = Object.keys(riftCollections).map( + (collection) => new SkyBlockCollection(riftCollections?.[collection], collection) + ); + } + + toString(): string { + return this.version; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockCollections; diff --git a/src/Structures/SkyBlock/Election/SkyBlockElection.test.ts b/src/Structures/SkyBlock/Election/SkyBlockElection.test.ts new file mode 100644 index 000000000..9adc2a7ba --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElection.test.ts @@ -0,0 +1,20 @@ +import SkyBlockElection from './SkyBlockElection.js'; +import SkyBlockElectionCandidate from './SkyBlockElectionCandidate.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockElection', () => { + const data = new SkyBlockElection({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockElection); + expectTypeOf(data).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expect(data.year).toBeGreaterThanOrEqual(0); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.candidates).toBeDefined(); + expectTypeOf(data.candidates).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.year); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Election/SkyBlockElection.ts b/src/Structures/SkyBlock/Election/SkyBlockElection.ts new file mode 100644 index 000000000..6ff1ec0db --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElection.ts @@ -0,0 +1,18 @@ +import SkyBlockElectionCandidate from './SkyBlockElectionCandidate.js'; + +class SkyBlockElection { + year: number; + candidates: SkyBlockElectionCandidate[]; + constructor(data: Record) { + this.year = data?.year || 0; + this.candidates = (data?.candidates || []) + .map((candidate: Record) => new SkyBlockElectionCandidate(candidate)) + .sort((a: SkyBlockElectionCandidate, b: SkyBlockElectionCandidate) => a.votesReceived - b.votesReceived); + } + + toString(): number { + return this.year; + } +} + +export default SkyBlockElection; diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.test.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.test.ts new file mode 100644 index 000000000..81679efb9 --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.test.ts @@ -0,0 +1,25 @@ +import SkyBlockElectionCandidate from './SkyBlockElectionCandidate.js'; +import SkyBlockElectionCandidatePerk from './SkyBlockElectionCandidatePerk.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockCandidateKeyBenefit, SkyBlockMayor } from '../../../Types/SkyBlock.js'; + +test('SkyBlockElectionCandidate', () => { + const data = new SkyBlockElectionCandidate({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockElectionCandidate); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.keyBenefit).toBeDefined(); + expectTypeOf(data.keyBenefit).toEqualTypeOf(); + expect(data.perks).toBeDefined(); + expectTypeOf(data.perks).toEqualTypeOf(); + expect(data.votesReceived).toBeDefined(); + expect(data.votesReceived).toBeGreaterThanOrEqual(0); + expectTypeOf(data.votesReceived).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockMayor | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.ts new file mode 100644 index 000000000..bea876960 --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidate.ts @@ -0,0 +1,21 @@ +import SkyBlockElectionCandidatePerk from './SkyBlockElectionCandidatePerk.js'; +import type { SkyBlockCandidateKeyBenefit, SkyBlockMayor } from '../../../Types/SkyBlock.js'; + +class SkyBlockElectionCandidate { + name: SkyBlockMayor | 'UNKNOWN'; + keyBenefit: SkyBlockCandidateKeyBenefit | 'UNKNOWN'; + perks: SkyBlockElectionCandidatePerk[]; + votesReceived: number; + constructor(data: Record) { + this.name = data?.name || 'UNKNOWN'; + this.keyBenefit = data?.key || 'UNKNOWN'; + this.perks = (data?.perks || []).map((perk: Record) => new SkyBlockElectionCandidatePerk(perk)); + this.votesReceived = data?.votes || 0; + } + + toString(): SkyBlockMayor | 'UNKNOWN' { + return this.name; + } +} + +export default SkyBlockElectionCandidate; diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.test.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.test.ts new file mode 100644 index 000000000..08b2202d1 --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.test.ts @@ -0,0 +1,20 @@ +import SkyBlockElectionCandidatePerk from './SkyBlockElectionCandidatePerk.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockElectionCandidatePerk', () => { + const data = new SkyBlockElectionCandidatePerk({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockElectionCandidatePerk); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.minister).toBeDefined(); + expectTypeOf(data.minister).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.ts new file mode 100644 index 000000000..e7fc98467 --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.ts @@ -0,0 +1,16 @@ +class SkyBlockElectionCandidatePerk { + name: string; + description: string; + minister: boolean; + constructor(data: Record) { + this.name = data?.name || 'UNKNOWN'; + this.description = data?.description || 'UNKNOWN'; + this.minister = data?.minister || false; + } + + toString(): string { + return this.name; + } +} + +export default SkyBlockElectionCandidatePerk; diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionData.test.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionData.test.ts new file mode 100644 index 000000000..127683ad9 --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionData.test.ts @@ -0,0 +1,21 @@ +import SkyBlockElection from './SkyBlockElection.js'; +import SkyBlockElectionData from './SkyBlockElectionData.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockElectionData', () => { + const data = new SkyBlockElectionData({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockElectionData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.lastElectionResults).toBeDefined(); + expect(data.lastElectionResults).toBeInstanceOf(SkyBlockElection); + expectTypeOf(data.lastElectionResults).toEqualTypeOf(); + expect(data.currentElection).toBeDefined(); + expectTypeOf(data.currentElection).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Election/SkyBlockElectionData.ts b/src/Structures/SkyBlock/Election/SkyBlockElectionData.ts new file mode 100644 index 000000000..627ee9a1c --- /dev/null +++ b/src/Structures/SkyBlock/Election/SkyBlockElectionData.ts @@ -0,0 +1,21 @@ +import SkyBlockElection from './SkyBlockElection.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockElectionData { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + lastElectionResults: SkyBlockElection; + currentElection: SkyBlockElection | null; + constructor(data: Record) { + this.lastUpdatedTimestamp = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.lastElectionResults = new SkyBlockElection(data?.mayor?.election || {}); + this.currentElection = data?.current ? new SkyBlockElection(data?.current || {}) : null; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockElectionData; diff --git a/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.test.ts b/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.test.ts new file mode 100644 index 000000000..1e9fb4ba4 --- /dev/null +++ b/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.test.ts @@ -0,0 +1,34 @@ +import SkyBlockFireSale from './SkyBlockFireSale.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockFireSale', () => { + const data = new SkyBlockFireSale({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockFireSale); + expectTypeOf(data).toEqualTypeOf(); + expect(data.itemId).toBeDefined(); + expectTypeOf(data.itemId).toEqualTypeOf(); + expect(data.startTimestamp).toBeDefined(); + expect(data.startTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startTimestamp).toEqualTypeOf(); + expect(data.startAt).toBeDefined(); + expect(data.startAt).toBeInstanceOf(Date); + expectTypeOf(data.startAt).toEqualTypeOf(); + expect(data.endTimestamp).toBeDefined(); + expect(data.endTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.endTimestamp).toEqualTypeOf(); + expect(data.endAt).toBeDefined(); + expect(data.endAt).toBeInstanceOf(Date); + expectTypeOf(data.endAt).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.price).toBeDefined(); + expect(data.price).toBeGreaterThanOrEqual(0); + expectTypeOf(data.price).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.itemId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.ts b/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.ts new file mode 100644 index 000000000..917495a2d --- /dev/null +++ b/src/Structures/SkyBlock/FireSale/SkyBlockFireSale.ts @@ -0,0 +1,30 @@ +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockFireSale { + itemId: string; + startTimestamp: number; + startAt: Date; + endTimestamp: number; + endAt: Date; + amount: number; + price: number; + constructor(data: Record) { + this.itemId = data.item_id || 'UNKNOWN'; + this.startTimestamp = data.start || 0; + this.startAt = new Date(this.startTimestamp); + this.endTimestamp = data.end || 0; + this.endAt = new Date(this.endTimestamp); + this.amount = data.amount || 0; + this.price = data.price || 0; + } + + toString(): string { + return this.itemId; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockFireSale; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGarden.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGarden.test.ts new file mode 100644 index 000000000..111e0c42e --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGarden.test.ts @@ -0,0 +1,42 @@ +import SkyBlockGarden from './SkyBlockGarden.js'; +import SkyBlockGardenActiveVisitor from './SkyBlockGardenActiveVisitor.js'; +import SkyBlockGardenComposter from './SkyBlockGardenComposter.js'; +import SkyBlockGardenCropMilestones from './SkyBlockGardenCropMilestones.js'; +import SkyBlockGardenCropsUpgrades from './SkyBlockGardenCropsUpgrades.js'; +import SkyBlockGardenVisitors from './SkyBlockGardenVisitors.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BarnPlot, BarnSkin, SkillLevelData } from '../../../Types/SkyBlock.js'; + +test('SkyBlockGarden', () => { + const data = new SkyBlockGarden({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGarden); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.barnSkin).toBeDefined(); + expectTypeOf(data.barnSkin).toEqualTypeOf(); + expect(data.unlockedBarnSkins).toBeDefined(); + expectTypeOf(data.unlockedBarnSkins).toEqualTypeOf(); + expect(data.unlockedPlots).toBeDefined(); + expectTypeOf(data.unlockedPlots).toEqualTypeOf(); + expect(data.visitors).toBeDefined(); + expect(data.visitors).toBeInstanceOf(SkyBlockGardenVisitors); + expectTypeOf(data.visitors).toEqualTypeOf(); + expect(data.currentVisitors).toBeDefined(); + expectTypeOf(data.currentVisitors).toEqualTypeOf(); + expect(data.cropMilestones).toBeDefined(); + expect(data.cropMilestones).toBeInstanceOf(SkyBlockGardenCropMilestones); + expectTypeOf(data.cropMilestones).toEqualTypeOf(); + expect(data.composter).toBeDefined(); + expect(data.composter).toBeInstanceOf(SkyBlockGardenComposter); + expectTypeOf(data.composter).toEqualTypeOf(); + expect(data.cropUpgrades).toBeDefined(); + expect(data.cropUpgrades).toBeInstanceOf(SkyBlockGardenCropsUpgrades); + expectTypeOf(data.cropUpgrades).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGarden.ts b/src/Structures/SkyBlock/Garden/SkyBlockGarden.ts new file mode 100644 index 000000000..a7657fbbf --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGarden.ts @@ -0,0 +1,43 @@ +import SkyBlockGardenActiveVisitor from './SkyBlockGardenActiveVisitor.js'; +import SkyBlockGardenComposter from './SkyBlockGardenComposter.js'; +import SkyBlockGardenCropMilestones from './SkyBlockGardenCropMilestones.js'; +import SkyBlockGardenCropsUpgrades from './SkyBlockGardenCropsUpgrades.js'; +import SkyBlockGardenVisitors from './SkyBlockGardenVisitors.js'; +import { getLevelByXp } from '../../../Utils/SkyBlockUtils.js'; +import type RequestData from '../../../Private/RequestData.js'; +import type { BarnPlot, BarnSkin, SkillLevelData } from '../../../Types/SkyBlock.js'; + +class SkyBlockGarden { + level: SkillLevelData; + barnSkin: BarnSkin; + unlockedBarnSkins: BarnSkin[]; + unlockedPlots: BarnPlot[]; + visitors: SkyBlockGardenVisitors; + currentVisitors: SkyBlockGardenActiveVisitor[]; + cropMilestones: SkyBlockGardenCropMilestones; + composter: SkyBlockGardenComposter; + cropUpgrades: SkyBlockGardenCropsUpgrades; + constructor(data: Record) { + this.level = getLevelByXp(data?.garden_experience, { type: 'garden' }); + this.barnSkin = data?.selected_barn_skin || 'UNKNOWN'; + this.unlockedBarnSkins = data?.unlocked_barn_skins || []; + this.unlockedPlots = data?.unlocked_plots_ids || []; + this.visitors = new SkyBlockGardenVisitors(data?.commission_data || {}); + this.currentVisitors = Object.keys(data?.active_commissions || {}).map( + (visitor) => new SkyBlockGardenActiveVisitor(data?.active_commissions?.[visitor], visitor) + ); + this.cropMilestones = new SkyBlockGardenCropMilestones(data?.resources_collected || {}); + this.composter = new SkyBlockGardenComposter(data?.composter_data || {}); + this.cropUpgrades = new SkyBlockGardenCropsUpgrades(data?.crop_upgrade_levels || {}); + } + + toString(): number { + return this.level.level; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockGarden; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.test.ts new file mode 100644 index 000000000..94ef01550 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.test.ts @@ -0,0 +1,25 @@ +import SkyBlockGardenActiveVisitor from './SkyBlockGardenActiveVisitor.js'; +import SkyBlockGardenActiveVisitorRequirement from './SkyBlockGardenActiveVisitorRequirement.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { VisitorStatus } from '../../../Types/SkyBlock.js'; + +test('SkyBlockGardenActiveVisitor', () => { + const data = new SkyBlockGardenActiveVisitor({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenActiveVisitor); + expectTypeOf(data).toEqualTypeOf(); + expect(data.visitor).toBeDefined(); + expectTypeOf(data.visitor).toEqualTypeOf(); + expect(data.requirements).toBeDefined(); + expectTypeOf(data.requirements).toEqualTypeOf(); + expect(data.status).toBeDefined(); + expectTypeOf(data.status).toEqualTypeOf(); + expect(data.position).toBeDefined(); + expect(data.position).toBeGreaterThanOrEqual(0); + expectTypeOf(data.position).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.visitor); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.ts new file mode 100644 index 000000000..b373e5787 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.ts @@ -0,0 +1,23 @@ +import SkyBlockGardenActiveVisitorRequirement from './SkyBlockGardenActiveVisitorRequirement.js'; +import type { VisitorStatus } from '../../../Types/SkyBlock.js'; + +class SkyBlockGardenActiveVisitor { + visitor: string; + requirements: SkyBlockGardenActiveVisitorRequirement[]; + status: VisitorStatus | 'UNKNOWN'; + position: number; + constructor(data: Record, name: string) { + this.visitor = name; + this.requirements = (data?.requirement || []).map( + (requirement: Record) => new SkyBlockGardenActiveVisitorRequirement(requirement) + ); + this.status = data?.status || 'UNKNOWN'; + this.position = data?.position || 1; + } + + toString(): string { + return this.visitor; + } +} + +export default SkyBlockGardenActiveVisitor; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.test.ts new file mode 100644 index 000000000..152074bb6 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.test.ts @@ -0,0 +1,24 @@ +import SkyBlockGardenActiveVisitorRequirement from './SkyBlockGardenActiveVisitorRequirement.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockGardenActiveVisitorRequirement', () => { + const data = new SkyBlockGardenActiveVisitorRequirement({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenActiveVisitorRequirement); + expectTypeOf(data).toEqualTypeOf(); + expect(data.originalItem).toBeDefined(); + expectTypeOf(data.originalItem).toEqualTypeOf(); + expect(data.originalAmount).toBeDefined(); + expect(data.originalAmount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.originalAmount).toEqualTypeOf(); + expect(data.item).toBeDefined(); + expectTypeOf(data.item).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.amount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.ts new file mode 100644 index 000000000..352e9fad8 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.ts @@ -0,0 +1,18 @@ +class SkyBlockGardenActiveVisitorRequirement { + originalItem: string; + originalAmount: number; + item: string; + amount: number; + constructor(data: Record) { + this.originalItem = data?.original_item || ''; + this.originalAmount = data?.original_amount || 0; + this.item = data?.item || ''; + this.amount = data?.amount || 0; + } + + toString(): number { + return this.amount; + } +} + +export default SkyBlockGardenActiveVisitorRequirement; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.test.ts new file mode 100644 index 000000000..870872454 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.test.ts @@ -0,0 +1,33 @@ +import SkyBlockGardenComposter from './SkyBlockGardenComposter.js'; +import SkyBlockGardenComposterUpgrades from './SkyBlockGardenComposterUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockGardenComposter', () => { + const data = new SkyBlockGardenComposter({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenComposter); + expectTypeOf(data).toEqualTypeOf(); + expect(data.organicMatter).toBeDefined(); + expect(data.organicMatter).toBeGreaterThanOrEqual(0); + expectTypeOf(data.organicMatter).toEqualTypeOf(); + expect(data.fuelUnits).toBeDefined(); + expect(data.fuelUnits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fuelUnits).toEqualTypeOf(); + expect(data.compostUnits).toBeDefined(); + expect(data.compostUnits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.compostUnits).toEqualTypeOf(); + expect(data.compostItems).toBeDefined(); + expect(data.compostItems).toBeGreaterThanOrEqual(0); + expectTypeOf(data.compostItems).toEqualTypeOf(); + expect(data.conversionTicks).toBeDefined(); + expect(data.conversionTicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.conversionTicks).toEqualTypeOf(); + expect(data.upgrades).toBeDefined(); + expect(data.upgrades).toBeInstanceOf(SkyBlockGardenComposterUpgrades); + expectTypeOf(data.upgrades).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.organicMatter); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.ts new file mode 100644 index 000000000..80d17c16e --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposter.ts @@ -0,0 +1,24 @@ +import SkyBlockGardenComposterUpgrades from './SkyBlockGardenComposterUpgrades.js'; + +class SkyBlockGardenComposter { + organicMatter: number; + fuelUnits: number; + compostUnits: number; + compostItems: number; + conversionTicks: number; + upgrades: SkyBlockGardenComposterUpgrades; + constructor(data: Record) { + this.organicMatter = data?.organic_matter || 0; + this.fuelUnits = data?.fuel_units || 0; + this.compostUnits = data?.compost_units || 0; + this.compostItems = data?.compost_items || 0; + this.conversionTicks = data?.conversion_ticks || 0; + this.upgrades = new SkyBlockGardenComposterUpgrades(data?.upgrades || {}); + } + + toString(): number { + return this.organicMatter; + } +} + +export default SkyBlockGardenComposter; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.test.ts new file mode 100644 index 000000000..b5e72b21e --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.test.ts @@ -0,0 +1,24 @@ +import SkyBlockGardenComposterUpgrades from './SkyBlockGardenComposterUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockGardenComposterUpgrades', () => { + const data = new SkyBlockGardenComposterUpgrades({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenComposterUpgrades); + expectTypeOf(data).toEqualTypeOf(); + expect(data.speed).toBeDefined(); + expect(data.speed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speed).toEqualTypeOf(); + expect(data.multiDrop).toBeDefined(); + expect(data.multiDrop).toBeGreaterThanOrEqual(0); + expectTypeOf(data.multiDrop).toEqualTypeOf(); + expect(data.fuelCap).toBeDefined(); + expect(data.fuelCap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fuelCap).toEqualTypeOf(); + expect(data.organicMatterCap).toBeDefined(); + expect(data.organicMatterCap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.organicMatterCap).toEqualTypeOf(); + expect(data.costReduction).toBeDefined(); + expect(data.costReduction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.costReduction).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.ts new file mode 100644 index 000000000..42dbf6e91 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.ts @@ -0,0 +1,16 @@ +class SkyBlockGardenComposterUpgrades { + speed: number; + multiDrop: number; + fuelCap: number; + organicMatterCap: number; + costReduction: number; + constructor(data: Record) { + this.speed = data?.speed || 0; + this.multiDrop = data?.multi_drop || 0; + this.fuelCap = data?.fuel_cap || 0; + this.organicMatterCap = data?.organic_matter_cap || 0; + this.costReduction = data?.cost_reduction || 0; + } +} + +export default SkyBlockGardenComposterUpgrades; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.test.ts new file mode 100644 index 000000000..f4d621d49 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.test.ts @@ -0,0 +1,44 @@ +import SkyBlockGardenCropMilestones from './SkyBlockGardenCropMilestones.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkillLevelData } from '../../../Types/SkyBlock.js'; + +test('SkyBlockGardenCropMilestones', () => { + const data = new SkyBlockGardenCropMilestones({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenCropMilestones); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wheat).toBeDefined(); + expectTypeOf(data.wheat).toEqualTypeOf(); + expect(data.carrot).toBeDefined(); + expectTypeOf(data.carrot).toEqualTypeOf(); + expect(data.sugarCane).toBeDefined(); + expectTypeOf(data.sugarCane).toEqualTypeOf(); + expect(data.potato).toBeDefined(); + expectTypeOf(data.potato).toEqualTypeOf(); + expect(data.pumpkin).toBeDefined(); + expectTypeOf(data.pumpkin).toEqualTypeOf(); + expect(data.melon).toBeDefined(); + expectTypeOf(data.melon).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.cocoaBeans).toBeDefined(); + expectTypeOf(data.cocoaBeans).toEqualTypeOf(); + expect(data.mushroom).toBeDefined(); + expectTypeOf(data.mushroom).toEqualTypeOf(); + expect(data.netherWart).toBeDefined(); + expectTypeOf(data.netherWart).toEqualTypeOf(); + expect(data.moonFlower).toBeDefined(); + expectTypeOf(data.moonFlower).toEqualTypeOf(); + expect(data.sunFlower).toBeDefined(); + expectTypeOf(data.sunFlower).toEqualTypeOf(); + expect(data.wildRose).toBeDefined(); + expectTypeOf(data.wildRose).toEqualTypeOf(); + expect(data.average).toBeDefined(); + expect(data.average).toBeGreaterThanOrEqual(0); + expectTypeOf(data.average).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.average); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.ts new file mode 100644 index 000000000..aa9be2f3b --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.ts @@ -0,0 +1,55 @@ +import { getLevelByXp } from '../../../Utils/SkyBlockUtils.js'; +import type { SkillLevelData } from '../../../Types/SkyBlock.js'; + +class SkyBlockGardenCropMilestones { + wheat: SkillLevelData; + carrot: SkillLevelData; + sugarCane: SkillLevelData; + potato: SkillLevelData; + pumpkin: SkillLevelData; + melon: SkillLevelData; + cactus: SkillLevelData; + cocoaBeans: SkillLevelData; + mushroom: SkillLevelData; + netherWart: SkillLevelData; + moonFlower: SkillLevelData; + sunFlower: SkillLevelData; + wildRose: SkillLevelData; + average: number; + constructor(data: Record) { + this.wheat = getLevelByXp(data?.WHEAT || 0, { type: 'wheat' }); + this.carrot = getLevelByXp(data?.CARROT_ITEM || 0, { type: 'carrot' }); + this.sugarCane = getLevelByXp(data?.SUGAR_CANE || 0, { type: 'sugarCane' }); + this.potato = getLevelByXp(data?.POTATO_ITEM || 0, { type: 'potato' }); + this.pumpkin = getLevelByXp(data?.PUMPKIN || 0, { type: 'pumpkin' }); + this.melon = getLevelByXp(data?.MELON || 0, { type: 'melon' }); + this.cactus = getLevelByXp(data?.CACTUS || 0, { type: 'cactus' }); + this.cocoaBeans = getLevelByXp(data?.['INK_SACK:3'] || 0, { type: 'cocoaBeans' }); + this.mushroom = getLevelByXp(data?.MUSHROOM_COLLECTION || 0, { type: 'mushroom' }); + this.netherWart = getLevelByXp(data?.NETHER_STALK || 0, { type: 'netherWart' }); + this.moonFlower = getLevelByXp(data?.MOONFLOWER || 0, { type: 'moonFlower' }); + this.sunFlower = getLevelByXp(data?.DOUBLE_PLANT || 0, { type: 'sunFlower' }); + this.wildRose = getLevelByXp(data?.WILD_ROSE || 0, { type: 'wildRose' }); + this.average = + (this.wheat.level + + this.carrot.level + + this.sugarCane.level + + this.potato.level + + this.pumpkin.level + + this.melon.level + + this.cactus.level + + this.cocoaBeans.level + + this.mushroom.level + + this.netherWart.level + + this.moonFlower.level + + this.sunFlower.level + + this.wildRose.level) / + 13; + } + + toString(): number { + return this.average; + } +} + +export default SkyBlockGardenCropMilestones; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.test.ts new file mode 100644 index 000000000..f90f62026 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.test.ts @@ -0,0 +1,47 @@ +import SkyBlockGardenCropsUpgrades from './SkyBlockGardenCropsUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockGardenCropsUpgrades', () => { + const data = new SkyBlockGardenCropsUpgrades({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenCropsUpgrades); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wheat).toBeDefined(); + expect(data.wheat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wheat).toEqualTypeOf(); + expect(data.carrot).toBeDefined(); + expect(data.carrot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.carrot).toEqualTypeOf(); + expect(data.sugarCane).toBeDefined(); + expect(data.sugarCane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sugarCane).toEqualTypeOf(); + expect(data.potato).toBeDefined(); + expect(data.potato).toBeGreaterThanOrEqual(0); + expectTypeOf(data.potato).toEqualTypeOf(); + expect(data.pumpkin).toBeDefined(); + expect(data.pumpkin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pumpkin).toEqualTypeOf(); + expect(data.melon).toBeDefined(); + expect(data.melon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.melon).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expect(data.cactus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.cocoaBeans).toBeDefined(); + expect(data.cocoaBeans).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cocoaBeans).toEqualTypeOf(); + expect(data.mushroom).toBeDefined(); + expect(data.mushroom).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mushroom).toEqualTypeOf(); + expect(data.netherWart).toBeDefined(); + expect(data.netherWart).toBeGreaterThanOrEqual(0); + expectTypeOf(data.netherWart).toEqualTypeOf(); + expect(data.average).toBeDefined(); + expect(data.average).toBeGreaterThanOrEqual(0); + expectTypeOf(data.average).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.average); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.ts new file mode 100644 index 000000000..0495764d2 --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.ts @@ -0,0 +1,43 @@ +class SkyBlockGardenCropsUpgrades { + wheat: number; + carrot: number; + sugarCane: number; + potato: number; + pumpkin: number; + melon: number; + cactus: number; + cocoaBeans: number; + mushroom: number; + netherWart: number; + average: number; + constructor(data: Record) { + this.wheat = data?.WHEAT || 0; + this.carrot = data?.CARROT_ITEM || 0; + this.sugarCane = data?.SUGAR_CANE || 0; + this.potato = data?.POTATO_ITEM || 0; + this.pumpkin = data?.PUMPKIN || 0; + this.melon = data?.MELON || 0; + this.cactus = data?.CACTUS || 0; + this.cocoaBeans = data?.['INK_SACK:3'] || 0; + this.mushroom = data?.MUSHROOM_COLLECTION || 0; + this.netherWart = data?.NETHER_STALK || 0; + this.average = + (this.wheat + + this.carrot + + this.sugarCane + + this.potato + + this.pumpkin + + this.melon + + this.cactus + + this.cocoaBeans + + this.mushroom + + this.netherWart) / + 10; + } + + toString(): number { + return this.average; + } +} + +export default SkyBlockGardenCropsUpgrades; diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.test.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.test.ts new file mode 100644 index 000000000..18767ce6e --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.test.ts @@ -0,0 +1,19 @@ +import SkyBlockGardenVisitors from './SkyBlockGardenVisitors.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockGardenVisitors', () => { + const data = new SkyBlockGardenVisitors({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockGardenVisitors); + expectTypeOf(data).toEqualTypeOf(); + expect(data.visited).toBeDefined(); + expectTypeOf(data.visited).toEqualTypeOf>(); + expect(data.completed).toBeDefined(); + expectTypeOf(data.completed).toEqualTypeOf>(); + expect(data.totalCompleted).toBeDefined(); + expect(data.totalCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalCompleted).toEqualTypeOf(); + expect(data.uniqueNpcsServed).toBeDefined(); + expect(data.uniqueNpcsServed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.uniqueNpcsServed).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.ts b/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.ts new file mode 100644 index 000000000..f599d6bff --- /dev/null +++ b/src/Structures/SkyBlock/Garden/SkyBlockGardenVisitors.ts @@ -0,0 +1,14 @@ +class SkyBlockGardenVisitors { + visited: Record; + completed: Record; + totalCompleted: number; + uniqueNpcsServed: number; + constructor(data: Record) { + this.visited = data?.visits || {}; + this.completed = data?.completed || {}; + this.totalCompleted = data?.total_completed || 0; + this.uniqueNpcsServed = data?.unique_npcs_served || 0; + } +} + +export default SkyBlockGardenVisitors; diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.test.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.test.ts new file mode 100644 index 000000000..73c4578b9 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.test.ts @@ -0,0 +1,163 @@ +import SkyBlockInventoryItem from './SkyBlockInventoryItem.js'; +import SkyBlockInventoryItemAttribute from './SkyBlockInventoryItemAttribute.js'; +import SkyBlockInventoryItemEnchantment from './SkyBlockInventoryItemEnchantment.js'; +import SkyBlockInventoryItemRune from './SkyBlockInventoryItemRune.js'; +import SkyBlockPotionEffect from '../Potion/SkyBlockPotionEffect.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { Rarity } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +test('SkyBlockInventoryItem', () => { + const data = new SkyBlockInventoryItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockInventoryItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.minecraftItemId).toBeDefined(); + expect(data.minecraftItemId).toBeGreaterThanOrEqual(0); + expectTypeOf(data.minecraftItemId).toEqualTypeOf(); + expect(data.itemCount).toBeDefined(); + expect(data.itemCount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemCount).toEqualTypeOf(); + expect(data.itemDamage).toBeDefined(); + expect(data.itemDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.itemDamage).toEqualTypeOf(); + expect(data.unbreakable).toBeDefined(); + expectTypeOf(data.unbreakable).toEqualTypeOf(); + expect(data.hideFlags).toBeDefined(); + expectTypeOf(data.hideFlags).toEqualTypeOf(); + expect(data.lore).toBeDefined(); + expectTypeOf(data.lore).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.color).toBeDefined(); + expectTypeOf(data.color).toEqualTypeOf(); + expect(data.recombobulated).toBeDefined(); + expectTypeOf(data.recombobulated).toEqualTypeOf(); + expect(data.statsBook).toBeDefined(); + expectTypeOf(data.statsBook).toEqualTypeOf(); + expect(data.runes).toBeDefined(); + expectTypeOf(data.runes).toEqualTypeOf(); + expect(data.reforge).toBeDefined(); + expectTypeOf(data.reforge).toEqualTypeOf(); + expect(data.hasArtOfWar).toBeDefined(); + expectTypeOf(data.hasArtOfWar).toEqualTypeOf(); + expect(data.starCount).toBeDefined(); + expect(data.starCount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.starCount).toEqualTypeOf(); + expect(data.enchantments).toBeDefined(); + expectTypeOf(data.enchantments).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.hotPotatoBookCount).toBeDefined(); + expectTypeOf(data.hotPotatoBookCount).toEqualTypeOf(); + expect(data.championCombatXP).toBeDefined(); + expectTypeOf(data.championCombatXP).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.hasDonatedItem).toBeDefined(); + expectTypeOf(data.hasDonatedItem).toEqualTypeOf(); + expect(data.transmissionTunerCount).toBeDefined(); + expectTypeOf(data.transmissionTunerCount).toEqualTypeOf(); + expect(data.powerAbilityScroll).toBeDefined(); + expectTypeOf(data.powerAbilityScroll).toEqualTypeOf(); + expect(data.hasEtherwarp).toBeDefined(); + expectTypeOf(data.hasEtherwarp).toEqualTypeOf(); + expect(data.isDungeonItem).toBeDefined(); + expectTypeOf(data.isDungeonItem).toEqualTypeOf(); + expect(data.abilityScrolls).toBeDefined(); + expectTypeOf(data.abilityScrolls).toEqualTypeOf(); + expect(data.dungeonSkillRequirement).toBeDefined(); + expectTypeOf(data.dungeonSkillRequirement).toEqualTypeOf(); + expect(data.baseStatBoostPercentage).toBeDefined(); + expectTypeOf(data.baseStatBoostPercentage).toEqualTypeOf(); + expect(data.itemTier).toBeDefined(); + expectTypeOf(data.itemTier).toEqualTypeOf(); + expect(data.manaDisintergratorCount).toBeDefined(); + expectTypeOf(data.manaDisintergratorCount).toEqualTypeOf(); + expect(data.skin).toBeDefined(); + expectTypeOf(data.skin).toEqualTypeOf(); + expect(data.blazetekkChannel).toBeDefined(); + expectTypeOf(data.blazetekkChannel).toEqualTypeOf(); + expect(data.capturedPlayer).toBeDefined(); + expectTypeOf(data.capturedPlayer).toEqualTypeOf(); + expect(data.cakeOwner).toBeDefined(); + expectTypeOf(data.cakeOwner).toEqualTypeOf(); + expect(data.soulDurability).toBeDefined(); + expectTypeOf(data.soulDurability).toEqualTypeOf(); + expect(data.initiatorPlayer).toBeDefined(); + expectTypeOf(data.initiatorPlayer).toEqualTypeOf(); + expect(data.isShiny).toBeDefined(); + expectTypeOf(data.isShiny).toEqualTypeOf(); + expect(data.attributes).toBeDefined(); + expectTypeOf(data.attributes).toEqualTypeOf(); + expect(data.jalapenoCount).toBeDefined(); + expectTypeOf(data.jalapenoCount).toEqualTypeOf(); + expect(data.hecatombSRuns).toBeDefined(); + expectTypeOf(data.hecatombSRuns).toEqualTypeOf(); + expect(data.dungeonItemLevel).toBeDefined(); + expectTypeOf(data.dungeonItemLevel).toEqualTypeOf(); + expect(data.originTag).toBeDefined(); + expectTypeOf(data.originTag).toEqualTypeOf(); + expect(data.hasArtOfPeace).toBeDefined(); + expectTypeOf(data.hasArtOfPeace).toEqualTypeOf(); + expect(data.secondRandomColor).toBeDefined(); + expectTypeOf(data.secondRandomColor).toEqualTypeOf(); + expect(data.dyeItem).toBeDefined(); + expectTypeOf(data.dyeItem).toEqualTypeOf(); + expect(data.raffleYear).toBeDefined(); + expectTypeOf(data.raffleYear).toEqualTypeOf(); + expect(data.raffleWin).toBeDefined(); + expectTypeOf(data.raffleWin).toEqualTypeOf(); + expect(data.edition).toBeDefined(); + expectTypeOf(data.edition).toEqualTypeOf(); + expect(data.recipientName).toBeDefined(); + expectTypeOf(data.recipientName).toEqualTypeOf(); + expect(data.recipientUUID).toBeDefined(); + expectTypeOf(data.recipientUUID).toEqualTypeOf(); + expect(data.bossTier).toBeDefined(); + expectTypeOf(data.bossTier).toEqualTypeOf(); + expect(data.divanPowerCoating).toBeDefined(); + expectTypeOf(data.divanPowerCoating).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.bossId).toBeDefined(); + expectTypeOf(data.bossId).toEqualTypeOf(); + expect(data.spawnedFor).toBeDefined(); + expectTypeOf(data.spawnedFor).toEqualTypeOf(); + expect(data.emanKills).toBeDefined(); + expectTypeOf(data.emanKills).toEqualTypeOf(); + expect(data.isRiftTransferable).toBeDefined(); + expectTypeOf(data.isRiftTransferable).toEqualTypeOf(); + expect(data.coinsGained).toBeDefined(); + expectTypeOf(data.coinsGained).toEqualTypeOf(); + expect(data.ranchersSpeed).toBeDefined(); + expectTypeOf(data.ranchersSpeed).toEqualTypeOf(); + expect(data.favoriteSentinalWarden).toBeDefined(); + expectTypeOf(data.favoriteSentinalWarden).toEqualTypeOf(); + expect(data.potionLevel).toBeDefined(); + expectTypeOf(data.potionLevel).toEqualTypeOf(); + expect(data.potion).toBeDefined(); + expectTypeOf(data.potion).toEqualTypeOf(); + expect(data.potionEffects).toBeDefined(); + expectTypeOf(data.potionEffects).toEqualTypeOf(); + expect(data.potionType).toBeDefined(); + expectTypeOf(data.potionType).toEqualTypeOf(); + expect(data.isSplashPotion).toBeDefined(); + expectTypeOf(data.isSplashPotion).toEqualTypeOf(); + expect(data.potionName).toBeDefined(); + expectTypeOf(data.potionName).toEqualTypeOf(); + expect(data.isDungeonPotion).toBeDefined(); + expectTypeOf(data.isDungeonPotion).toEqualTypeOf(); + expect(data.gearScore).toBeDefined(); + expect(data.gearScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gearScore).toEqualTypeOf(); + expect(data.rarity).toBeDefined(); + expectTypeOf(data.rarity).toEqualTypeOf(); + expect(data.raw).toBeDefined(); + expectTypeOf(data.raw).toEqualTypeOf>(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.ts new file mode 100644 index 000000000..9efd06f1f --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItem.ts @@ -0,0 +1,202 @@ +import SkyBlockInventoryItemAttribute from './SkyBlockInventoryItemAttribute.js'; +import SkyBlockInventoryItemEnchantment from './SkyBlockInventoryItemEnchantment.js'; +import SkyBlockInventoryItemRune from './SkyBlockInventoryItemRune.js'; +import SkyBlockPotionEffect from '../Potion/SkyBlockPotionEffect.js'; +import type { Rarity } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockInventoryItem { + minecraftItemId: number; + itemCount: number; + itemDamage: number; + unbreakable: boolean; + hideFlags: number | null; + lore: string[] | null; + name: string | 'UNKNOWN'; + color: number | null; + recombobulated: boolean; + statsBook: number | null; + runes: SkyBlockInventoryItemRune[] | null; + reforge: string | 'none'; + hasArtOfWar: boolean; + starCount: number; + enchantments: SkyBlockInventoryItemEnchantment[] | null; + uuid: UUID | null; + hotPotatoBookCount: number | null; + championCombatXP: number | null; + id: string; + hasDonatedItem: boolean; + transmissionTunerCount: number | null; + powerAbilityScroll: string | null; + hasEtherwarp: boolean; + isDungeonItem: boolean; + abilityScrolls: string[] | null; + dungeonSkillRequirement: number | null; + baseStatBoostPercentage: number | null; + itemTier: number | null; + manaDisintergratorCount: number | null; + skin: string | null; + blazetekkChannel: number | null; + capturedPlayer: string | null; + cakeOwner: string | null; + soulDurability: number | null; + initiatorPlayer: string | null; + isShiny: boolean; + attributes: SkyBlockInventoryItemAttribute[] | null; + jalapenoCount: number | null; + hecatombSRuns: number | null; + dungeonItemLevel: number | null; + originTag: string | null; + hasArtOfPeace: boolean; + secondRandomColor: number | null; + dyeItem: string | null; + raffleYear: number | null; + raffleWin: string | null; + edition: number | null; + recipientName: string | null; + recipientUUID: string | null; + bossTier: number | null; + divanPowerCoating: number | null; + year: number | null; + bossId: number | null; + spawnedFor: number | null; + emanKills: number | null; + isRiftTransferable: boolean; + coinsGained: number | null; + ranchersSpeed: number | null; + favoriteSentinalWarden: number | null; + potionLevel: number | null; + potion: number | null; + potionEffects: SkyBlockPotionEffect[] | null; + potionType: number | null; + isSplashPotion: boolean; + potionName: string | null; + isDungeonPotion: boolean; + gearScore: number; + rarity: Rarity; + raw: Record; + constructor(data: Record) { + this.minecraftItemId = data?.id || 0; + this.itemCount = data?.count || 1; + this.itemDamage = data?.Damage || 0; + this.unbreakable = Boolean(data?.tag?.Unbreakable || 1); + this.hideFlags = data?.tag?.HideFlags || null; + this.lore = data?.tag?.display?.Lore || null; + this.name = data?.tag?.display?.name || 'UNKNOWN'; + this.color = data?.tag?.display?.color || null; + this.recombobulated = Boolean(data?.tag?.ExtraAttributes?.rarity_upgrades || 0); + this.statsBook = data?.tag?.ExtraAttributes?.stats_book || null; + this.runes = data?.tag?.ExtraAttributes?.runes + ? Object.keys(data?.tag?.ExtraAttributes?.runes).map( + (rune) => new SkyBlockInventoryItemRune({ id: rune, tier: data?.tag?.ExtraAttributes?.runes?.[rune] }) + ) + : null; + this.reforge = data?.tag?.ExtraAttributes?.modifier || 'none'; + this.hasArtOfWar = Boolean(data?.tag?.ExtraAttributes?.art_of_war_count || 0); + this.starCount = data?.tag?.ExtraAttributes?.upgrade_level || 0; + this.enchantments = data?.tag?.ExtraAttributes?.enchantments + ? Object.keys(data?.tag?.ExtraAttributes?.enchantments).map( + (enchantment) => + new SkyBlockInventoryItemEnchantment({ + id: enchantment, + level: data?.tag?.ExtraAttributes?.enchantments?.[enchantment] + }) + ) + : null; + this.uuid = data?.tag?.ExtraAttributes?.uuid || null; + this.hotPotatoBookCount = data?.tag?.ExtraAttributes?.hot_potato_count || null; + this.championCombatXP = data?.tag?.ExtraAttributes?.champion_combat_xp || null; + this.id = data?.tag?.ExtraAttributes?.id || 'UNKNOWN'; + this.hasDonatedItem = Boolean(data?.tag?.ExtraAttributes?.donated_museum || 0); + this.transmissionTunerCount = data?.tag?.ExtraAttributes?.tuned_transmission || null; + this.powerAbilityScroll = data?.tag?.ExtraAttributes?.power_ability_scroll || null; + this.hasEtherwarp = Boolean(data?.tag?.ExtraAttributes?.ethermerge || 0); + this.isDungeonItem = Boolean(data?.tag?.ExtraAttributes?.dungeon_item || 0); + this.abilityScrolls = data?.tag?.ExtraAttributes?.ability_scroll || null; + this.dungeonSkillRequirement = data?.tag?.ExtraAttributes?.dungeon_skill_req || null; + this.baseStatBoostPercentage = data?.tag?.ExtraAttributes?.baseStatBoostPercentage || null; + this.itemTier = data?.tag?.ExtraAttributes?.item_tier || null; + this.manaDisintergratorCount = data?.tag?.ExtraAttributes?.mana_disintergrator_count || null; + this.skin = data?.tag?.ExtraAttributes?.skin || null; + this.blazetekkChannel = data?.tag?.ExtraAttributes?.blazetekk_channel || null; + this.capturedPlayer = data?.tag?.ExtraAttributes?.captured_player || null; + this.cakeOwner = data?.tag?.ExtraAttributes?.cake_owner || null; + this.soulDurability = data?.tag?.ExtraAttributes?.soul_durability || null; + this.initiatorPlayer = data?.tag?.ExtraAttributes?.initator_player || null; + this.isShiny = Boolean(data?.tag?.ExtraAttributes?.is_shiny || 0); + this.attributes = data?.tag?.ExtraAttributes?.attributes + ? Object.keys(data?.tag?.ExtraAttributes?.attributes).map( + (attribute) => + new SkyBlockInventoryItemAttribute({ + id: attribute, + level: data?.tag?.ExtraAttributes?.attributes[attribute] + }) + ) + : null; + this.jalapenoCount = data?.tag?.ExtraAttributes?.jalapeono_count || null; + this.hecatombSRuns = data?.tag?.ExtraAttributes?.hecatomb_s_runs || null; + this.dungeonItemLevel = data?.tag?.ExtraAttributes?.dungeon_item_level || null; + this.originTag = data?.tag?.ExtraAttributes?.originTag || null; + this.hasArtOfPeace = Boolean(data?.tag?.ExtraAttributes?.artOfPeaceApplied || 0); + this.secondRandomColor = data?.tag?.ExtraAttributes?.color || null; + this.dyeItem = data?.tag?.ExtraAttributes?.dye_item || null; + this.raffleYear = data?.tag?.ExtraAttributes?.raffle_year || null; + this.raffleWin = data?.tag?.ExtraAttributes?.raffle_win || null; + this.edition = data?.tag?.ExtraAttributes?.edition || null; + this.recipientName = data?.tag?.ExtraAttributes?.recipient_name || null; + this.recipientUUID = data?.tag?.ExtraAttributes?.recipient_id || null; + this.bossTier = data?.tag?.ExtraAttributes?.boss_tier || null; + this.divanPowerCoating = data?.tag?.ExtraAttributes?.divan_power_coating || null; + this.year = data?.tag?.ExtraAttributes?.year || null; + this.bossId = data?.tag?.ExtraAttributes?.bossId || null; + this.spawnedFor = data?.tag?.ExtraAttributes?.spawnedFor || null; + this.emanKills = data?.tag?.ExtraAttributes?.eman_kills || null; + this.isRiftTransferable = Boolean(data?.tag?.ExtraAttributes?.rift_transferred || 0); + this.coinsGained = data?.tag?.ExtraAttributes?.coins_gained || null; + this.ranchersSpeed = data?.tag?.ExtraAttributes?.ranchers_speed || null; + this.favoriteSentinalWarden = data?.tag?.ExtraAttributes?.favorite_sentinel_warden || null; + this.potionLevel = data?.tag?.ExtraAttributes?.potion_level || null; + this.potion = data?.tag?.ExtraAttributes?.potion || null; + this.potionEffects = data?.tag?.ExtraAttributes?.effects + ? data?.tag?.ExtraAttributes?.effects.map((effect: Record) => new SkyBlockPotionEffect(effect)) + : null; + this.potionType = data?.tag?.ExtraAttributes?.potion_type || null; + this.isSplashPotion = Boolean(data?.tag?.ExtraAttributes?.splash || 0); + this.potionName = data?.tag?.ExtraAttributes?.potion_name || null; + this.isDungeonPotion = Boolean(data?.tag?.ExtraAttributes?.dungeon_potion || 0); + this.gearScore = this.lore ? this.parseGearScore(this.lore) : 0; + this.rarity = this.lore ? this.parseRarity(this.lore[this.lore.length - 1] || '') : 'COMMON'; + this.raw = data; + } + + private parseRarity(str: string): Rarity { + const rarityArray = [ + 'COMMON', + 'UNCOMMON', + 'RARE', + 'EPIC', + 'LEGENDARY', + 'MYTHIC', + 'DIVINE', + 'SPECIAL', + 'VERY SPECIAL' + ]; + for (const rarity of rarityArray) { + if (str.includes(rarity)) return rarity as Rarity; + } + return 'COMMON'; + } + + private parseGearScore(lore: any): number { + for (const line of lore) { + if (line.match(/Gear Score: §[0-9a-f](\d+)/)) return Number(line.match(/Gear Score: §d(\d+)/)[1]); + } + return 0; + } + + toString(): string { + return this.name; + } +} + +export default SkyBlockInventoryItem; diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.test.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.test.ts new file mode 100644 index 000000000..f6a3f07e7 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.test.ts @@ -0,0 +1,19 @@ +import SkyBlockInventoryItemAttribute from './SkyBlockInventoryItemAttribute.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockInventoryItemAttribute', () => { + const data = new SkyBlockInventoryItemAttribute({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockInventoryItemAttribute); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.id); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.ts new file mode 100644 index 000000000..044612695 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.ts @@ -0,0 +1,14 @@ +class SkyBlockInventoryItemAttribute { + id: string | 'UNKNOWN'; + tier: number; + constructor(data: Record) { + this.id = data?.id || 'UNKNOWN'; + this.tier = data?.tier || 0; + } + + toString(): string | 'UNKNOWN' { + return this.id; + } +} + +export default SkyBlockInventoryItemAttribute; diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.test.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.test.ts new file mode 100644 index 000000000..53fc658b2 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.test.ts @@ -0,0 +1,19 @@ +import SkyBlockInventoryItemEnchantment from './SkyBlockInventoryItemEnchantment.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockInventoryItemEnchantment', () => { + const data = new SkyBlockInventoryItemEnchantment({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockInventoryItemEnchantment); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.ts new file mode 100644 index 000000000..86ea93496 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.ts @@ -0,0 +1,14 @@ +class SkyBlockInventoryItemEnchantment { + name: string | 'UNKNOWN'; + level: number; + constructor(data: Record) { + this.name = data?.id || 'UNKNOWN'; + this.level = data?.lvl || 0; + } + + toString(): string | 'UNKNOWN' { + return this.name; + } +} + +export default SkyBlockInventoryItemEnchantment; diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.test.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.test.ts new file mode 100644 index 000000000..c78226fa3 --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.test.ts @@ -0,0 +1,19 @@ +import SkyBlockInventoryItemRune from './SkyBlockInventoryItemRune.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockInventoryItemRune', () => { + const data = new SkyBlockInventoryItemRune({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockInventoryItemRune); + expectTypeOf(data).toEqualTypeOf(); + expect(data.runeId).toBeDefined(); + expectTypeOf(data.runeId).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.runeId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.ts b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.ts new file mode 100644 index 000000000..29a86ef7a --- /dev/null +++ b/src/Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.ts @@ -0,0 +1,14 @@ +class SkyBlockInventoryItemRune { + runeId: string | 'UNKNOWN'; + tier: number; + constructor(data: Record) { + this.runeId = data?.id || 'UNKNOWN'; + this.tier = data?.tier || 0; + } + + toString(): string | 'UNKNOWN' { + return this.runeId; + } +} + +export default SkyBlockInventoryItemRune; diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.test.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.test.ts new file mode 100644 index 000000000..d54e09251 --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberAccessoryBag from './SkyBlockMemberAccessoryBag.js'; +import SkyBlockMemberAccessoryBagTuning from './SkyBlockMemberAccessoryBagTuning.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockMemberPower } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberAccessoryBag', () => { + const data = new SkyBlockMemberAccessoryBag({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberAccessoryBag); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selectedPower).toBeDefined(); + expectTypeOf(data.selectedPower).toEqualTypeOf(); + expect(data.unlockedPowers).toBeDefined(); + expectTypeOf(data.unlockedPowers).toEqualTypeOf(); + expect(data.bagUpgradesPurchased).toBeDefined(); + expect(data.bagUpgradesPurchased).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bagUpgradesPurchased).toEqualTypeOf(); + expect(data.highestMagicalPower).toBeDefined(); + expect(data.highestMagicalPower).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestMagicalPower).toEqualTypeOf(); + expect(data.tuning).toBeDefined(); + expect(data.tuning).toBeInstanceOf(SkyBlockMemberAccessoryBagTuning); + expectTypeOf(data.tuning).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockMemberPower | null>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.selectedPower); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.ts new file mode 100644 index 000000000..df1c60e08 --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.ts @@ -0,0 +1,34 @@ +import SkyBlockMemberAccessoryBagTuning from './SkyBlockMemberAccessoryBagTuning.js'; +import type { SkyBlockMemberPower } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberAccessoryBag { + selectedPower: SkyBlockMemberPower | null; + unlockedPowers: SkyBlockMemberPower[]; + bagUpgradesPurchased: number; + highestMagicalPower: number; + tuning: SkyBlockMemberAccessoryBagTuning; + constructor(data: Record) { + this.selectedPower = data?.selected_power || null; + this.unlockedPowers = data?.unlocked_powers || [ + 'Fortuitous ', + 'Pretty', + 'Protected', + 'Simple', + 'Warrior', + 'Commando', + 'Disciplined', + 'Inspired', + 'Ominous ', + 'Prepared' + ]; + this.bagUpgradesPurchased = data?.bag_upgrades_purchased || 0; + this.highestMagicalPower = data?.highest_magical_power || 0; + this.tuning = new SkyBlockMemberAccessoryBagTuning(data?.tuning || {}); + } + + toString(): SkyBlockMemberPower | null { + return this.selectedPower; + } +} + +export default SkyBlockMemberAccessoryBag; diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.test.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.test.ts new file mode 100644 index 000000000..3312b25ae --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.test.ts @@ -0,0 +1,42 @@ +import SkyBlockMemberAccessoryBagTuning from './SkyBlockMemberAccessoryBagTuning.js'; +import SkyBlockMemberAccessoryBagTuningSlot from './SkyBlockMemberAccessoryBagTuningSlot.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberAccessoryBagTuning', () => { + const data = new SkyBlockMemberAccessoryBagTuning({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberAccessoryBagTuning); + expectTypeOf(data).toEqualTypeOf(); + expect(data.highestUnlockedSlot).toBeDefined(); + expect(data.highestUnlockedSlot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestUnlockedSlot).toEqualTypeOf(); + expect(data.slot1).toBeDefined(); + expect(data.slot1).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot1).toEqualTypeOf(); + expect(data.slot2).toBeDefined(); + expect(data.slot2).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot2).toEqualTypeOf(); + expect(data.slot3).toBeDefined(); + expect(data.slot3).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot3).toEqualTypeOf(); + expect(data.slot4).toBeDefined(); + expect(data.slot4).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot4).toEqualTypeOf(); + expect(data.slot5).toBeDefined(); + expect(data.slot5).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot5).toEqualTypeOf(); + expect(data.slot6).toBeDefined(); + expect(data.slot6).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot6).toEqualTypeOf(); + expect(data.slot7).toBeDefined(); + expect(data.slot7).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot7).toEqualTypeOf(); + expect(data.slot8).toBeDefined(); + expect(data.slot8).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data.slot8).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.highestUnlockedSlot); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.ts new file mode 100644 index 000000000..475d525ab --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.ts @@ -0,0 +1,30 @@ +import SkyBlockMemberAccessoryBagTuningSlot from './SkyBlockMemberAccessoryBagTuningSlot.js'; + +class SkyBlockMemberAccessoryBagTuning { + highestUnlockedSlot: number; + slot1: SkyBlockMemberAccessoryBagTuningSlot; + slot2: SkyBlockMemberAccessoryBagTuningSlot; + slot3: SkyBlockMemberAccessoryBagTuningSlot; + slot4: SkyBlockMemberAccessoryBagTuningSlot; + slot5: SkyBlockMemberAccessoryBagTuningSlot; + slot6: SkyBlockMemberAccessoryBagTuningSlot; + slot7: SkyBlockMemberAccessoryBagTuningSlot; + slot8: SkyBlockMemberAccessoryBagTuningSlot; + constructor(data: Record) { + this.highestUnlockedSlot = data?.highest_unlocked_slot || 1; + this.slot1 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_0 || {}, Boolean(data?.slot_0)); + this.slot2 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_1 || {}, Boolean(data?.slot_1)); + this.slot3 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_2 || {}, Boolean(data?.slot_2)); + this.slot4 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_3 || {}, Boolean(data?.slot_3)); + this.slot5 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_4 || {}, Boolean(data?.slot_4)); + this.slot6 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_5 || {}, Boolean(data?.slot_5)); + this.slot7 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_6 || {}, Boolean(data?.slot_6)); + this.slot8 = new SkyBlockMemberAccessoryBagTuningSlot(data?.slot_7 || {}, Boolean(data?.slot_7)); + } + + toString(): number { + return this.highestUnlockedSlot; + } +} + +export default SkyBlockMemberAccessoryBagTuning; diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.test.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.test.ts new file mode 100644 index 000000000..7f74cfa2c --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.test.ts @@ -0,0 +1,44 @@ +import SkyBlockMemberAccessoryBagTuningSlot from './SkyBlockMemberAccessoryBagTuningSlot.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberAccessoryBagTuningSlot', () => { + const data = new SkyBlockMemberAccessoryBagTuningSlot({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberAccessoryBagTuningSlot); + expectTypeOf(data).toEqualTypeOf(); + expect(data.unlocked).toBeDefined(); + expectTypeOf(data.unlocked).toEqualTypeOf(); + expect(data.purchasedTimestamp).toBeDefined(); + expectTypeOf(data.purchasedTimestamp).toEqualTypeOf(); + expect(data.purchasedDate).toBeDefined(); + expectTypeOf(data.purchasedDate).toEqualTypeOf(); + expect(data.health).toBeDefined(); + expect(data.health).toBeGreaterThanOrEqual(0); + expectTypeOf(data.health).toEqualTypeOf(); + expect(data.defense).toBeDefined(); + expect(data.defense).toBeGreaterThanOrEqual(0); + expectTypeOf(data.defense).toEqualTypeOf(); + expect(data.walkSpeed).toBeDefined(); + expect(data.walkSpeed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.walkSpeed).toEqualTypeOf(); + expect(data.strength).toBeDefined(); + expect(data.strength).toBeGreaterThanOrEqual(0); + expectTypeOf(data.strength).toEqualTypeOf(); + expect(data.criticalDamage).toBeDefined(); + expect(data.criticalDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.criticalDamage).toEqualTypeOf(); + expect(data.criticalChance).toBeDefined(); + expect(data.criticalChance).toBeGreaterThanOrEqual(0); + expectTypeOf(data.criticalChance).toEqualTypeOf(); + expect(data.attackSpeed).toBeDefined(); + expect(data.attackSpeed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.attackSpeed).toEqualTypeOf(); + expect(data.intelligence).toBeDefined(); + expect(data.intelligence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.intelligence).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => boolean>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.unlocked); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.ts b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.ts new file mode 100644 index 000000000..8907eb233 --- /dev/null +++ b/src/Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.ts @@ -0,0 +1,32 @@ +class SkyBlockMemberAccessoryBagTuningSlot { + unlocked: boolean; + purchasedTimestamp: number | null; + purchasedDate: Date | null; + health: number; + defense: number; + walkSpeed: number; + strength: number; + criticalDamage: number; + criticalChance: number; + attackSpeed: number; + intelligence: number; + constructor(data: Record, unlocked: boolean = false) { + this.unlocked = unlocked; + this.purchasedTimestamp = data?.purchase_ts || null; + this.purchasedDate = this.purchasedTimestamp ? new Date(this.purchasedTimestamp) : null; + this.health = data?.health || 0; + this.defense = data?.defense || 0; + this.walkSpeed = data?.walk_speed || 0; + this.strength = data?.strength || 0; + this.criticalDamage = data?.critical_damage || 0; + this.criticalChance = data?.critical_chance || 0; + this.attackSpeed = data?.attack_speed || 0; + this.intelligence = data?.intelligence || 0; + } + + toString(): boolean { + return this.unlocked; + } +} + +export default SkyBlockMemberAccessoryBagTuningSlot; diff --git a/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.test.ts b/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.test.ts new file mode 100644 index 000000000..ed34daa20 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.test.ts @@ -0,0 +1,40 @@ +import SkyBlockMemberBestiary from './SkyBlockMemberBestiary.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BestiaryCategory } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberBestiary', () => { + const data = new SkyBlockMemberBestiary({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberBestiary); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expectTypeOf(data.kills).toEqualTypeOf>(); + expect(data.deaths).toBeDefined(); + expectTypeOf(data.deaths).toEqualTypeOf>(); + expect(data.lastClaimedMilestone).toBeDefined(); + expect(data.lastClaimedMilestone).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastClaimedMilestone).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.maxLevel).toBeDefined(); + expect(data.maxLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxLevel).toEqualTypeOf(); + expect(data.familiesUnlocked).toBeDefined(); + expect(data.familiesUnlocked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familiesUnlocked).toEqualTypeOf(); + expect(data.familiesCompleted).toBeDefined(); + expect(data.familiesCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familiesCompleted).toEqualTypeOf(); + expect(data.totalFamilies).toBeDefined(); + expect(data.totalFamilies).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalFamilies).toEqualTypeOf(); + expect(data.familyTiers).toBeDefined(); + expect(data.familyTiers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.familyTiers).toEqualTypeOf(); + expect(data.maxFamilyTiers).toBeDefined(); + expect(data.maxFamilyTiers).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxFamilyTiers).toEqualTypeOf(); + expect(data.categories).toBeDefined(); + expectTypeOf(data.categories).toEqualTypeOf>(); +}); diff --git a/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.ts b/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.ts new file mode 100644 index 000000000..68e065db3 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.ts @@ -0,0 +1,95 @@ +import { BestiaryBrackets, BestiaryMobs } from '../../../../Utils/Constants.js'; +import type { BestiaryCategory, BestiaryMob, BestiaryStats, RawBestiaryMob } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberBestiary { + kills: Record; + deaths: Record; + lastClaimedMilestone: number; + level: number; + maxLevel: number; + familiesUnlocked: number; + familiesCompleted: number; + totalFamilies: number; + familyTiers: number; + maxFamilyTiers: number; + categories: Record; + constructor(data: Record) { + this.kills = data?.kills || {}; + this.deaths = data?.deaths || {}; + this.lastClaimedMilestone = data?.milestone?.last_claimed_milestone || 0; + const parsed = this.getBestiary(); + this.level = parsed.level; + this.maxLevel = parsed.maxLevel; + this.familiesUnlocked = parsed.familiesUnlocked; + this.familiesCompleted = parsed.familiesCompleted; + this.totalFamilies = parsed.totalFamilies; + this.familyTiers = parsed.familyTiers; + this.maxFamilyTiers = parsed.maxFamilyTiers; + this.categories = parsed.categories; + } + + // Credit: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/d73d449ec52f0af3c8a2fa04b79a969a6734e0b2/src/lib/server/stats/bestiary.ts + private getBestiaryMobs(mobList: RawBestiaryMob[]): BestiaryMob[] { + const output: BestiaryMob[] = []; + for (const mob of mobList) { + const mobBracket = BestiaryBrackets?.[mob.bracket] || []; + + const totalKills = mob.mobs.reduce((acc, mob) => acc + (this.kills[mob] || 0), 0); + const maxKills = mob.cap; + const nextTierKills = mobBracket.find((tier: number) => totalKills < tier && tier <= maxKills); + const tier = nextTierKills ? mobBracket.indexOf(nextTierKills) : mobBracket.indexOf(maxKills) + 1; + + output.push({ + name: mob.name, + kills: totalKills, + nextTierKills: nextTierKills ?? null, + maxKills: maxKills, + tier: tier, + maxTier: mobBracket.indexOf(maxKills) + 1 + }); + } + + return output; + } + + private getBestiary(): BestiaryStats { + const categories = {} as Record; + for (const [category, categoryData] of Object.entries(BestiaryMobs)) { + categories[category] = { + name: categoryData.name, + mobs: this.getBestiaryMobs(categoryData.mobs), + mobsUnlocked: 0, + mobsMaxed: 0 + }; + + categories[category].mobsUnlocked = categories[category].mobs.reduce( + (acc, mob) => acc + (mob.kills > 0 ? 1 : 0), + 0 + ); + categories[category].mobsMaxed = categories[category].mobs.reduce( + (acc, mob) => acc + (mob.kills >= mob.maxKills ? 1 : 0), + 0 + ); + } + + const mobs = Object.values(categories).flatMap((category) => Object.values(category.mobs)); + const maxMilestone = mobs.map((mob) => mob.maxTier).reduce((acc, cur) => acc + cur, 0); + const milestone = mobs.map((mob) => mob.tier).reduce((acc, cur) => acc + cur, 0); + const familiesMaxed = mobs.filter((mob) => mob.tier === mob.maxTier).length; + const familiesUnlocked = mobs.filter((mob) => mob.kills > 0).length; + const totalFamilies = mobs.length; + + return { + level: milestone / 10, + maxLevel: maxMilestone / 10, + familiesUnlocked: familiesUnlocked, + familiesCompleted: familiesMaxed, + totalFamilies: totalFamilies, + familyTiers: milestone, + maxFamilyTiers: maxMilestone, + categories: categories + }; + } +} + +export default SkyBlockMemberBestiary; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.test.ts new file mode 100644 index 000000000..c090389ae --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.test.ts @@ -0,0 +1,63 @@ +import SkyBlockMemberChocolateFactory from './SkyBlockMemberChocolateFactory.js'; +import SkyBlockMemberChocolateFactoryEggs from './SkyBlockMemberChocolateFactoryEggs.js'; +import SkyBlockMemberChocolateFactoryEmployees from './SkyBlockMemberChocolateFactoryEmployees.js'; +import SkyBlockMemberChocolateFactoryHitmen from './SkyBlockMemberChocolateFactoryHitmen.js'; +import SkyBlockMemberChocolateFactoryTimeTower from './SkyBlockMemberChocolateFactoryTimeTower.js'; +import SkyBlockMemberChocolateFactoryUpgrades from './SkyBlockMemberChocolateFactoryUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockArea } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberChocolateFactory', () => { + const data = new SkyBlockMemberChocolateFactory({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactory); + expectTypeOf(data).toEqualTypeOf(); + expect(data.employees).toBeDefined(); + expect(data.employees).toBeInstanceOf(SkyBlockMemberChocolateFactoryEmployees); + expectTypeOf(data.employees).toEqualTypeOf(); + expect(data.timeTower).toBeDefined(); + expect(data.timeTower).toBeInstanceOf(SkyBlockMemberChocolateFactoryTimeTower); + expectTypeOf(data.timeTower).toEqualTypeOf(); + expect(data.upgrades).toBeDefined(); + expect(data.upgrades).toBeInstanceOf(SkyBlockMemberChocolateFactoryUpgrades); + expectTypeOf(data.upgrades).toEqualTypeOf(); + expect(data.hitman).toBeDefined(); + expect(data.hitman).toBeInstanceOf(SkyBlockMemberChocolateFactoryHitmen); + expectTypeOf(data.hitman).toEqualTypeOf(); + expect(data.currentChocolate).toBeDefined(); + expect(data.currentChocolate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.currentChocolate).toEqualTypeOf(); + expect(data.chocolateSincePrestige).toBeDefined(); + expect(data.chocolateSincePrestige).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chocolateSincePrestige).toEqualTypeOf(); + expect(data.totalChocolate).toBeDefined(); + expect(data.totalChocolate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalChocolate).toEqualTypeOf(); + expect(data.barnCapacity).toBeDefined(); + expect(data.barnCapacity).toBeGreaterThanOrEqual(0); + expectTypeOf(data.barnCapacity).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expect(data.prestige).toBeGreaterThanOrEqual(0); + expectTypeOf(data.prestige).toEqualTypeOf(); + expect(data.lastViewedChocolateFactory).toBeDefined(); + expect(data.lastViewedChocolateFactory).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastViewedChocolateFactory).toEqualTypeOf(); + expect(data.lastViewedChocolateFactoryDate).toBeDefined(); + expect(data.lastViewedChocolateFactoryDate).toBeInstanceOf(Date); + expectTypeOf(data.lastViewedChocolateFactoryDate).toEqualTypeOf(); + expect(data.supremeChocolateBars).toBeDefined(); + expect(data.supremeChocolateBars).toBeGreaterThanOrEqual(0); + expectTypeOf(data.supremeChocolateBars).toEqualTypeOf(); + expect(data.eggs).toBeDefined(); + expect(data.eggs).toBeInstanceOf(SkyBlockMemberChocolateFactoryEggs); + expectTypeOf(data.eggs).toEqualTypeOf(); + expect(data.foundRabbits).toBeDefined(); + expectTypeOf(data.foundRabbits).toEqualTypeOf>(); + expect(data.foundEggLocations).toBeDefined(); + expectTypeOf(data.foundEggLocations).toEqualTypeOf>(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.currentChocolate); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.ts new file mode 100644 index 000000000..8c786706e --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.ts @@ -0,0 +1,52 @@ +import SkyBlockMemberChocolateFactoryEggs from './SkyBlockMemberChocolateFactoryEggs.js'; +import SkyBlockMemberChocolateFactoryEmployees from './SkyBlockMemberChocolateFactoryEmployees.js'; +import SkyBlockMemberChocolateFactoryHitmen from './SkyBlockMemberChocolateFactoryHitmen.js'; +import SkyBlockMemberChocolateFactoryTimeTower from './SkyBlockMemberChocolateFactoryTimeTower.js'; +import SkyBlockMemberChocolateFactoryUpgrades from './SkyBlockMemberChocolateFactoryUpgrades.js'; +import type { SkyBlockArea } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberChocolateFactory { + employees: SkyBlockMemberChocolateFactoryEmployees; + timeTower: SkyBlockMemberChocolateFactoryTimeTower; + upgrades: SkyBlockMemberChocolateFactoryUpgrades; + hitman: SkyBlockMemberChocolateFactoryHitmen; + currentChocolate: number; + chocolateSincePrestige: number; + totalChocolate: number; + barnCapacity: number; + prestige: number; + lastViewedChocolateFactory: number; + lastViewedChocolateFactoryDate: Date; + supremeChocolateBars: number; + eggs: SkyBlockMemberChocolateFactoryEggs; + foundRabbits: Record; + foundEggLocations: Record; + constructor(data: Record) { + this.employees = new SkyBlockMemberChocolateFactoryEmployees(data?.employees || {}); + this.timeTower = new SkyBlockMemberChocolateFactoryTimeTower(data?.time_tower || {}); + this.upgrades = new SkyBlockMemberChocolateFactoryUpgrades(data || {}); + this.hitman = new SkyBlockMemberChocolateFactoryHitmen(data?.rabbit_hitmen || {}); + this.currentChocolate = data?.chocolate || 0; + this.chocolateSincePrestige = data?.chocolate_since_prestige || 0; + this.totalChocolate = data?.total_chocolate || 0; + this.barnCapacity = data?.rabbit_barn_capacity_level || 0; + this.prestige = data?.chocolate_level || 0; + this.lastViewedChocolateFactory = data?.last_viewed_chocolate_factory || 0; + this.lastViewedChocolateFactoryDate = new Date(this.lastViewedChocolateFactory); + this.supremeChocolateBars = data?.supreme_chocolate_bars || 0; + this.eggs = new SkyBlockMemberChocolateFactoryEggs(data?.rabbits?.collected_eggs || {}); + this.foundRabbits = Object.keys(data?.rabbits || {}) + .filter((key) => key !== 'collected_eggs' && key !== 'collected_locations') + .reduce((obj: Record, key: string) => { + obj[key] = data.rabbits[key]; + return obj; + }, {}); + this.foundEggLocations = data?.rabbits?.collected_locations || {}; + } + + toString(): number { + return this.currentChocolate; + } +} + +export default SkyBlockMemberChocolateFactory; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.test.ts new file mode 100644 index 000000000..bebfe4eed --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.test.ts @@ -0,0 +1,27 @@ +import SkyBlockMemberChocolateFactoryEggs from './SkyBlockMemberChocolateFactoryEggs.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberChocolateFactoryEggs', () => { + const data = new SkyBlockMemberChocolateFactoryEggs({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactoryEggs); + expectTypeOf(data).toEqualTypeOf(); + expect(data.breakfast).toBeDefined(); + expect(data.breakfast).toBeGreaterThanOrEqual(0); + expectTypeOf(data.breakfast).toEqualTypeOf(); + expect(data.lunch).toBeDefined(); + expect(data.lunch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lunch).toEqualTypeOf(); + expect(data.dinner).toBeDefined(); + expect(data.dinner).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dinner).toEqualTypeOf(); + expect(data.brunch).toBeDefined(); + expect(data.brunch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.brunch).toEqualTypeOf(); + expect(data.dejeuner).toBeDefined(); + expect(data.dejeuner).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dejeuner).toEqualTypeOf(); + expect(data.supper).toBeDefined(); + expect(data.supper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.supper).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.ts new file mode 100644 index 000000000..9179ec4d0 --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.ts @@ -0,0 +1,18 @@ +class SkyBlockMemberChocolateFactoryEggs { + breakfast: number; + lunch: number; + dinner: number; + brunch: number; + dejeuner: number; + supper: number; + constructor(data: Record) { + this.breakfast = data?.breakfast || 0; + this.lunch = data?.lunch || 0; + this.dinner = data?.dinner || 0; + this.brunch = data?.brunch || 0; + this.dejeuner = data?.dejeuner || 0; + this.supper = data?.supper || 0; + } +} + +export default SkyBlockMemberChocolateFactoryEggs; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.test.ts new file mode 100644 index 000000000..5ff9ef749 --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.test.ts @@ -0,0 +1,30 @@ +import SkyBlockMemberChocolateFactoryEmployees from './SkyBlockMemberChocolateFactoryEmployees.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberChocolateFactoryEmployees', () => { + const data = new SkyBlockMemberChocolateFactoryEmployees({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactoryEmployees); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bro).toBeDefined(); + expect(data.bro).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bro).toEqualTypeOf(); + expect(data.cousin).toBeDefined(); + expect(data.cousin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.cousin).toEqualTypeOf(); + expect(data.sis).toBeDefined(); + expect(data.sis).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sis).toEqualTypeOf(); + expect(data.father).toBeDefined(); + expect(data.father).toBeGreaterThanOrEqual(0); + expectTypeOf(data.father).toEqualTypeOf(); + expect(data.grandma).toBeDefined(); + expect(data.grandma).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grandma).toEqualTypeOf(); + expect(data.dog).toBeDefined(); + expect(data.dog).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dog).toEqualTypeOf(); + expect(data.uncle).toBeDefined(); + expect(data.uncle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.uncle).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.ts new file mode 100644 index 000000000..d9c69584f --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.ts @@ -0,0 +1,20 @@ +class SkyBlockMemberChocolateFactoryEmployees { + bro: number; + cousin: number; + sis: number; + father: number; + grandma: number; + dog: number; + uncle: number; + constructor(data: Record) { + this.bro = data?.rabbit_bro || 0; + this.cousin = data?.rabbit_cousin || 0; + this.father = data?.rabbit_father || 0; + this.grandma = data?.rabbit_grandma || 0; + this.sis = data?.rabbit_sis || 0; + this.dog = data?.rabbit_dog || 0; + this.uncle = data?.rabbit_uncle || 0; + } +} + +export default SkyBlockMemberChocolateFactoryEmployees; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.test.ts new file mode 100644 index 000000000..149a16bda --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.test.ts @@ -0,0 +1,32 @@ +import SkyBlockMemberChocolateFactoryHitmen from './SkyBlockMemberChocolateFactoryHitmen.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberChocolateFactoryHitmen', () => { + const data = new SkyBlockMemberChocolateFactoryHitmen({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactoryHitmen); + expectTypeOf(data).toEqualTypeOf(); + expect(data.rabbitHitmenSlots).toBeDefined(); + expect(data.rabbitHitmenSlots).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rabbitHitmenSlots).toEqualTypeOf(); + expect(data.missedUncollectedEggs).toBeDefined(); + expect(data.missedUncollectedEggs).toBeGreaterThanOrEqual(0); + expectTypeOf(data.missedUncollectedEggs).toEqualTypeOf(); + expect(data.eggSlotCooldownMark).toBeDefined(); + expect(data.eggSlotCooldownMark).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggSlotCooldownMark).toEqualTypeOf(); + expect(data.eggSlotCooldownMarkDate).toBeDefined(); + expect(data.eggSlotCooldownMarkDate).toBeInstanceOf(Date); + expectTypeOf(data.eggSlotCooldownMarkDate).toEqualTypeOf(); + expect(data.eggSlotCooldownExpire).toBeDefined(); + expect(data.eggSlotCooldownExpire).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eggSlotCooldownExpire).toEqualTypeOf(); + expect(data.eggSlotCooldownExpireDate).toBeDefined(); + expect(data.eggSlotCooldownExpireDate).toBeInstanceOf(Date); + expectTypeOf(data.eggSlotCooldownExpireDate).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.rabbitHitmenSlots); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.ts new file mode 100644 index 000000000..aa12dd44f --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.ts @@ -0,0 +1,22 @@ +class SkyBlockMemberChocolateFactoryHitmen { + rabbitHitmenSlots: number; + missedUncollectedEggs: number; + eggSlotCooldownMark: number; + eggSlotCooldownMarkDate: Date; + eggSlotCooldownExpire: number; + eggSlotCooldownExpireDate: Date; + constructor(data: Record) { + this.rabbitHitmenSlots = data?.rabbit_hitmen_slots || 0; + this.missedUncollectedEggs = data?.missed_uncollected_eggs || 0; + this.eggSlotCooldownMark = data?.egg_slot_cooldown_mark || 0; + this.eggSlotCooldownMarkDate = new Date(this.eggSlotCooldownMark); + this.eggSlotCooldownExpire = this.eggSlotCooldownMark + (data?.egg_slot_cooldown_sum || 0); + this.eggSlotCooldownExpireDate = new Date(this.eggSlotCooldownExpire); + } + + toString(): number { + return this.rabbitHitmenSlots; + } +} + +export default SkyBlockMemberChocolateFactoryHitmen; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.test.ts new file mode 100644 index 000000000..8ed2c51fd --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.test.ts @@ -0,0 +1,32 @@ +import SkyBlockMemberChocolateFactoryTimeTower from './SkyBlockMemberChocolateFactoryTimeTower.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberChocolateFactoryTimeTower', () => { + const data = new SkyBlockMemberChocolateFactoryTimeTower({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactoryTimeTower); + expectTypeOf(data).toEqualTypeOf(); + expect(data.charges).toBeDefined(); + expect(data.charges).toBeGreaterThanOrEqual(0); + expectTypeOf(data.charges).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.activationTime).toBeDefined(); + expect(data.activationTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.activationTime).toEqualTypeOf(); + expect(data.activationTimeDate).toBeDefined(); + expect(data.activationTimeDate).toBeInstanceOf(Date); + expectTypeOf(data.activationTimeDate).toEqualTypeOf(); + expect(data.lastChargeTime).toBeDefined(); + expect(data.lastChargeTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastChargeTime).toEqualTypeOf(); + expect(data.lastChargeTimeDate).toBeDefined(); + expect(data.lastChargeTimeDate).toBeInstanceOf(Date); + expectTypeOf(data.lastChargeTimeDate).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.ts new file mode 100644 index 000000000..5c9544420 --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.ts @@ -0,0 +1,22 @@ +class SkyBlockMemberChocolateFactoryTimeTower { + charges: number; + level: number; + activationTime: number; + activationTimeDate: Date; + lastChargeTime: number; + lastChargeTimeDate: Date; + constructor(data: Record) { + this.charges = data?.charges || 0; + this.level = data?.level || 0; + this.activationTime = data?.activation_time || 0; + this.activationTimeDate = new Date(this.activationTime); + this.lastChargeTime = data?.last_charge_time || 0; + this.lastChargeTimeDate = new Date(this.lastChargeTime); + } + + toString(): number { + return this.level; + } +} + +export default SkyBlockMemberChocolateFactoryTimeTower; diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.test.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.test.ts new file mode 100644 index 000000000..bb17a485a --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberChocolateFactoryUpgrades from './SkyBlockMemberChocolateFactoryUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberChocolateFactoryUpgrades', () => { + const data = new SkyBlockMemberChocolateFactoryUpgrades({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberChocolateFactoryUpgrades); + expectTypeOf(data).toEqualTypeOf(); + expect(data.click).toBeDefined(); + expect(data.click).toBeGreaterThanOrEqual(0); + expectTypeOf(data.click).toEqualTypeOf(); + expect(data.chocolateMultiplier).toBeDefined(); + expect(data.chocolateMultiplier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chocolateMultiplier).toEqualTypeOf(); + expect(data.rabbitRarity).toBeDefined(); + expect(data.rabbitRarity).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rabbitRarity).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.ts b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.ts new file mode 100644 index 000000000..18a261739 --- /dev/null +++ b/src/Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberChocolateFactoryUpgrades { + click: number; + chocolateMultiplier: number; + rabbitRarity: number; + constructor(data: Record) { + this.click = data?.click_upgrades || 0; + this.chocolateMultiplier = data?.chocolate_multiplier_upgrades || 0; + this.rabbitRarity = data?.rabbit_rarity_upgrades || 0; + } +} + +export default SkyBlockMemberChocolateFactoryUpgrades; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.test.ts new file mode 100644 index 000000000..d0507420e --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.test.ts @@ -0,0 +1,47 @@ +/* eslint-disable @stylistic/max-len */ +import SkyBlockMemberCrimsonIsle from './SkyBlockMemberCrimsonIsle.js'; +import SkyBlockMemberCrimsonIsleAbiphone from './SkyBlockMemberCrimsonIsleAbiphone.js'; +import SkyBlockMemberCrimsonIsleDojo from './SkyBlockMemberCrimsonIsleDojo.js'; +import SkyBlockMemberCrimsonIsleKuudra from './SkyBlockMemberCrimsonIsleKuudra.js'; +import SkyBlockMemberCrimsonIsleMatriarch from './SkyBlockMemberCrimsonIsleMatriarch.js'; +import SkyBlockMemberCrimsonIsleTrophyFish from './SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CrimsonIsleBoss, CrimsonIsleFaction } from '../../../../Types/SkyBlock.js'; +/* eslint-enable @stylistic/max-len */ + +test('SkyBlockMemberCrimsonIsle', () => { + const data = new SkyBlockMemberCrimsonIsle({ stats: 'meow' }, { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsle); + expectTypeOf(data).toEqualTypeOf(); + expect(data.dojo).toBeDefined(); + expect(data.dojo).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojo); + expectTypeOf(data.dojo).toEqualTypeOf(); + expect(data.kuudra).toBeDefined(); + expect(data.kuudra).toBeInstanceOf(SkyBlockMemberCrimsonIsleKuudra); + expectTypeOf(data.kuudra).toEqualTypeOf(); + expect(data.matriarch).toBeDefined(); + expect(data.matriarch).toBeInstanceOf(SkyBlockMemberCrimsonIsleMatriarch); + expectTypeOf(data.matriarch).toEqualTypeOf(); + expect(data.abiphone).toBeDefined(); + expect(data.abiphone).toBeInstanceOf(SkyBlockMemberCrimsonIsleAbiphone); + expectTypeOf(data.abiphone).toEqualTypeOf(); + expect(data.faction).toBeDefined(); + expectTypeOf(data.faction).toEqualTypeOf(); + expect(data.magesReputation).toBeDefined(); + expect(data.magesReputation).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magesReputation).toEqualTypeOf(); + expect(data.barbariansReputation).toBeDefined(); + expect(data.barbariansReputation).toBeGreaterThanOrEqual(0); + expectTypeOf(data.barbariansReputation).toEqualTypeOf(); + expect(data.lastMiniBossesKilled).toBeDefined(); + expectTypeOf(data.lastMiniBossesKilled).toEqualTypeOf(); + expect(data.trophyFishing).toBeDefined(); + expect(data.trophyFishing).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFish); + expectTypeOf(data.trophyFishing).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => CrimsonIsleFaction | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.faction); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.ts new file mode 100644 index 000000000..24b64b17a --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.ts @@ -0,0 +1,40 @@ +/* eslint-disable @stylistic/max-len */ +import SkyBlockMemberCrimsonIsleAbiphone from './SkyBlockMemberCrimsonIsleAbiphone.js'; +import SkyBlockMemberCrimsonIsleDojo from './SkyBlockMemberCrimsonIsleDojo.js'; +import SkyBlockMemberCrimsonIsleKuudra from './SkyBlockMemberCrimsonIsleKuudra.js'; +import SkyBlockMemberCrimsonIsleMatriarch from './SkyBlockMemberCrimsonIsleMatriarch.js'; +import SkyBlockMemberCrimsonIsleTrophyFish from './SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.js'; +import type { CrimsonIsleBoss, CrimsonIsleFaction } from '../../../../Types/SkyBlock.js'; +/* eslint-enable @stylistic/max-len */ + +class SkyBlockMemberCrimsonIsle { + dojo: SkyBlockMemberCrimsonIsleDojo; + kuudra: SkyBlockMemberCrimsonIsleKuudra; + matriarch: SkyBlockMemberCrimsonIsleMatriarch; + abiphone: SkyBlockMemberCrimsonIsleAbiphone; + faction: CrimsonIsleFaction | 'UNKNOWN'; + magesReputation: number; + barbariansReputation: number; + lastMiniBossesKilled: CrimsonIsleBoss[]; + trophyFishing: SkyBlockMemberCrimsonIsleTrophyFish; + constructor(data: Record, trophyFish: Record) { + this.dojo = new SkyBlockMemberCrimsonIsleDojo(data?.dojo || {}); + this.kuudra = new SkyBlockMemberCrimsonIsleKuudra( + data?.kuudra_completed_tiers || {}, + data?.kuudra_party_finder || {} + ); + this.matriarch = new SkyBlockMemberCrimsonIsleMatriarch(data?.matriarch || {}); + this.abiphone = new SkyBlockMemberCrimsonIsleAbiphone(data?.abiphone || {}); + this.faction = data?.selected_faction || 'UNKNOWN'; + this.magesReputation = data?.mages_reputation || 0; + this.barbariansReputation = data?.barbarians_reputation || 0; + this.lastMiniBossesKilled = data?.last_minibosses_killed || []; + this.trophyFishing = new SkyBlockMemberCrimsonIsleTrophyFish(trophyFish); + } + + toString(): CrimsonIsleFaction | 'UNKNOWN' { + return this.faction; + } +} + +export default SkyBlockMemberCrimsonIsle; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.test.ts new file mode 100644 index 000000000..8bff2b33a --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.test.ts @@ -0,0 +1,35 @@ +import SkyBlockMemberCrimsonIsleAbiphone from './SkyBlockMemberCrimsonIsleAbiphone.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { + AbiphoneContact, + AbiphoneContactSort, + CrimsonIsleRingtone, + RawAbiphoneData +} from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberCrimsonIsleAbiphone', () => { + const data = new SkyBlockMemberCrimsonIsleAbiphone({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleAbiphone); + expectTypeOf(data).toEqualTypeOf(); + expect(data.contactData).toBeDefined(); + expectTypeOf(data.contactData).toEqualTypeOf>(); + expect(data.activeContacts).toBeDefined(); + expectTypeOf(data.activeContacts).toEqualTypeOf(); + expect(data.ringtone).toBeDefined(); + expectTypeOf(data.ringtone).toEqualTypeOf(); + expect(data.sort).toBeDefined(); + expectTypeOf(data.sort).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expectTypeOf(data.games).toEqualTypeOf>(); + expect(data.operatorChip).toBeDefined(); + expectTypeOf(data.operatorChip).toEqualTypeOf>(); + expect(data.trioContactAddons).toBeDefined(); + expect(data.trioContactAddons).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trioContactAddons).toEqualTypeOf(); + expect(data.hasUsedSiriusPersonalPhoneNumberItem).toBeDefined(); + expectTypeOf(data.hasUsedSiriusPersonalPhoneNumberItem).toEqualTypeOf(); + expect(data.lastDyeCalledYear).toBeDefined(); + expect(data.lastDyeCalledYear).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastDyeCalledYear).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.ts new file mode 100644 index 000000000..f36d797ce --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.ts @@ -0,0 +1,31 @@ +import type { + AbiphoneContact, + AbiphoneContactSort, + CrimsonIsleRingtone, + RawAbiphoneData +} from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberCrimsonIsleAbiphone { + contactData: Record; + activeContacts: AbiphoneContact[]; + ringtone: CrimsonIsleRingtone; + sort: AbiphoneContactSort | 'UNKNOWN'; + games: Record; + operatorChip: Record; + trioContactAddons: number; + hasUsedSiriusPersonalPhoneNumberItem: boolean; + lastDyeCalledYear: number; + constructor(data: Record) { + this.contactData = data?.contact_data || {}; + this.activeContacts = data?.active_contacts || []; + this.ringtone = data?.selected_ringtone || 'DEFAULT'; + this.sort = data?.selected_sort || 'UNKNOWN'; + this.games = data?.games || {}; + this.operatorChip = data?.operator_chip || {}; + this.trioContactAddons = data?.trio_contact_addons || 0; + this.hasUsedSiriusPersonalPhoneNumberItem = data?.has_used_sirius_personal_phone_number_item || false; + this.lastDyeCalledYear = data?.last_dye_called_year || 0; + } +} + +export default SkyBlockMemberCrimsonIsleAbiphone; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.test.ts new file mode 100644 index 000000000..6176ec8de --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.test.ts @@ -0,0 +1,39 @@ +import SkyBlockMemberCrimsonIsleDojo from './SkyBlockMemberCrimsonIsleDojo.js'; +import SkyBlockMemberCrimsonIsleDojoMinigame from './SkyBlockMemberCrimsonIsleDojoMinigame.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CrimsonIsleBelt } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberCrimsonIsleDojo', () => { + const data = new SkyBlockMemberCrimsonIsleDojo({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojo); + expectTypeOf(data).toEqualTypeOf(); + expect(data.force).toBeDefined(); + expect(data.force).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.force).toEqualTypeOf(); + expect(data.stamina).toBeDefined(); + expect(data.stamina).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.stamina).toEqualTypeOf(); + expect(data.mastery).toBeDefined(); + expect(data.mastery).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.mastery).toEqualTypeOf(); + expect(data.discipline).toBeDefined(); + expect(data.discipline).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.discipline).toEqualTypeOf(); + expect(data.swiftness).toBeDefined(); + expect(data.swiftness).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.swiftness).toEqualTypeOf(); + expect(data.tenacity).toBeDefined(); + expect(data.tenacity).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.tenacity).toEqualTypeOf(); + expect(data.control).toBeDefined(); + expect(data.control).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data.control).toEqualTypeOf(); + expect(data.belt).toBeDefined(); + expectTypeOf(data.belt).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => CrimsonIsleBelt>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.belt); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.ts new file mode 100644 index 000000000..637e596ee --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.ts @@ -0,0 +1,52 @@ +import SkyBlockMemberCrimsonIsleDojoMinigame from './SkyBlockMemberCrimsonIsleDojoMinigame.js'; +import type { CrimsonIsleBelt } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberCrimsonIsleDojo { + force: SkyBlockMemberCrimsonIsleDojoMinigame; + stamina: SkyBlockMemberCrimsonIsleDojoMinigame; + mastery: SkyBlockMemberCrimsonIsleDojoMinigame; + discipline: SkyBlockMemberCrimsonIsleDojoMinigame; + swiftness: SkyBlockMemberCrimsonIsleDojoMinigame; + tenacity: SkyBlockMemberCrimsonIsleDojoMinigame; + control: SkyBlockMemberCrimsonIsleDojoMinigame; + belt: CrimsonIsleBelt; + constructor(data: Record) { + this.force = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'mob_kb'); + this.stamina = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'wall_jump'); + this.mastery = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'archer'); + this.discipline = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'sword_swap'); + this.swiftness = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'snake'); + this.tenacity = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'fireball'); + this.control = new SkyBlockMemberCrimsonIsleDojoMinigame(data || {}, 'lock_head'); + this.belt = this.getBelt( + this.force.points + + this.stamina.points + + this.mastery.points + + this.discipline.points + + this.swiftness.points + + this.tenacity.points + + this.control.points + ); + } + + toString(): CrimsonIsleBelt { + return this.belt; + } + + private getBelt(points: number): CrimsonIsleBelt { + if (points >= 7000) { + return 'Black'; + } else if (points >= 6000) { + return 'Brown'; + } else if (points >= 4000) { + return 'Blue'; + } else if (points >= 2000) { + return 'Green'; + } else if (points >= 1000) { + return 'Yellow'; + } + return 'White'; + } +} + +export default SkyBlockMemberCrimsonIsleDojo; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.test.ts new file mode 100644 index 000000000..605001dc4 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberCrimsonIsleDojoMinigame from './SkyBlockMemberCrimsonIsleDojoMinigame.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CrimsonIsleDojoRank } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberCrimsonIsleDojoMinigame', () => { + const data = new SkyBlockMemberCrimsonIsleDojoMinigame({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleDojoMinigame); + expectTypeOf(data).toEqualTypeOf(); + expect(data.points).toBeDefined(); + expect(data.points).toBeGreaterThanOrEqual(0); + expectTypeOf(data.points).toEqualTypeOf(); + expect(data.time).toBeDefined(); + expect(data.time).toBeGreaterThanOrEqual(0); + expectTypeOf(data.time).toEqualTypeOf(); + expect(data.rank).toBeDefined(); + expectTypeOf(data.rank).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => CrimsonIsleDojoRank>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.rank); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.ts new file mode 100644 index 000000000..4c36edce3 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.ts @@ -0,0 +1,33 @@ +import type { CrimsonIsleDojoRank } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberCrimsonIsleDojoMinigame { + points: number; + time: number; + rank: CrimsonIsleDojoRank; + constructor(data: Record, type: string) { + this.points = data?.[`dojo_points_${type}`] || 0; + this.time = data?.[`dojo_time_${type}`] || 0; + this.rank = this.getScore(this.points); + } + + toString(): CrimsonIsleDojoRank { + return this.rank; + } + + private getScore(points: number): CrimsonIsleDojoRank { + if (points >= 1000) { + return 'S'; + } else if (points >= 800) { + return 'A'; + } else if (points >= 600) { + return 'B'; + } else if (points >= 400) { + return 'C'; + } else if (points >= 200) { + return 'D'; + } + return 'F'; + } +} + +export default SkyBlockMemberCrimsonIsleDojoMinigame; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.test.ts new file mode 100644 index 000000000..1d533925f --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.test.ts @@ -0,0 +1,51 @@ +import SkyBlockMemberCrimsonIsleKuudra from './SkyBlockMemberCrimsonIsleKuudra.js'; +import SkyBlockMemberCrimsonIsleKuudraPartyFinder from './SkyBlockMemberCrimsonIsleKuudraPartyFinder.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberCrimsonIsleKuudra', () => { + const data = new SkyBlockMemberCrimsonIsleKuudra({ stats: 'meow' }, { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleKuudra); + expectTypeOf(data).toEqualTypeOf(); + expect(data.basicCompletions).toBeDefined(); + expect(data.basicCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.basicCompletions).toEqualTypeOf(); + expect(data.highestWaveBasic).toBeDefined(); + expect(data.highestWaveBasic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestWaveBasic).toEqualTypeOf(); + expect(data.hotCompletions).toBeDefined(); + expect(data.hotCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hotCompletions).toEqualTypeOf(); + expect(data.highestWaveHot).toBeDefined(); + expect(data.highestWaveHot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestWaveHot).toEqualTypeOf(); + expect(data.burningCompletions).toBeDefined(); + expect(data.burningCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.burningCompletions).toEqualTypeOf(); + expect(data.highestWaveBurning).toBeDefined(); + expect(data.highestWaveBurning).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestWaveBurning).toEqualTypeOf(); + expect(data.fieryCompletions).toBeDefined(); + expect(data.fieryCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fieryCompletions).toEqualTypeOf(); + expect(data.highestWaveFiery).toBeDefined(); + expect(data.highestWaveFiery).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestWaveFiery).toEqualTypeOf(); + expect(data.infernalCompletions).toBeDefined(); + expect(data.infernalCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.infernalCompletions).toEqualTypeOf(); + expect(data.highestWaveInfernal).toBeDefined(); + expect(data.highestWaveInfernal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestWaveInfernal).toEqualTypeOf(); + expect(data.partyFinderOptions).toBeDefined(); + expect(data.partyFinderOptions).toBeInstanceOf(SkyBlockMemberCrimsonIsleKuudraPartyFinder); + expectTypeOf(data.partyFinderOptions).toEqualTypeOf(); + expect(data.totalCompletions).toBeDefined(); + expect(data.totalCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalCompletions).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.totalCompletions); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.ts new file mode 100644 index 000000000..5ae712ba4 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.ts @@ -0,0 +1,41 @@ +import SkyBlockMemberCrimsonIsleKuudraPartyFinder from './SkyBlockMemberCrimsonIsleKuudraPartyFinder.js'; + +class SkyBlockMemberCrimsonIsleKuudra { + basicCompletions: number; + highestWaveBasic: number; + hotCompletions: number; + highestWaveHot: number; + burningCompletions: number; + highestWaveBurning: number; + fieryCompletions: number; + highestWaveFiery: number; + infernalCompletions: number; + highestWaveInfernal: number; + partyFinderOptions: SkyBlockMemberCrimsonIsleKuudraPartyFinder; + totalCompletions: number; + constructor(data: Record, partyFinderOptions: Record) { + this.basicCompletions = data?.none || 0; + this.highestWaveBasic = data?.highest_wave_none || 0; + this.hotCompletions = data?.hot || 0; + this.highestWaveHot = data?.highest_wave_hot || 0; + this.burningCompletions = data?.burning || 0; + this.highestWaveBurning = data?.highest_wave_burning || 0; + this.fieryCompletions = data?.fiery || 0; + this.highestWaveFiery = data?.highest_wave_fiery || 0; + this.infernalCompletions = data?.infernal || 0; + this.highestWaveInfernal = data?.highest_wave_infernal || 0; + this.partyFinderOptions = new SkyBlockMemberCrimsonIsleKuudraPartyFinder(partyFinderOptions || {}); + this.totalCompletions = + this.basicCompletions + + this.hotCompletions + + this.burningCompletions + + this.fieryCompletions + + this.infernalCompletions; + } + + toString(): number { + return this.totalCompletions; + } +} + +export default SkyBlockMemberCrimsonIsleKuudra; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.test.ts new file mode 100644 index 000000000..e555471ac --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.test.ts @@ -0,0 +1,19 @@ +import SkyBlockMemberCrimsonIsleKuudraPartyFinder from './SkyBlockMemberCrimsonIsleKuudraPartyFinder.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CrimsonIsleKuudraTier } from '../../../../Types/SkyBlock.js'; +import type { UserInput } from '../../../../Types/Global.js'; + +test('SkyBlockMemberCrimsonIsleKuudraPartyFinder', () => { + const data = new SkyBlockMemberCrimsonIsleKuudraPartyFinder({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleKuudraPartyFinder); + expectTypeOf(data).toEqualTypeOf(); + expect(data.searchTier).toBeDefined(); + expectTypeOf(data.searchTier).toEqualTypeOf(); + expect(data.groupBuildTier).toBeDefined(); + expectTypeOf(data.groupBuildTier).toEqualTypeOf(); + expect(data.groupBuildNote).toBeDefined(); + expectTypeOf(data.groupBuildNote).toEqualTypeOf(); + expect(data.groupBuildRequiredCombatLevel).toBeDefined(); + expectTypeOf(data.groupBuildRequiredCombatLevel).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.ts new file mode 100644 index 000000000..5bdaf90ea --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.ts @@ -0,0 +1,17 @@ +import type { CrimsonIsleKuudraTier } from '../../../../Types/SkyBlock.js'; +import type { UserInput } from '../../../../Types/Global.js'; + +class SkyBlockMemberCrimsonIsleKuudraPartyFinder { + searchTier: CrimsonIsleKuudraTier | 'UNKNOWN'; + groupBuildTier: CrimsonIsleKuudraTier | 'UNKNOWN'; + groupBuildNote: UserInput | null; + groupBuildRequiredCombatLevel: number | null; + constructor(data: Record) { + this.searchTier = data?.search_settings?.tier || 'UNKNOWN'; + this.groupBuildTier = data?.group_builder?.tier || 'UNKNOWN'; + this.groupBuildNote = data?.group_builder?.note || null; + this.groupBuildRequiredCombatLevel = data?.group_builder?.combat_level_required || null; + } +} + +export default SkyBlockMemberCrimsonIsleKuudraPartyFinder; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.test.ts new file mode 100644 index 000000000..5f544ef28 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.test.ts @@ -0,0 +1,22 @@ +import SkyBlockMemberCrimsonIsleMatriarch from './SkyBlockMemberCrimsonIsleMatriarch.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberCrimsonIsleMatriarch', () => { + const data = new SkyBlockMemberCrimsonIsleMatriarch({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleMatriarch); + expectTypeOf(data).toEqualTypeOf(); + expect(data.pearlsCollected).toBeDefined(); + expect(data.pearlsCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pearlsCollected).toEqualTypeOf(); + expect(data.lastAttempt).toBeDefined(); + expect(data.lastAttempt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastAttempt).toEqualTypeOf(); + expect(data.recentRefreshes).toBeDefined(); + expectTypeOf(data.recentRefreshes).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.pearlsCollected); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.ts new file mode 100644 index 000000000..f773db8d3 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberCrimsonIsleMatriarch { + pearlsCollected: number; + lastAttempt: number; + recentRefreshes: number[]; + constructor(data: Record) { + this.pearlsCollected = data?.pearls_collected || 0; + this.lastAttempt = data?.last_attempt || 0; + this.recentRefreshes = data?.recent_refreshes || []; + } + + toString(): number { + return this.pearlsCollected; + } +} + +export default SkyBlockMemberCrimsonIsleMatriarch; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.test.ts new file mode 100644 index 000000000..49392fb05 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.test.ts @@ -0,0 +1,104 @@ +import SkyBlockMemberCrimsonIsleTrophyFish from './SkyBlockMemberCrimsonIsleTrophyFish.js'; +import SkyBlockMemberCrimsonIsleTrophyFishCaught from './SkyBlockMemberCrimsonIsleTrophyFishCaught.js'; +import SkyBlockMemberCrimsonIsleTrophyFishFish from './SkyBlockMemberCrimsonIsleTrophyFishFish.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CrimsonIsleTrophyFishRank } from '../../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberCrimsonIsleTrophyFish', () => { + const data = new SkyBlockMemberCrimsonIsleTrophyFish({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFish); + expectTypeOf(data).toEqualTypeOf(); + expect(data.rank).toBeDefined(); + expectTypeOf(data.rank).toEqualTypeOf(); + expect(data.gusher).toBeDefined(); + expect(data.gusher).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.gusher).toEqualTypeOf(); + expect(data.blobfish).toBeDefined(); + expect(data.blobfish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.blobfish).toEqualTypeOf(); + expect(data.lavaHorse).toBeDefined(); + expect(data.lavaHorse).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.lavaHorse).toEqualTypeOf(); + expect(data.goldenFish).toBeDefined(); + expect(data.goldenFish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.goldenFish).toEqualTypeOf(); + expect(data.volcanicStonefish).toBeDefined(); + expect(data.volcanicStonefish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.volcanicStonefish).toEqualTypeOf(); + expect(data.slugfish).toBeDefined(); + expect(data.slugfish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.slugfish).toEqualTypeOf(); + expect(data.vanille).toBeDefined(); + expect(data.vanille).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.vanille).toEqualTypeOf(); + expect(data.obfuscatedFish1).toBeDefined(); + expect(data.obfuscatedFish1).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.obfuscatedFish1).toEqualTypeOf(); + expect(data.obfuscatedFish2).toBeDefined(); + expect(data.obfuscatedFish2).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.obfuscatedFish2).toEqualTypeOf(); + expect(data.obfuscatedFish3).toBeDefined(); + expect(data.obfuscatedFish3).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.obfuscatedFish3).toEqualTypeOf(); + expect(data.sulphurSkitter).toBeDefined(); + expect(data.sulphurSkitter).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.sulphurSkitter).toEqualTypeOf(); + expect(data.skeletonFish).toBeDefined(); + expect(data.skeletonFish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.skeletonFish).toEqualTypeOf(); + expect(data.manaRay).toBeDefined(); + expect(data.manaRay).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.manaRay).toEqualTypeOf(); + expect(data.flyfish).toBeDefined(); + expect(data.flyfish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.flyfish).toEqualTypeOf(); + expect(data.steamingHotFlounder).toBeDefined(); + expect(data.steamingHotFlounder).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.steamingHotFlounder).toEqualTypeOf(); + expect(data.soulFish).toBeDefined(); + expect(data.soulFish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.soulFish).toEqualTypeOf(); + expect(data.karateFish).toBeDefined(); + expect(data.karateFish).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.karateFish).toEqualTypeOf(); + expect(data.moldfin).toBeDefined(); + expect(data.moldfin).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data.moldfin).toEqualTypeOf(); + expect(data.caught).toBeDefined(); + expect(data.caught).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishCaught); + expectTypeOf(data.caught).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => CrimsonIsleTrophyFishRank>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.rank); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); + +test('SkyBlockMemberCrimsonIsleTrophyFish getTrophyFishRank (Bronze)', () => { + const rank = SkyBlockMemberCrimsonIsleTrophyFish.getTrophyFishRank(1); + expect(rank).toBeDefined(); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank).toBe('Bronze'); +}); + +test('SkyBlockMemberCrimsonIsleTrophyFish getTrophyFishRank (Silver)', () => { + const rank = SkyBlockMemberCrimsonIsleTrophyFish.getTrophyFishRank(2); + expect(rank).toBeDefined(); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank).toBe('Silver'); +}); + +test('SkyBlockMemberCrimsonIsleTrophyFish getTrophyFishRank (Gold)', () => { + const rank = SkyBlockMemberCrimsonIsleTrophyFish.getTrophyFishRank(3); + expect(rank).toBeDefined(); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank).toBe('Gold'); +}); + +test('SkyBlockMemberCrimsonIsleTrophyFish getTrophyFishRank (Diamond)', () => { + const rank = SkyBlockMemberCrimsonIsleTrophyFish.getTrophyFishRank(4); + expect(rank).toBeDefined(); + expectTypeOf(rank).toEqualTypeOf(); + expect(rank).toBe('Diamond'); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.ts new file mode 100644 index 000000000..0c3ebba4b --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.ts @@ -0,0 +1,68 @@ +import SkyBlockMemberCrimsonIsleTrophyFishCaught from './SkyBlockMemberCrimsonIsleTrophyFishCaught.js'; +import SkyBlockMemberCrimsonIsleTrophyFishFish from './SkyBlockMemberCrimsonIsleTrophyFishFish.js'; +import type { CrimsonIsleTrophyFishRank } from '../../../../../Types/SkyBlock.js'; + +class SkyBlockMemberCrimsonIsleTrophyFish { + rank: CrimsonIsleTrophyFishRank; + gusher: SkyBlockMemberCrimsonIsleTrophyFishFish; + blobfish: SkyBlockMemberCrimsonIsleTrophyFishFish; + lavaHorse: SkyBlockMemberCrimsonIsleTrophyFishFish; + goldenFish: SkyBlockMemberCrimsonIsleTrophyFishFish; + volcanicStonefish: SkyBlockMemberCrimsonIsleTrophyFishFish; + slugfish: SkyBlockMemberCrimsonIsleTrophyFishFish; + vanille: SkyBlockMemberCrimsonIsleTrophyFishFish; + obfuscatedFish1: SkyBlockMemberCrimsonIsleTrophyFishFish; + obfuscatedFish2: SkyBlockMemberCrimsonIsleTrophyFishFish; + obfuscatedFish3: SkyBlockMemberCrimsonIsleTrophyFishFish; + sulphurSkitter: SkyBlockMemberCrimsonIsleTrophyFishFish; + skeletonFish: SkyBlockMemberCrimsonIsleTrophyFishFish; + manaRay: SkyBlockMemberCrimsonIsleTrophyFishFish; + flyfish: SkyBlockMemberCrimsonIsleTrophyFishFish; + steamingHotFlounder: SkyBlockMemberCrimsonIsleTrophyFishFish; + soulFish: SkyBlockMemberCrimsonIsleTrophyFishFish; + karateFish: SkyBlockMemberCrimsonIsleTrophyFishFish; + moldfin: SkyBlockMemberCrimsonIsleTrophyFishFish; + caught: SkyBlockMemberCrimsonIsleTrophyFishCaught; + constructor(data: Record) { + const rewards = data?.rewards || [1]; + this.rank = SkyBlockMemberCrimsonIsleTrophyFish.getTrophyFishRank(rewards[rewards.length - 1]); + this.gusher = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'gusher'); + this.blobfish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'blobfish'); + this.lavaHorse = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'lava_horse'); + this.goldenFish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'golden_fish'); + this.volcanicStonefish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'volcanic_stonefish'); + this.slugfish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'slugfish'); + this.vanille = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'vanille'); + this.obfuscatedFish1 = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'obfuscated_fish_1'); + this.obfuscatedFish2 = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'obfuscated_fish_2'); + this.obfuscatedFish3 = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'obfuscated_fish_3'); + this.sulphurSkitter = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'sulphur_skitter'); + this.skeletonFish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'skeleton_fish'); + this.manaRay = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'mana_ray'); + this.flyfish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'flyfish'); + this.steamingHotFlounder = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'steaming_hot_flounder'); + this.soulFish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'soul_fish'); + this.karateFish = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'karate_fish'); + this.moldfin = new SkyBlockMemberCrimsonIsleTrophyFishFish(data, 'moldfin'); + this.caught = new SkyBlockMemberCrimsonIsleTrophyFishCaught(this); + } + + toString(): CrimsonIsleTrophyFishRank { + return this.rank; + } + + static getTrophyFishRank(level: number): CrimsonIsleTrophyFishRank { + switch (level) { + case 2: + return 'Silver'; + case 3: + return 'Gold'; + case 4: + return 'Diamond'; + default: + return 'Bronze'; + } + } +} + +export default SkyBlockMemberCrimsonIsleTrophyFish; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.test.ts new file mode 100644 index 000000000..5e27d56b5 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.test.ts @@ -0,0 +1,32 @@ +import SkyBlockMemberCrimsonIsleTrophyFish from './SkyBlockMemberCrimsonIsleTrophyFish.js'; +import SkyBlockMemberCrimsonIsleTrophyFishCaught from './SkyBlockMemberCrimsonIsleTrophyFishCaught.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberCrimsonIsleTrophyFishCaught', () => { + const data = new SkyBlockMemberCrimsonIsleTrophyFishCaught( + new SkyBlockMemberCrimsonIsleTrophyFish({ stats: 'meow' }) + ); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishCaught); + expectTypeOf(data).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.bronze).toBeDefined(); + expect(data.bronze).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bronze).toEqualTypeOf(); + expect(data.silver).toBeDefined(); + expect(data.silver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silver).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expect(data.gold).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gold).toEqualTypeOf(); + expect(data.diamond).toBeDefined(); + expect(data.diamond).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamond).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.ts new file mode 100644 index 000000000..c2d451493 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.ts @@ -0,0 +1,40 @@ +import SkyBlockMemberCrimsonIsleTrophyFishFish from './SkyBlockMemberCrimsonIsleTrophyFishFish.js'; +import type SkyBlockMemberCrimsonIsleTrophyFish from './SkyBlockMemberCrimsonIsleTrophyFish.js'; +import type { CrimsonIsleTrophyFishRank } from '../../../../../Types/SkyBlock.js'; + +class SkyBlockMemberCrimsonIsleTrophyFishCaught { + total: number; + bronze: number; + silver: number; + gold: number; + diamond: number; + constructor(data: SkyBlockMemberCrimsonIsleTrophyFish) { + this.total = this.getTrophyFishPerRank(data, 'Total'); + this.bronze = this.getTrophyFishPerRank(data, 'Bronze'); + this.silver = this.getTrophyFishPerRank(data, 'Silver'); + this.gold = this.getTrophyFishPerRank(data, 'Gold'); + this.diamond = this.getTrophyFishPerRank(data, 'Diamond'); + } + + toString(): number { + return this.total; + } + + private getTrophyFishPerRank( + data: SkyBlockMemberCrimsonIsleTrophyFish, + rank: CrimsonIsleTrophyFishRank | 'Total' + ): number { + let num = 0; + + (Object.keys(data) as (keyof SkyBlockMemberCrimsonIsleTrophyFish)[]) + .filter((fish) => !['toString', 'rank', 'caught'].includes(fish as string)) + .forEach((fishName) => { + const fish = data[fishName] as SkyBlockMemberCrimsonIsleTrophyFishFish; + num += fish[rank.toLowerCase() as keyof SkyBlockMemberCrimsonIsleTrophyFishFish] as number; + }); + + return num; + } +} + +export default SkyBlockMemberCrimsonIsleTrophyFishCaught; diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.test.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.test.ts new file mode 100644 index 000000000..2cdcbd262 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberCrimsonIsleTrophyFishFish from './SkyBlockMemberCrimsonIsleTrophyFishFish.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberCrimsonIsleTrophyFishFish', () => { + const data = new SkyBlockMemberCrimsonIsleTrophyFishFish({ stats: 'meow' }, 'mrrp'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCrimsonIsleTrophyFishFish); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bronze).toBeDefined(); + expect(data.bronze).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bronze).toEqualTypeOf(); + expect(data.silver).toBeDefined(); + expect(data.silver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silver).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expect(data.gold).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gold).toEqualTypeOf(); + expect(data.diamond).toBeDefined(); + expect(data.diamond).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamond).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.ts b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.ts new file mode 100644 index 000000000..2f2d7e222 --- /dev/null +++ b/src/Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.ts @@ -0,0 +1,20 @@ +class SkyBlockMemberCrimsonIsleTrophyFishFish { + bronze: number; + silver: number; + gold: number; + diamond: number; + total: number; + constructor(data: Record, fishName: string) { + this.bronze = data?.[`${fishName}_bronze`] || 0; + this.silver = data?.[`${fishName}_silver`] || 0; + this.gold = data?.[`${fishName}_gold`] || 0; + this.diamond = data?.[`${fishName}_diamond`] || 0; + this.total = this.bronze + this.silver + this.gold + this.diamond; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberCrimsonIsleTrophyFishFish; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.test.ts new file mode 100644 index 000000000..bcb1bf735 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.test.ts @@ -0,0 +1,38 @@ +import SkyBlockMemberDungeons from './SkyBlockMemberDungeons.js'; +import SkyBlockMemberDungeonsClasses from './SkyBlockMemberDungeonsClasses.js'; +import SkyBlockMemberDungeonsMode from './SkyBlockMemberDungeonsMode.js'; +import SkyBlockMemberDungeonsTreasureRun from './SkyBlockMemberDungeonsTreasureRun.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { DungeonFloor, SkillLevelData } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberDungeons', () => { + const data = new SkyBlockMemberDungeons({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeons); + expectTypeOf(data).toEqualTypeOf(); + expect(data.catacombs).toBeDefined(); + expect(data.catacombs).toBeInstanceOf(SkyBlockMemberDungeonsMode); + expectTypeOf(data.catacombs).toEqualTypeOf(); + expect(data.masterCatacombs).toBeDefined(); + expect(data.masterCatacombs).toBeInstanceOf(SkyBlockMemberDungeonsMode); + expectTypeOf(data.masterCatacombs).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.classes).toBeDefined(); + expect(data.classes).toBeInstanceOf(SkyBlockMemberDungeonsClasses); + expectTypeOf(data.classes).toEqualTypeOf(); + expect(data.unlockedJournals).toBeDefined(); + expectTypeOf(data.unlockedJournals).toEqualTypeOf(); + expect(data.treasures).toBeDefined(); + expectTypeOf(data.treasures).toEqualTypeOf(); + expect(data.lastDungeonRun).toBeDefined(); + expectTypeOf(data.lastDungeonRun).toEqualTypeOf(); + expect(data.secrets).toBeDefined(); + expect(data.secrets).toBeGreaterThanOrEqual(0); + expectTypeOf(data.secrets).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.ts new file mode 100644 index 000000000..d98f6aa59 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.ts @@ -0,0 +1,34 @@ +import SkyBlockMemberDungeonsClasses from './SkyBlockMemberDungeonsClasses.js'; +import SkyBlockMemberDungeonsMode from './SkyBlockMemberDungeonsMode.js'; +import SkyBlockMemberDungeonsTreasureRun from './SkyBlockMemberDungeonsTreasureRun.js'; +import { getLevelByXp } from '../../../../Utils/SkyBlockUtils.js'; +import type { DungeonFloor, SkillLevelData } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberDungeons { + catacombs: SkyBlockMemberDungeonsMode; + masterCatacombs: SkyBlockMemberDungeonsMode; + level: SkillLevelData; + classes: SkyBlockMemberDungeonsClasses; + unlockedJournals: string[]; + treasures: SkyBlockMemberDungeonsTreasureRun[]; + lastDungeonRun: DungeonFloor | 'UNKNOWN'; + secrets: number; + constructor(data: Record) { + this.catacombs = new SkyBlockMemberDungeonsMode(data?.dungeon_types || {}, 'catacombs'); + this.masterCatacombs = new SkyBlockMemberDungeonsMode(data?.dungeon_types || {}, 'master_catacombs'); + this.level = getLevelByXp(data?.dungeon_types?.catacombs?.experience || 0, { type: 'dungeoneering' }); + this.classes = new SkyBlockMemberDungeonsClasses(data); + this.unlockedJournals = data?.dungeon_journal?.unlocked_journals || []; + this.treasures = (data?.treasures?.runs || []).map( + (run: Record) => new SkyBlockMemberDungeonsTreasureRun(run, data?.treasures?.chests) + ); + this.lastDungeonRun = data?.last_dungeon_run || 'UNKNOWN'; + this.secrets = data?.secrets || 0; + } + + toString(): number { + return this.level.level; + } +} + +export default SkyBlockMemberDungeons; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.test.ts new file mode 100644 index 000000000..e13375f8d --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.test.ts @@ -0,0 +1,30 @@ +import SkyBlockMemberDungeonsClasses from './SkyBlockMemberDungeonsClasses.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { DungeonClass, SkillLevelData } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberDungeonsClasses', () => { + const data = new SkyBlockMemberDungeonsClasses({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsClasses); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selected).toBeDefined(); + expectTypeOf(data.selected).toEqualTypeOf(); + expect(data.healer).toBeDefined(); + expectTypeOf(data.healer).toEqualTypeOf(); + expect(data.berserk).toBeDefined(); + expectTypeOf(data.berserk).toEqualTypeOf(); + expect(data.mage).toBeDefined(); + expectTypeOf(data.mage).toEqualTypeOf(); + expect(data.archer).toBeDefined(); + expectTypeOf(data.archer).toEqualTypeOf(); + expect(data.tank).toBeDefined(); + expectTypeOf(data.tank).toEqualTypeOf(); + expect(data.average).toBeDefined(); + expect(data.average).toBeGreaterThanOrEqual(0); + expectTypeOf(data.average).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => DungeonClass | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.selected); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.ts new file mode 100644 index 000000000..3f916aa7f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.ts @@ -0,0 +1,27 @@ +import { getLevelByXp } from '../../../../Utils/SkyBlockUtils.js'; +import type { DungeonClass, SkillLevelData } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberDungeonsClasses { + selected: DungeonClass | 'UNKNOWN'; + healer: SkillLevelData; + berserk: SkillLevelData; + mage: SkillLevelData; + archer: SkillLevelData; + tank: SkillLevelData; + average: number; + constructor(data: Record) { + this.selected = data?.selected_dungeon_class || 'UNKNOWN'; + this.healer = getLevelByXp(data?.player_classes?.healer?.experience || 0, { type: 'dungeoneering' }); + this.berserk = getLevelByXp(data?.player_classes?.berserk?.experience || 0, { type: 'dungeoneering' }); + this.mage = getLevelByXp(data?.player_classes?.mage?.experience || 0, { type: 'dungeoneering' }); + this.archer = getLevelByXp(data?.player_classes?.archer?.experience || 0, { type: 'dungeoneering' }); + this.tank = getLevelByXp(data?.player_classes?.tank?.experience || 0, { type: 'dungeoneering' }); + this.average = (this.healer.level + this.berserk.level + this.mage.level + this.archer.level + this.tank.level) / 5; + } + + toString(): DungeonClass | 'UNKNOWN' { + return this.selected; + } +} + +export default SkyBlockMemberDungeonsClasses; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.test.ts new file mode 100644 index 000000000..d0f7708bf --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.test.ts @@ -0,0 +1,56 @@ +import SkyBlockMemberDungeonsFloor from './SkyBlockMemberDungeonsFloor.js'; +import SkyBlockMemberDungeonsFloorRun from './SkyBlockMemberDungeonsFloorRun.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberDungeonsFloor', () => { + const data = new SkyBlockMemberDungeonsFloor({ stats: 'meow' }, '0'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data).toEqualTypeOf(); + expect(data.timesPlayed).toBeDefined(); + expect(data.timesPlayed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timesPlayed).toEqualTypeOf(); + expect(data.bestRuns).toBeDefined(); + expectTypeOf(data.bestRuns).toEqualTypeOf(); + expect(data.bestScore).toBeDefined(); + expect(data.bestScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestScore).toEqualTypeOf(); + expect(data.mobsKilled).toBeDefined(); + expect(data.mobsKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mobsKilled).toEqualTypeOf(); + expect(data.mostMobsKilled).toBeDefined(); + expect(data.mostMobsKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostMobsKilled).toEqualTypeOf(); + expect(data.mostDamageBerserk).toBeDefined(); + expect(data.mostDamageBerserk).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageBerserk).toEqualTypeOf(); + expect(data.mostDamageMage).toBeDefined(); + expect(data.mostDamageMage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageMage).toEqualTypeOf(); + expect(data.mostDamageHealer).toBeDefined(); + expect(data.mostDamageHealer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageHealer).toEqualTypeOf(); + expect(data.mostDamageArcher).toBeDefined(); + expect(data.mostDamageArcher).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageArcher).toEqualTypeOf(); + expect(data.mostDamageTank).toBeDefined(); + expect(data.mostDamageTank).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageTank).toEqualTypeOf(); + expect(data.mostHealing).toBeDefined(); + expect(data.mostHealing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostHealing).toEqualTypeOf(); + expect(data.watcherKills).toBeDefined(); + expect(data.watcherKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.watcherKills).toEqualTypeOf(); + expect(data.fastestTimeS).toBeDefined(); + expect(data.fastestTimeS).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTimeS).toEqualTypeOf(); + expect(data.fastestTimeSPlus).toBeDefined(); + expect(data.fastestTimeSPlus).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTimeSPlus).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.timesPlayed); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.ts new file mode 100644 index 000000000..827e4713f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.ts @@ -0,0 +1,42 @@ +import SkyBlockMemberDungeonsFloorRun from './SkyBlockMemberDungeonsFloorRun.js'; + +class SkyBlockMemberDungeonsFloor { + timesPlayed: number; + bestRuns: SkyBlockMemberDungeonsFloorRun[]; + bestScore: number; + mobsKilled: number; + mostMobsKilled: number; + mostDamageBerserk: number; + mostDamageMage: number; + mostDamageHealer: number; + mostDamageArcher: number; + mostDamageTank: number; + mostHealing: number; + watcherKills: number; + fastestTimeS: number; + fastestTimeSPlus: number; + constructor(data: Record, floorNumber: '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7') { + this.timesPlayed = data?.tier_completions?.[floorNumber] || 0; + this.bestRuns = (data?.best_runs?.[floorNumber] || []).map( + (run: Record) => new SkyBlockMemberDungeonsFloorRun(run) + ); + this.bestScore = data?.best_score?.[floorNumber] || 0; + this.mobsKilled = data?.mobs_killed?.[floorNumber] || 0; + this.mostMobsKilled = data?.most_mobs_killed?.[floorNumber] || 0; + this.mostDamageBerserk = data?.most_damage_berserk?.[floorNumber] || 0; + this.mostDamageMage = data?.most_damage_mage?.[floorNumber] || 0; + this.mostDamageHealer = data?.most_damage_healer?.[floorNumber] || 0; + this.mostDamageArcher = data?.most_damage_archer?.[floorNumber] || 0; + this.mostDamageTank = data?.most_damage_tank?.[floorNumber] || 0; + this.mostHealing = data?.most_healing?.[floorNumber] || 0; + this.watcherKills = data?.watcher_kills?.[floorNumber] || 0; + this.fastestTimeS = data?.fastest_time_s?.[floorNumber] || 0; + this.fastestTimeSPlus = data?.fastest_time_s_plus?.[floorNumber] || 0; + } + + toString(): number { + return this.timesPlayed; + } +} + +export default SkyBlockMemberDungeonsFloor; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.test.ts new file mode 100644 index 000000000..f2022c9d9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.test.ts @@ -0,0 +1,59 @@ +import SkyBlockMemberDungeonsFloorRun from './SkyBlockMemberDungeonsFloorRun.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { DungeonClass } from '../../../../Types/SkyBlock.js'; +import type { UUID } from '../../../../Types/Global.js'; + +test('SkyBlockMemberDungeonsFloorRun', () => { + const data = new SkyBlockMemberDungeonsFloorRun({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsFloorRun); + expectTypeOf(data).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expect(data.timestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.explorationScore).toBeDefined(); + expect(data.explorationScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.explorationScore).toEqualTypeOf(); + expect(data.speedScore).toBeDefined(); + expect(data.speedScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speedScore).toEqualTypeOf(); + expect(data.skillScore).toBeDefined(); + expect(data.skillScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skillScore).toEqualTypeOf(); + expect(data.bonusScore).toBeDefined(); + expect(data.bonusScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bonusScore).toEqualTypeOf(); + expect(data.score).toBeDefined(); + expect(data.score).toBeGreaterThanOrEqual(0); + expectTypeOf(data.score).toEqualTypeOf(); + expect(data.selectedClass).toBeDefined(); + expectTypeOf(data.selectedClass).toEqualTypeOf(); + expect(data.teammates).toBeDefined(); + expectTypeOf(data.teammates).toEqualTypeOf(); + expect(data.elapsedTime).toBeDefined(); + expect(data.elapsedTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.elapsedTime).toEqualTypeOf(); + expect(data.damageDealt).toBeDefined(); + expect(data.damageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageDealt).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.mobsKilled).toBeDefined(); + expect(data.mobsKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mobsKilled).toEqualTypeOf(); + expect(data.secretsFound).toBeDefined(); + expect(data.secretsFound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.secretsFound).toEqualTypeOf(); + expect(data.damageMitigated).toBeDefined(); + expect(data.damageMitigated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.damageMitigated).toEqualTypeOf(); + expect(data.allyHealing).toBeDefined(); + expect(data.allyHealing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.allyHealing).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.score); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.ts new file mode 100644 index 000000000..c0802972e --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.ts @@ -0,0 +1,43 @@ +import type { DungeonClass } from '../../../../Types/SkyBlock.js'; +import type { UUID } from '../../../../Types/Global.js'; + +class SkyBlockMemberDungeonsFloorRun { + timestamp: number; + explorationScore: number; + speedScore: number; + skillScore: number; + bonusScore: number; + score: number; + selectedClass: DungeonClass; + teammates: UUID[]; + elapsedTime: number; + damageDealt: number; + deaths: number; + mobsKilled: number; + secretsFound: number; + damageMitigated: number; + allyHealing: number; + constructor(data: Record) { + this.timestamp = data?.timestamp || 0; + this.explorationScore = data?.score_exploration || 0; + this.speedScore = data?.score_speed || 0; + this.skillScore = data?.score_skill || 0; + this.bonusScore = data?.score_bonus || 0; + this.score = this.explorationScore + this.speedScore + this.skillScore + this.bonusScore; + this.selectedClass = data?.dungeon_class || 'mage'; + this.teammates = data?.teammates || []; + this.elapsedTime = data?.elapsed_time || 0; + this.damageDealt = data?.damage_delt || 0; + this.deaths = data?.deaths || 0; + this.mobsKilled = data?.mobs_killed || 0; + this.secretsFound = data?.secrets_found || 0; + this.damageMitigated = data?.damage_mitigated || 0; + this.allyHealing = data?.ally_healing || 0; + } + + toString(): number { + return this.score; + } +} + +export default SkyBlockMemberDungeonsFloorRun; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.test.ts new file mode 100644 index 000000000..7f6f2da59 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.test.ts @@ -0,0 +1,41 @@ +import SkyBlockMemberDungeonsFloor from './SkyBlockMemberDungeonsFloor.js'; +import SkyBlockMemberDungeonsMode from './SkyBlockMemberDungeonsMode.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberDungeonsMode', () => { + const data = new SkyBlockMemberDungeonsMode({ stats: 'meow' }, 'catacombs'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsMode); + expectTypeOf(data).toEqualTypeOf(); + expect(data.highestFloorCompleted).toBeDefined(); + expect(data.highestFloorCompleted).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestFloorCompleted).toEqualTypeOf(); + expect(data.floor0).toBeDefined(); + expectTypeOf(data.floor0).toEqualTypeOf(); + expect(data.floor1).toBeDefined(); + expect(data.floor1).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor1).toEqualTypeOf(); + expect(data.floor2).toBeDefined(); + expect(data.floor2).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor2).toEqualTypeOf(); + expect(data.floor3).toBeDefined(); + expect(data.floor3).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor3).toEqualTypeOf(); + expect(data.floor4).toBeDefined(); + expect(data.floor4).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor4).toEqualTypeOf(); + expect(data.floor5).toBeDefined(); + expect(data.floor5).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor5).toEqualTypeOf(); + expect(data.floor6).toBeDefined(); + expect(data.floor6).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor6).toEqualTypeOf(); + expect(data.floor7).toBeDefined(); + expect(data.floor7).toBeInstanceOf(SkyBlockMemberDungeonsFloor); + expectTypeOf(data.floor7).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.highestFloorCompleted); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.ts new file mode 100644 index 000000000..3fe409740 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.ts @@ -0,0 +1,31 @@ +import SkyBlockMemberDungeonsFloor from './SkyBlockMemberDungeonsFloor.js'; +import type { DungeonGamemode } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberDungeonsMode { + highestFloorCompleted: number; + floor0: SkyBlockMemberDungeonsFloor | null; + floor1: SkyBlockMemberDungeonsFloor; + floor2: SkyBlockMemberDungeonsFloor; + floor3: SkyBlockMemberDungeonsFloor; + floor4: SkyBlockMemberDungeonsFloor; + floor5: SkyBlockMemberDungeonsFloor; + floor6: SkyBlockMemberDungeonsFloor; + floor7: SkyBlockMemberDungeonsFloor; + constructor(data: Record, type: DungeonGamemode) { + this.highestFloorCompleted = data?.[type]?.highest_tier_completed || 0; + this.floor0 = type === 'catacombs' ? new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '0') : null; + this.floor1 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '1'); + this.floor2 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '2'); + this.floor3 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '3'); + this.floor4 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '4'); + this.floor5 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '5'); + this.floor6 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '6'); + this.floor7 = new SkyBlockMemberDungeonsFloor(data?.[type] || {}, '7'); + } + + toString(): number { + return this.highestFloorCompleted; + } +} + +export default SkyBlockMemberDungeonsMode; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.test.ts new file mode 100644 index 000000000..a55d1bc2b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.test.ts @@ -0,0 +1,36 @@ +import SkyBlockMemberDungeonsTreasureRun from './SkyBlockMemberDungeonsTreasureRun.js'; +import SkyBlockMemberDungeonsTreasuresChest from './SkyBlockMemberDungeonsTreasuresChest.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { DungeonGamemode } from '../../../../Types/SkyBlock.js'; +import type { UUID, UserInput } from '../../../../Types/Global.js'; + +test('SkyBlockMemberDungeonsTreasureRun', () => { + const data = new SkyBlockMemberDungeonsTreasureRun({ stats: 'meow' }, [{ stats: 'meow' }]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsTreasureRun); + expectTypeOf(data).toEqualTypeOf(); + expect(data.runId).toBeDefined(); + expectTypeOf(data.runId).toEqualTypeOf(); + expect(data.completionTimestamp).toBeDefined(); + expect(data.completionTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completionTimestamp).toEqualTypeOf(); + expect(data.completionDate).toBeDefined(); + expect(data.completionDate).toBeInstanceOf(Date); + expectTypeOf(data.completionDate).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.dungeonTier).toBeDefined(); + expect(data.dungeonTier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dungeonTier).toEqualTypeOf(); + expect(data.participants).toBeDefined(); + expectTypeOf(data.participants).toEqualTypeOf< + { playerUUID: UUID; displayName: UserInput; classMilestone: number }[] + >(); + expect(data.chests).toBeDefined(); + expectTypeOf(data.chests).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.runId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.ts new file mode 100644 index 000000000..54d6a5717 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.ts @@ -0,0 +1,30 @@ +import SkyBlockMemberDungeonsTreasuresChest from './SkyBlockMemberDungeonsTreasuresChest.js'; +import type { DungeonGamemode } from '../../../../Types/SkyBlock.js'; +import type { UUID, UserInput } from '../../../../Types/Global.js'; + +class SkyBlockMemberDungeonsTreasureRun { + runId: string; + completionTimestamp: number; + completionDate: Date; + type: DungeonGamemode; + dungeonTier: number; + participants: { playerUUID: UUID; displayName: UserInput; classMilestone: number }[]; + chests: SkyBlockMemberDungeonsTreasuresChest[]; + constructor(data: Record, chestData: Record[]) { + this.runId = data?.run_id || 'UNKNOWN'; + this.completionTimestamp = data?.completion_ts || 0; + this.completionDate = new Date(this.completionTimestamp); + this.type = data?.type || 'catacombs'; + this.dungeonTier = data?.dungeon_tier || 0; + this.participants = data?.participants || []; + this.chests = chestData + .filter((chest) => chest.run_id === this.runId) + .map((chest) => new SkyBlockMemberDungeonsTreasuresChest(chest)); + } + + toString(): string { + return this.runId; + } +} + +export default SkyBlockMemberDungeonsTreasureRun; diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.test.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.test.ts new file mode 100644 index 000000000..4a395327d --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.test.ts @@ -0,0 +1,34 @@ +import SkyBlockMemberDungeonsTreasuresChest from './SkyBlockMemberDungeonsTreasuresChest.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { DungeonsTreasureType } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberDungeonsTreasuresChest', () => { + const data = new SkyBlockMemberDungeonsTreasuresChest({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberDungeonsTreasuresChest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.runId).toBeDefined(); + expectTypeOf(data.runId).toEqualTypeOf(); + expect(data.chestId).toBeDefined(); + expectTypeOf(data.chestId).toEqualTypeOf(); + expect(data.chestType).toBeDefined(); + expectTypeOf(data.chestType).toEqualTypeOf(); + expect(data.rewards).toBeDefined(); + expectTypeOf(data.rewards).toEqualTypeOf(); + expect(data.rolledRNGMeter).toBeDefined(); + expectTypeOf(data.rolledRNGMeter).toEqualTypeOf(); + expect(data.quality).toBeDefined(); + expect(data.quality).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quality).toEqualTypeOf(); + expect(data.shinyEligible).toBeDefined(); + expectTypeOf(data.shinyEligible).toEqualTypeOf(); + expect(data.paid).toBeDefined(); + expectTypeOf(data.paid).toEqualTypeOf(); + expect(data.rerolls).toBeDefined(); + expectTypeOf(data.rerolls).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.runId); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.ts b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.ts new file mode 100644 index 000000000..e2fe6a993 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.ts @@ -0,0 +1,30 @@ +import type { DungeonsTreasureType } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberDungeonsTreasuresChest { + runId: string; + chestId: string; + chestType: DungeonsTreasureType; + rewards: string[]; + rolledRNGMeter: boolean; + quality: number; + shinyEligible: boolean; + paid: boolean; + rerolls: boolean; + constructor(data: Record) { + this.runId = data?.run_id || 'UNKNOWN'; + this.chestId = data?.chest_id || 'UNKNOWN'; + this.chestType = data?.treasure_type || 0; + this.rewards = data?.rewards?.rewards || []; + this.rolledRNGMeter = data?.rewards?.rolled_rng_meter_randomly || false; + this.quality = data?.quality || 0; + this.shinyEligible = data?.shiny_eligible || false; + this.paid = data?.paid || false; + this.rerolls = (data?.rerolls || 0) !== 0; + } + + toString(): string { + return this.runId; + } +} + +export default SkyBlockMemberDungeonsTreasuresChest; diff --git a/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.test.ts b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.test.ts new file mode 100644 index 000000000..aab265fd7 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.test.ts @@ -0,0 +1,9 @@ +import SkyBlockMemberInventoriesArmor from './SkyBlockMemberInventoriesArmor.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesArmor', () => { + const data = new SkyBlockMemberInventoriesArmor({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesArmor); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.ts b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.ts new file mode 100644 index 000000000..2c100f3fb --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberInventoriesArmorDecoded from './SkyBlockMemberInventoriesArmorDecoded.js'; +import SkyBlockMemberInventoriesBaseInventory from '../SkyBlockMemberInventoriesBaseInventory.js'; +import { decode } from '../../../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMemberInventoriesArmor extends SkyBlockMemberInventoriesBaseInventory { + override async decodeData(): Promise { + if (undefined === this.base64 || this.base64 === null) return null; + const decoded = await decode(this.base64); + return new SkyBlockMemberInventoriesArmorDecoded(decoded); + } +} + +export default SkyBlockMemberInventoriesArmor; diff --git a/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.test.ts b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.test.ts new file mode 100644 index 000000000..24690ead0 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.test.ts @@ -0,0 +1,18 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; +import SkyBlockMemberInventoriesArmorDecoded from './SkyBlockMemberInventoriesArmorDecoded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesArmorDecoded', () => { + const data = new SkyBlockMemberInventoriesArmorDecoded({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesArmorDecoded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.helmet).toBeDefined(); + expectTypeOf(data.helmet).toEqualTypeOf(); + expect(data.chestplate).toBeDefined(); + expectTypeOf(data.chestplate).toEqualTypeOf(); + expect(data.leggings).toBeDefined(); + expectTypeOf(data.leggings).toEqualTypeOf(); + expect(data.boots).toBeDefined(); + expectTypeOf(data.boots).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.ts b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.ts new file mode 100644 index 000000000..9a9e3de19 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.ts @@ -0,0 +1,16 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; + +class SkyBlockMemberInventoriesArmorDecoded { + helmet: SkyBlockInventoryItem | null; + chestplate: SkyBlockInventoryItem | null; + leggings: SkyBlockInventoryItem | null; + boots: SkyBlockInventoryItem | null; + constructor(data: Record) { + this.helmet = data[3]?.id ? new SkyBlockInventoryItem(data[3]) : null; + this.chestplate = data[2]?.id ? new SkyBlockInventoryItem(data[2]) : null; + this.leggings = data[1]?.id ? new SkyBlockInventoryItem(data[1]) : null; + this.boots = data[0]?.id ? new SkyBlockInventoryItem(data[0]) : null; + } +} + +export default SkyBlockMemberInventoriesArmorDecoded; diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.test.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.test.ts new file mode 100644 index 000000000..1c246237a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.test.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberInventoriesBackpack from './SkyBlockMemberInventoriesBackpack.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBackpack', () => { + const data = new SkyBlockMemberInventoriesBackpack({ stats: 'meow' }, '0'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBackpack); + expectTypeOf(data).toEqualTypeOf(); + expect(data.backpackItemBase64).toBeDefined(); + expectTypeOf(data.backpackItemBase64).toEqualTypeOf(); + expect(data.backpackContentsBase64).toBeDefined(); + expectTypeOf(data.backpackContentsBase64).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.ts new file mode 100644 index 000000000..b688513cc --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.ts @@ -0,0 +1,21 @@ +import SkyBlockMemberInventoriesBackpackDecoded from './SkyBlockMemberInventoriesBackpackDecoded.js'; +import { decode } from '../../../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMemberInventoriesBackpack { + backpackItemBase64: string; + backpackContentsBase64: string; + constructor(data: Record, slot: string) { + this.backpackItemBase64 = data?.backpackIcons?.[slot]?.data || 'UNKNOWN'; + this.backpackContentsBase64 = data?.backpackContents?.[slot]?.data || 'UNKNOWN'; + } + + async decodeData(): Promise { + if (undefined === this.backpackItemBase64 || this.backpackItemBase64 === null) return null; + if (undefined === this.backpackContentsBase64 || this.backpackContentsBase64 === null) return null; + const backpackIconDecoded = await decode(this.backpackItemBase64); + const backpackItemsDecoded = await decode(this.backpackContentsBase64); + return new SkyBlockMemberInventoriesBackpackDecoded({ backpackIconDecoded, backpackItemsDecoded }); + } +} + +export default SkyBlockMemberInventoriesBackpack; diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.test.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.test.ts new file mode 100644 index 000000000..9252e3028 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.test.ts @@ -0,0 +1,15 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; +import SkyBlockMemberInventoriesBackpackDecoded from './SkyBlockMemberInventoriesBackpackDecoded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBackpackDecoded', () => { + const data = new SkyBlockMemberInventoriesBackpackDecoded({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBackpackDecoded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.icon).toBeDefined(); + expect(data.icon).toBeInstanceOf(SkyBlockInventoryItem); + expectTypeOf(data.icon).toEqualTypeOf(); + expect(data.items).toBeDefined(); + expectTypeOf(data.items).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.ts new file mode 100644 index 000000000..6ee13f990 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.ts @@ -0,0 +1,17 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; + +class SkyBlockMemberInventoriesBackpackDecoded { + icon: SkyBlockInventoryItem; + items: SkyBlockInventoryItem[]; + constructor(data: Record) { + const decoded = data?.backpackItemsDecoded || []; + this.icon = new SkyBlockInventoryItem(decoded?.[0] || {}); + this.items = []; + for (let i = 0; i < decoded.length; i++) { + if (!decoded?.[i]?.id) continue; + this.items.push(new SkyBlockInventoryItem(decoded[i])); + } + } +} + +export default SkyBlockMemberInventoriesBackpackDecoded; diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.test.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.test.ts new file mode 100644 index 000000000..d200bba1f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.test.ts @@ -0,0 +1,46 @@ +import SkyBlockMemberInventoriesBackpack from './SkyBlockMemberInventoriesBackpack.js'; +import SkyBlockMemberInventoriesBackpacks from './SkyBlockMemberInventoriesBackpacks.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBackpacks', () => { + const data = new SkyBlockMemberInventoriesBackpacks({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBackpacks); + expectTypeOf(data).toEqualTypeOf(); + expect(data.backpack1).toBeDefined(); + expectTypeOf(data.backpack1).toEqualTypeOf(); + expect(data.backpack2).toBeDefined(); + expectTypeOf(data.backpack2).toEqualTypeOf(); + expect(data.backpack3).toBeDefined(); + expectTypeOf(data.backpack3).toEqualTypeOf(); + expect(data.backpack4).toBeDefined(); + expectTypeOf(data.backpack4).toEqualTypeOf(); + expect(data.backpack5).toBeDefined(); + expectTypeOf(data.backpack5).toEqualTypeOf(); + expect(data.backpack6).toBeDefined(); + expectTypeOf(data.backpack6).toEqualTypeOf(); + expect(data.backpack7).toBeDefined(); + expectTypeOf(data.backpack7).toEqualTypeOf(); + expect(data.backpack8).toBeDefined(); + expectTypeOf(data.backpack8).toEqualTypeOf(); + expect(data.backpack9).toBeDefined(); + expectTypeOf(data.backpack9).toEqualTypeOf(); + expect(data.backpack10).toBeDefined(); + expectTypeOf(data.backpack10).toEqualTypeOf(); + expect(data.backpack11).toBeDefined(); + expectTypeOf(data.backpack11).toEqualTypeOf(); + expect(data.backpack12).toBeDefined(); + expectTypeOf(data.backpack12).toEqualTypeOf(); + expect(data.backpack13).toBeDefined(); + expectTypeOf(data.backpack13).toEqualTypeOf(); + expect(data.backpack14).toBeDefined(); + expectTypeOf(data.backpack14).toEqualTypeOf(); + expect(data.backpack15).toBeDefined(); + expectTypeOf(data.backpack15).toEqualTypeOf(); + expect(data.backpack16).toBeDefined(); + expectTypeOf(data.backpack16).toEqualTypeOf(); + expect(data.backpack17).toBeDefined(); + expectTypeOf(data.backpack17).toEqualTypeOf(); + expect(data.backpack18).toBeDefined(); + expectTypeOf(data.backpack18).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.ts b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.ts new file mode 100644 index 000000000..8dbca1c6a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.ts @@ -0,0 +1,98 @@ +import SkyBlockMemberInventoriesBackpack from './SkyBlockMemberInventoriesBackpack.js'; + +class SkyBlockMemberInventoriesBackpacks { + backpack1: SkyBlockMemberInventoriesBackpack | null; + backpack2: SkyBlockMemberInventoriesBackpack | null; + backpack3: SkyBlockMemberInventoriesBackpack | null; + backpack4: SkyBlockMemberInventoriesBackpack | null; + backpack5: SkyBlockMemberInventoriesBackpack | null; + backpack6: SkyBlockMemberInventoriesBackpack | null; + backpack7: SkyBlockMemberInventoriesBackpack | null; + backpack8: SkyBlockMemberInventoriesBackpack | null; + backpack9: SkyBlockMemberInventoriesBackpack | null; + backpack10: SkyBlockMemberInventoriesBackpack | null; + backpack11: SkyBlockMemberInventoriesBackpack | null; + backpack12: SkyBlockMemberInventoriesBackpack | null; + backpack13: SkyBlockMemberInventoriesBackpack | null; + backpack14: SkyBlockMemberInventoriesBackpack | null; + backpack15: SkyBlockMemberInventoriesBackpack | null; + backpack16: SkyBlockMemberInventoriesBackpack | null; + backpack17: SkyBlockMemberInventoriesBackpack | null; + backpack18: SkyBlockMemberInventoriesBackpack | null; + constructor(data: Record) { + this.backpack1 = + data?.backpackIcons?.['0']?.data === undefined || data?.backpackContents?.['0']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '0'); + this.backpack2 = + data?.backpackIcons?.['1']?.data === undefined || data?.backpackContents?.['1']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '1'); + this.backpack3 = + data?.backpackIcons?.['2']?.data === undefined || data?.backpackContents?.['2']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '2'); + this.backpack4 = + data?.backpackIcons?.['3']?.data === undefined || data?.backpackContents?.['3']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '3'); + this.backpack5 = + data?.backpackIcons?.['4']?.data === undefined || data?.backpackContents?.['4']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '4'); + this.backpack6 = + data?.backpackIcons?.['5']?.data === undefined || data?.backpackContents?.['5']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '5'); + this.backpack7 = + data?.backpackIcons?.['6']?.data === undefined || data?.backpackContents?.['6']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '6'); + this.backpack8 = + data?.backpackIcons?.['7']?.data === undefined || data?.backpackContents?.['7']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '7'); + this.backpack9 = + data?.backpackIcons?.['8']?.data === undefined || data?.backpackContents?.['8']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '8'); + this.backpack10 = + data?.backpackIcons?.['9']?.data === undefined || data?.backpackContents?.['9']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '9'); + this.backpack11 = + data?.backpackIcons?.['10']?.data === undefined || data?.backpackContents?.['10']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '10'); + this.backpack12 = + data?.backpackIcons?.['11']?.data === undefined || data?.backpackContents?.['11']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '11'); + this.backpack13 = + data?.backpackIcons?.['12']?.data === undefined || data?.backpackContents?.['12']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '12'); + this.backpack14 = + data?.backpackIcons?.['13']?.data === undefined || data?.backpackContents?.['13']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '13'); + this.backpack15 = + data?.backpackIcons?.['14']?.data === undefined || data?.backpackContents?.['14']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '14'); + this.backpack16 = + data?.backpackIcons?.['15']?.data === undefined || data?.backpackContents?.['15']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '15'); + this.backpack17 = + data?.backpackIcons?.['16']?.data === undefined || data?.backpackContents?.['16']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '16'); + this.backpack18 = + data?.backpackIcons?.['17']?.data === undefined || data?.backpackContents?.['17']?.data === undefined + ? null + : new SkyBlockMemberInventoriesBackpack(data, '17'); + } +} + +export default SkyBlockMemberInventoriesBackpacks; diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.test.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.test.ts new file mode 100644 index 000000000..d26412afd --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.test.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberInventoriesBags from './SkyBlockMemberInventoriesBags.js'; +import SkyBlockMemberInventoriesBagsTalisman from './SkyBlockMemberInventoriesBagsTalisman.js'; +import SkyBlockMemberInventoriesInventory from '../Inventory/SkyBlockMemberInventoriesInventory.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBags', () => { + const data = new SkyBlockMemberInventoriesBags({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBags); + expectTypeOf(data).toEqualTypeOf(); + expect(data.potion).toBeDefined(); + expect(data.potion).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.potion).toEqualTypeOf(); + expect(data.talisman).toBeDefined(); + expect(data.talisman).toBeInstanceOf(SkyBlockMemberInventoriesBagsTalisman); + expectTypeOf(data.talisman).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expect(data.fishing).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.sacks).toBeDefined(); + expect(data.sacks).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.sacks).toEqualTypeOf(); + expect(data.quiver).toBeDefined(); + expect(data.quiver).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.quiver).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.ts new file mode 100644 index 000000000..f08ab1e0c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.ts @@ -0,0 +1,19 @@ +import SkyBlockMemberInventoriesBagsTalisman from './SkyBlockMemberInventoriesBagsTalisman.js'; +import SkyBlockMemberInventoriesInventory from '../Inventory/SkyBlockMemberInventoriesInventory.js'; + +class SkyBlockMemberInventoriesBags { + potion: SkyBlockMemberInventoriesInventory; + talisman: SkyBlockMemberInventoriesBagsTalisman; + fishing: SkyBlockMemberInventoriesInventory; + sacks: SkyBlockMemberInventoriesInventory; + quiver: SkyBlockMemberInventoriesInventory; + constructor(data: Record) { + this.potion = new SkyBlockMemberInventoriesInventory(data?.potion_bag || {}); + this.talisman = new SkyBlockMemberInventoriesBagsTalisman(data?.talisman_bag || {}); + this.fishing = new SkyBlockMemberInventoriesInventory(data?.fishing_bag || {}); + this.sacks = new SkyBlockMemberInventoriesInventory(data?.sacks_bag || {}); + this.quiver = new SkyBlockMemberInventoriesInventory(data?.quiver || {}); + } +} + +export default SkyBlockMemberInventoriesBags; diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.test.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.test.ts new file mode 100644 index 000000000..0430fed24 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.test.ts @@ -0,0 +1,9 @@ +import SkyBlockMemberInventoriesBagsTalisman from './SkyBlockMemberInventoriesBagsTalisman.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBagsTalisman', () => { + const data = new SkyBlockMemberInventoriesBagsTalisman({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBagsTalisman); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.ts new file mode 100644 index 000000000..8ee130502 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberInventoriesBagsTalismanDecoded from './SkyBlockMemberInventoriesBagsTalismanDecoded.js'; +import SkyBlockMemberInventoriesBaseInventory from '../SkyBlockMemberInventoriesBaseInventory.js'; +import { decode } from '../../../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMemberInventoriesBagsTalisman extends SkyBlockMemberInventoriesBaseInventory { + override async decodeData(): Promise { + if (undefined === this.base64 || this.base64 === null) return null; + const decoded = await decode(this.base64); + return new SkyBlockMemberInventoriesBagsTalismanDecoded(decoded); + } +} + +export default SkyBlockMemberInventoriesBagsTalisman; diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.test.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.test.ts new file mode 100644 index 000000000..7a7d50b8c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.test.ts @@ -0,0 +1,12 @@ +import SkyBlockMemberInventoriesBagsTalismanDecoded from './SkyBlockMemberInventoriesBagsTalismanDecoded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBagsTalismanDecoded', () => { + const data = new SkyBlockMemberInventoriesBagsTalismanDecoded([]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBagsTalismanDecoded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.magicalPower).toBeDefined(); + expect(data.magicalPower).toBeGreaterThanOrEqual(0); + expectTypeOf(data.magicalPower).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.ts b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.ts new file mode 100644 index 000000000..664b65f59 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.ts @@ -0,0 +1,25 @@ +import SkyBlockMemberInventoriesInventoryDecoded from '../Inventory/SkyBlockMemberInventoriesInventoryDecoded.js'; +import { magicalPowerValues } from '../../../../../Utils/Constants.js'; +import type { Rarity } from '../../../../../Types/SkyBlock.js'; + +class SkyBlockMemberInventoriesBagsTalismanDecoded extends SkyBlockMemberInventoriesInventoryDecoded { + magicalPower: number; + constructor(data: any[]) { + super(data); + this.magicalPower = this.getMagicalPower(); + } + + private getMagicalPowerItem(rarity: Rarity, id: string = 'UNKNOWN') { + if (id === 'HEGEMONY_ARTIFACT') return 2 * (magicalPowerValues?.[rarity] || 0); + if (id === 'RIFT_PRISM') return 11; + return magicalPowerValues?.[rarity] || 0; + } + + private getMagicalPower() { + let magicalPower = 0; + this.items.forEach((item) => (magicalPower += this.getMagicalPowerItem(item.rarity, item.id))); + return magicalPower; + } +} + +export default SkyBlockMemberInventoriesBagsTalismanDecoded; diff --git a/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.test.ts b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.test.ts new file mode 100644 index 000000000..aa88443a2 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.test.ts @@ -0,0 +1,9 @@ +import SkyBlockMemberInventoriesEquipment from './SkyBlockMemberInventoriesEquipment.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesEquipment', () => { + const data = new SkyBlockMemberInventoriesEquipment({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesEquipment); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.ts b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.ts new file mode 100644 index 000000000..5a0d3f9af --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberInventoriesBaseInventory from '../SkyBlockMemberInventoriesBaseInventory.js'; +import SkyBlockMemberInventoriesEquipmentDecoded from './SkyBlockMemberInventoriesEquipmentDecoded.js'; +import { decode } from '../../../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMemberInventoriesEquipment extends SkyBlockMemberInventoriesBaseInventory { + override async decodeData(): Promise { + if (undefined === this.base64 || this.base64 === null) return null; + const decoded = await decode(this.base64); + return new SkyBlockMemberInventoriesEquipmentDecoded(decoded); + } +} + +export default SkyBlockMemberInventoriesEquipment; diff --git a/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.test.ts b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.test.ts new file mode 100644 index 000000000..f8b6927aa --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.test.ts @@ -0,0 +1,18 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; +import SkyBlockMemberInventoriesEquipmentDecoded from './SkyBlockMemberInventoriesEquipmentDecoded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesEquipmentDecoded', () => { + const data = new SkyBlockMemberInventoriesEquipmentDecoded([]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesEquipmentDecoded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.gauntlet).toBeDefined(); + expectTypeOf(data.gauntlet).toEqualTypeOf(); + expect(data.belt).toBeDefined(); + expectTypeOf(data.belt).toEqualTypeOf(); + expect(data.cloak).toBeDefined(); + expectTypeOf(data.cloak).toEqualTypeOf(); + expect(data.necklace).toBeDefined(); + expectTypeOf(data.necklace).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.ts b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.ts new file mode 100644 index 000000000..9c36bc841 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.ts @@ -0,0 +1,16 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; + +class SkyBlockMemberInventoriesEquipmentDecoded { + gauntlet: SkyBlockInventoryItem | null; + belt: SkyBlockInventoryItem | null; + cloak: SkyBlockInventoryItem | null; + necklace: SkyBlockInventoryItem | null; + constructor(data: any[]) { + this.gauntlet = data[3]?.id ? new SkyBlockInventoryItem(data[3]) : null; + this.belt = data[2]?.id ? new SkyBlockInventoryItem(data[2]) : null; + this.cloak = data[1]?.id ? new SkyBlockInventoryItem(data[1]) : null; + this.necklace = data[0]?.id ? new SkyBlockInventoryItem(data[0]) : null; + } +} + +export default SkyBlockMemberInventoriesEquipmentDecoded; diff --git a/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.test.ts b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.test.ts new file mode 100644 index 000000000..5866023b4 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.test.ts @@ -0,0 +1,9 @@ +import SkyBlockMemberInventoriesInventory from './SkyBlockMemberInventoriesInventory.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesInventory', () => { + const data = new SkyBlockMemberInventoriesInventory({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.ts b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.ts new file mode 100644 index 000000000..ce4fcf0e6 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberInventoriesBaseInventory from '../SkyBlockMemberInventoriesBaseInventory.js'; +import SkyBlockMemberInventoriesInventoryDecoded from './SkyBlockMemberInventoriesInventoryDecoded.js'; +import { decode } from '../../../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMemberInventoriesInventory extends SkyBlockMemberInventoriesBaseInventory { + override async decodeData(): Promise { + if (undefined === this.base64 || this.base64 === null) return null; + const decoded = await decode(this.base64); + return new SkyBlockMemberInventoriesInventoryDecoded(decoded); + } +} + +export default SkyBlockMemberInventoriesInventory; diff --git a/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.test.ts b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.test.ts new file mode 100644 index 000000000..7ddccd1df --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.test.ts @@ -0,0 +1,12 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; +import SkyBlockMemberInventoriesInventoryDecoded from './SkyBlockMemberInventoriesInventoryDecoded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesInventoryDecoded', () => { + const data = new SkyBlockMemberInventoriesInventoryDecoded([]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesInventoryDecoded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.items).toBeDefined(); + expectTypeOf(data.items).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.ts b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.ts new file mode 100644 index 000000000..43edaf6aa --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.ts @@ -0,0 +1,15 @@ +import SkyBlockInventoryItem from '../../../Inventory/SkyBlockInventoryItem.js'; + +class SkyBlockMemberInventoriesInventoryDecoded { + items: SkyBlockInventoryItem[]; + constructor(data: any[]) { + this.items = []; + + for (let i = 0; i < data.length; i++) { + if (!data[i]?.id) continue; + this.items.push(new SkyBlockInventoryItem(data[i])); + } + } +} + +export default SkyBlockMemberInventoriesInventoryDecoded; diff --git a/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.test.ts b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.test.ts new file mode 100644 index 000000000..ac7bc9418 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.test.ts @@ -0,0 +1,46 @@ +import SkyBlockMemberInventories from './SkyBlockMemberInventories.js'; +import SkyBlockMemberInventoriesArmor from './Armor/SkyBlockMemberInventoriesArmor.js'; +import SkyBlockMemberInventoriesBackpacks from './Backpacks/SkyBlockMemberInventoriesBackpacks.js'; +import SkyBlockMemberInventoriesBags from './Bags/SkyBlockMemberInventoriesBags.js'; +import SkyBlockMemberInventoriesEquipment from './Equipment/SkyBlockMemberInventoriesEquipment.js'; +import SkyBlockMemberInventoriesInventory from './Inventory/SkyBlockMemberInventoriesInventory.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventories', () => { + const data = new SkyBlockMemberInventories({ stats: 'meow' }, { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventories); + expectTypeOf(data).toEqualTypeOf(); + expect(data.inventory).toBeDefined(); + expect(data.inventory).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.inventory).toEqualTypeOf(); + expect(data.armor).toBeDefined(); + expect(data.armor).toBeInstanceOf(SkyBlockMemberInventoriesArmor); + expectTypeOf(data.armor).toEqualTypeOf(); + expect(data.equipment).toBeDefined(); + expect(data.equipment).toBeInstanceOf(SkyBlockMemberInventoriesEquipment); + expectTypeOf(data.equipment).toEqualTypeOf(); + expect(data.backpacks).toBeDefined(); + expect(data.backpacks).toBeInstanceOf(SkyBlockMemberInventoriesBackpacks); + expectTypeOf(data.backpacks).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.enderChest).toEqualTypeOf(); + expect(data.bags).toBeDefined(); + expect(data.bags).toBeInstanceOf(SkyBlockMemberInventoriesBags); + expectTypeOf(data.bags).toEqualTypeOf(); + expect(data.personalVault).toBeDefined(); + expect(data.personalVault).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.personalVault).toEqualTypeOf(); + expect(data.wardrobe).toBeDefined(); + expect(data.wardrobe).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.wardrobe).toEqualTypeOf(); + expect(data.sacksCounts).toBeDefined(); + expectTypeOf(data.sacksCounts).toEqualTypeOf>(); + expect(data.candy).toBeDefined(); + expect(data.candy).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.candy).toEqualTypeOf(); + expect(data.carnivalMask).toBeDefined(); + expect(data.carnivalMask).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.carnivalMask).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.ts b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.ts new file mode 100644 index 000000000..639a985df --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.ts @@ -0,0 +1,37 @@ +import SkyBlockMemberInventoriesArmor from './Armor/SkyBlockMemberInventoriesArmor.js'; +import SkyBlockMemberInventoriesBackpacks from './Backpacks/SkyBlockMemberInventoriesBackpacks.js'; +import SkyBlockMemberInventoriesBags from './Bags/SkyBlockMemberInventoriesBags.js'; +import SkyBlockMemberInventoriesEquipment from './Equipment/SkyBlockMemberInventoriesEquipment.js'; +import SkyBlockMemberInventoriesInventory from './Inventory/SkyBlockMemberInventoriesInventory.js'; + +class SkyBlockMemberInventories { + inventory: SkyBlockMemberInventoriesInventory; + armor: SkyBlockMemberInventoriesArmor; + equipment: SkyBlockMemberInventoriesEquipment; + backpacks: SkyBlockMemberInventoriesBackpacks; + enderChest: SkyBlockMemberInventoriesInventory; + bags: SkyBlockMemberInventoriesBags; + personalVault: SkyBlockMemberInventoriesInventory; + wardrobe: SkyBlockMemberInventoriesInventory; + sacksCounts: Record; + candy: SkyBlockMemberInventoriesInventory; + carnivalMask: SkyBlockMemberInventoriesInventory; + constructor(data: Record, shared: Record) { + this.inventory = new SkyBlockMemberInventoriesInventory(data?.inv_contents || {}); + this.armor = new SkyBlockMemberInventoriesArmor(data?.inv_armor || {}); + this.equipment = new SkyBlockMemberInventoriesEquipment(data?.equipment_contents || {}); + this.backpacks = new SkyBlockMemberInventoriesBackpacks({ + backpackIcons: data?.backpack_icons || {}, + backpackContents: data?.backpack_contents || {} + }); + this.enderChest = new SkyBlockMemberInventoriesInventory(data?.ender_chest_contents || {}); + this.bags = new SkyBlockMemberInventoriesBags(data?.bag_contents || {}); + this.personalVault = new SkyBlockMemberInventoriesInventory(data?.personal_vault_contents || {}); + this.wardrobe = new SkyBlockMemberInventoriesInventory({ ...(data?.wardrobe_contents || {}) }); + this.sacksCounts = data?.sacks_counts || {}; + this.candy = new SkyBlockMemberInventoriesInventory(shared?.candy_inventory_contents || {}); + this.carnivalMask = new SkyBlockMemberInventoriesInventory(shared?.carnival_mask_inventory_contents || {}); + } +} + +export default SkyBlockMemberInventories; diff --git a/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.test.ts b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.test.ts new file mode 100644 index 000000000..f7763e9c9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.test.ts @@ -0,0 +1,11 @@ +import SkyBlockMemberInventoriesBaseInventory from './SkyBlockMemberInventoriesBaseInventory.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberInventoriesBaseInventory', () => { + const data = new SkyBlockMemberInventoriesBaseInventory({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberInventoriesBaseInventory); + expectTypeOf(data).toEqualTypeOf(); + expect(data.base64).toBeDefined(); + expectTypeOf(data.base64).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.ts b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.ts new file mode 100644 index 000000000..11856eacf --- /dev/null +++ b/src/Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberInventoriesBaseInventory { + base64: string | null; + constructor(data: Record) { + this.base64 = data?.data || null; + } + + decodeData(): Promise | any { + throw new Error("Something went wrong. You shouldn't be seeing this"); + } +} + +export default SkyBlockMemberInventoriesBaseInventory; diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.test.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.test.ts new file mode 100644 index 000000000..3191c3b6c --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.test.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberJacobContest from './SkyBlockMemberJacobContest.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberJacobContest', () => { + const data = new SkyBlockMemberJacobContest({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberJacobContest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.collected).toBeDefined(); + expectTypeOf(data.collected).toEqualTypeOf(); + expect(data.claimedRewards).toBeDefined(); + expectTypeOf(data.claimedRewards).toEqualTypeOf(); + expect(data.claimedPosition).toBeDefined(); + expectTypeOf(data.claimedPosition).toEqualTypeOf(); + expect(data.claimedParticipants).toBeDefined(); + expectTypeOf(data.claimedParticipants).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.ts new file mode 100644 index 000000000..dec551d96 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.ts @@ -0,0 +1,14 @@ +class SkyBlockMemberJacobContest { + collected: number | null; + claimedRewards: boolean | null; + claimedPosition: number | null; + claimedParticipants: number | null; + constructor(data: Record) { + this.collected = data?.collected || null; + this.claimedRewards = data?.claimed_rewards || null; + this.claimedPosition = data?.claimed_position || null; + this.claimedParticipants = data?.claimed_participants || null; + } +} + +export default SkyBlockMemberJacobContest; diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.test.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.test.ts new file mode 100644 index 000000000..f96203abc --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.test.ts @@ -0,0 +1,27 @@ +import SkyBlockMemberJacobContest from './SkyBlockMemberJacobContest.js'; +import SkyBlockMemberJacobContests from './SkyBlockMemberJacobContests.js'; +import SkyBlockMemberJacobContestsMedals from './SkyBlockMemberJacobContestsMedals.js'; +import SkyBlockMemberJacobContestsPerks from './SkyBlockMemberJacobContestsPerks.js'; +import SkyBlockMemberJacobContestsUniqueBrackets from './SkyBlockMemberJacobContestsUniqueBrackets.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { JacobCrops } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberJacobContests', () => { + const data = new SkyBlockMemberJacobContests({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberJacobContests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.perks).toBeDefined(); + expect(data.perks).toBeInstanceOf(SkyBlockMemberJacobContestsPerks); + expectTypeOf(data.perks).toEqualTypeOf(); + expect(data.medals).toBeDefined(); + expect(data.medals).toBeInstanceOf(SkyBlockMemberJacobContestsMedals); + expectTypeOf(data.medals).toEqualTypeOf(); + expect(data.uniqueBrackets).toBeDefined(); + expect(data.uniqueBrackets).toBeInstanceOf(SkyBlockMemberJacobContestsUniqueBrackets); + expectTypeOf(data.uniqueBrackets).toEqualTypeOf(); + expect(data.personalBests).toBeDefined(); + expectTypeOf(data.personalBests).toEqualTypeOf>(); + expect(data.contests).toBeDefined(); + expectTypeOf(data.contests).toEqualTypeOf>(); +}); diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.ts new file mode 100644 index 000000000..2fdea5176 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberJacobContestsMedals from './SkyBlockMemberJacobContestsMedals.js'; +import SkyBlockMemberJacobContestsPerks from './SkyBlockMemberJacobContestsPerks.js'; +import SkyBlockMemberJacobContestsUniqueBrackets from './SkyBlockMemberJacobContestsUniqueBrackets.js'; +import type SkyBlockMemberJacobContest from './SkyBlockMemberJacobContest.js'; +import type { JacobCrops } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberJacobContests { + perks: SkyBlockMemberJacobContestsPerks; + medals: SkyBlockMemberJacobContestsMedals; + uniqueBrackets: SkyBlockMemberJacobContestsUniqueBrackets; + personalBests: Record; + contests: Record; + constructor(data: Record) { + this.perks = new SkyBlockMemberJacobContestsPerks(data?.perks || {}); + this.medals = new SkyBlockMemberJacobContestsMedals(data?.medals_inv || {}); + this.uniqueBrackets = new SkyBlockMemberJacobContestsUniqueBrackets(data?.unique_brackets || {}); + this.personalBests = data?.personal_bests || {}; + const contests = data?.contests || {}; + this.contests = Object.keys(contests).reduce((obj: Record, key: string) => { + obj[key] = contests[key]; + return obj; + }, {}); + } +} + +export default SkyBlockMemberJacobContests; diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.test.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.test.ts new file mode 100644 index 000000000..5022dca26 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberJacobContestsMedals from './SkyBlockMemberJacobContestsMedals.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberJacobContestsMedals', () => { + const data = new SkyBlockMemberJacobContestsMedals({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberJacobContestsMedals); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bronze).toBeDefined(); + expect(data.bronze).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bronze).toEqualTypeOf(); + expect(data.silver).toBeDefined(); + expect(data.silver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.silver).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expect(data.gold).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gold).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.ts new file mode 100644 index 000000000..fe28154bc --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberJacobContestsMedals { + bronze: number; + silver: number; + gold: number; + constructor(data: Record) { + this.bronze = data?.bronze || 0; + this.silver = data?.silver || 0; + this.gold = data?.gold || 0; + } +} + +export default SkyBlockMemberJacobContestsMedals; diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.test.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.test.ts new file mode 100644 index 000000000..dd9872497 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.test.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberJacobContestsPerks from './SkyBlockMemberJacobContestsPerks.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberJacobContestsPerks', () => { + const data = new SkyBlockMemberJacobContestsPerks({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberJacobContestsPerks); + expectTypeOf(data).toEqualTypeOf(); + expect(data.doubleDrops).toBeDefined(); + expect(data.doubleDrops).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doubleDrops).toEqualTypeOf(); + expect(data.farmingLevelCap).toBeDefined(); + expect(data.farmingLevelCap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farmingLevelCap).toEqualTypeOf(); + expect(data.personalBests).toBeDefined(); + expectTypeOf(data.personalBests).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.ts new file mode 100644 index 000000000..7895c8b98 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberJacobContestsPerks { + doubleDrops: number; + farmingLevelCap: number; + personalBests: boolean; + constructor(data: Record) { + this.doubleDrops = data?.double_drops || 0; + this.farmingLevelCap = data?.farming_level_cap || 0; + this.personalBests = data?.personal_bests || false; + } +} + +export default SkyBlockMemberJacobContestsPerks; diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.test.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.test.ts new file mode 100644 index 000000000..c416deed1 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.test.ts @@ -0,0 +1,20 @@ +import SkyBlockMemberJacobContestsUniqueBrackets from './SkyBlockMemberJacobContestsUniqueBrackets.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { JacobCrops } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberJacobContestsUniqueBrackets', () => { + const data = new SkyBlockMemberJacobContestsUniqueBrackets({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberJacobContestsUniqueBrackets); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bronze).toBeDefined(); + expectTypeOf(data.bronze).toEqualTypeOf(); + expect(data.silver).toBeDefined(); + expectTypeOf(data.silver).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expectTypeOf(data.gold).toEqualTypeOf(); + expect(data.platinum).toBeDefined(); + expectTypeOf(data.platinum).toEqualTypeOf(); + expect(data.diamond).toBeDefined(); + expectTypeOf(data.diamond).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.ts b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.ts new file mode 100644 index 000000000..52b4134f1 --- /dev/null +++ b/src/Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.ts @@ -0,0 +1,18 @@ +import type { JacobCrops } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberJacobContestsUniqueBrackets { + bronze: JacobCrops[]; + silver: JacobCrops[]; + gold: JacobCrops[]; + platinum: JacobCrops[]; + diamond: JacobCrops[]; + constructor(data: Record) { + this.bronze = data?.bronze || []; + this.silver = data?.silver || []; + this.gold = data?.gold || []; + this.platinum = data?.platinum || []; + this.diamond = data?.diamond || []; + } +} + +export default SkyBlockMemberJacobContestsUniqueBrackets; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.test.ts new file mode 100644 index 000000000..2baa4ac93 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.test.ts @@ -0,0 +1,25 @@ +import SkyBlockMemberMining from './SkyBlockMemberMining.js'; +import SkyBlockMemberMiningCrystal from './SkyBlockMemberMiningCrystal.js'; +import SkyBlockMemberMiningHotm from './SkyBlockMemberMiningHotm.js'; +import SkyBlockMemberMiningPowders from './SkyBlockMemberMiningPowders.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { MiningCrystal, MiningPickaxeAbility, MiningSkyMallEffect } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberMining', () => { + const data = new SkyBlockMemberMining({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMining); + expectTypeOf(data).toEqualTypeOf(); + expect(data.powder).toBeDefined(); + expect(data.powder).toBeInstanceOf(SkyBlockMemberMiningPowders); + expectTypeOf(data.powder).toEqualTypeOf(); + expect(data.crystals).toBeDefined(); + expectTypeOf(data.crystals).toEqualTypeOf>(); + expect(data.hotm).toBeDefined(); + expect(data.hotm).toBeInstanceOf(SkyBlockMemberMiningHotm); + expectTypeOf(data.hotm).toEqualTypeOf(); + expect(data.pickaxeAbility).toBeDefined(); + expectTypeOf(data.pickaxeAbility).toEqualTypeOf(); + expect(data.dailyEffect).toBeDefined(); + expectTypeOf(data.dailyEffect).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.ts new file mode 100644 index 000000000..741b9b367 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.ts @@ -0,0 +1,27 @@ +import SkyBlockMemberMiningCrystal from './SkyBlockMemberMiningCrystal.js'; +import SkyBlockMemberMiningHotm from './SkyBlockMemberMiningHotm.js'; +import SkyBlockMemberMiningPowders from './SkyBlockMemberMiningPowders.js'; +import type { MiningCrystal, MiningPickaxeAbility, MiningSkyMallEffect } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberMining { + powder: SkyBlockMemberMiningPowders; + crystals: Record; + hotm: SkyBlockMemberMiningHotm; + pickaxeAbility: MiningPickaxeAbility | 'UNKNOWN'; + dailyEffect: MiningSkyMallEffect | 'UNKNOWN'; + constructor(data: Record) { + this.powder = new SkyBlockMemberMiningPowders(data || {}); + this.crystals = Object.keys(data?.crystals || {}).reduce( + (obj: Record, key: string) => { + obj[key.split('_crystal')[0] || 'jade'] = new SkyBlockMemberMiningCrystal(data?.crystals?.[key]); + return obj; + }, + {} + ); + this.hotm = new SkyBlockMemberMiningHotm(data || {}); + this.pickaxeAbility = data?.selected_pickaxe_ability || 'UNKNOWN'; + this.dailyEffect = data?.current_daily_effect || 'UNKNOWN'; + } +} + +export default SkyBlockMemberMining; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.test.ts new file mode 100644 index 000000000..892f93338 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.test.ts @@ -0,0 +1,22 @@ +import SkyBlockMemberMiningCrystal from './SkyBlockMemberMiningCrystal.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberMiningCrystal', () => { + const data = new SkyBlockMemberMiningCrystal({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningCrystal); + expectTypeOf(data).toEqualTypeOf(); + expect(data.found).toBeDefined(); + expectTypeOf(data.found).toEqualTypeOf(); + expect(data.totalFound).toBeDefined(); + expect(data.totalFound).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalFound).toEqualTypeOf(); + expect(data.totalPlaced).toBeDefined(); + expect(data.totalPlaced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalPlaced).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => boolean>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.found); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.ts new file mode 100644 index 000000000..51e6fa059 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberMiningCrystal { + found: boolean; + totalFound: number; + totalPlaced: number; + constructor(data: Record) { + this.found = data.state ? data.state === 'FOUND' : false; + this.totalFound = data?.total_found || 0; + this.totalPlaced = data?.total_placed || 0; + } + + toString(): boolean { + return this.found; + } +} + +export default SkyBlockMemberMiningCrystal; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.test.ts new file mode 100644 index 000000000..5d0fadc8c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.test.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberMiningHotm from './SkyBlockMemberMiningHotm.js'; +import SkyBlockMemberMiningHotmForge from './SkyBlockMemberMiningHotmForge.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkillLevelData } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberMiningHotm', () => { + const data = new SkyBlockMemberMiningHotm({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningHotm); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.nodes).toBeDefined(); + expectTypeOf(data.nodes).toEqualTypeOf>(); + expect(data.tokensSpent).toBeDefined(); + expect(data.tokensSpent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tokensSpent).toEqualTypeOf(); + expect(data.forge).toBeDefined(); + expect(data.forge).toBeInstanceOf(SkyBlockMemberMiningHotmForge); + expectTypeOf(data.forge).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.ts new file mode 100644 index 000000000..14d91acec --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.ts @@ -0,0 +1,25 @@ +import SkyBlockMemberMiningHotmForge from './SkyBlockMemberMiningHotmForge.js'; +import { getLevelByXp } from '../../../../Utils/SkyBlockUtils.js'; +import type { SkillLevelData } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberMiningHotm { + level: SkillLevelData; + nodes: Record; + tokensSpent: number; + forge: SkyBlockMemberMiningHotmForge; + constructor(data: Record) { + this.level = getLevelByXp(data?.experience || 0, { type: 'hotm' }); + this.nodes = data?.nodes || {}; + this.tokensSpent = data?.tokens_spent || 0; + this.forge = new SkyBlockMemberMiningHotmForge( + data?.forge_processes?.forge_1 || {}, + Number(this.nodes?.forge_time) || 0 + ); + } + + toString(): number { + return this.level.level; + } +} + +export default SkyBlockMemberMiningHotm; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.test.ts new file mode 100644 index 000000000..ed9b5ab0c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.test.ts @@ -0,0 +1,24 @@ +import SkyBlockMemberMiningHotmForge from './SkyBlockMemberMiningHotmForge.js'; +import SkyBlockMemberMiningHotmForgeItem from './SkyBlockMemberMiningHotmForgeItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberMiningHotmForge', () => { + const data = new SkyBlockMemberMiningHotmForge({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningHotmForge); + expectTypeOf(data).toEqualTypeOf(); + expect(data.slot1).toBeDefined(); + expectTypeOf(data.slot1).toEqualTypeOf(); + expect(data.slot2).toBeDefined(); + expectTypeOf(data.slot2).toEqualTypeOf(); + expect(data.slot3).toBeDefined(); + expectTypeOf(data.slot3).toEqualTypeOf(); + expect(data.slot4).toBeDefined(); + expectTypeOf(data.slot4).toEqualTypeOf(); + expect(data.slot5).toBeDefined(); + expectTypeOf(data.slot5).toEqualTypeOf(); + expect(data.slot6).toBeDefined(); + expectTypeOf(data.slot6).toEqualTypeOf(); + expect(data.slot7).toBeDefined(); + expectTypeOf(data.slot7).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.ts new file mode 100644 index 000000000..45c172a0e --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.ts @@ -0,0 +1,22 @@ +import SkyBlockMemberMiningHotmForgeItem from './SkyBlockMemberMiningHotmForgeItem.js'; + +class SkyBlockMemberMiningHotmForge { + slot1: SkyBlockMemberMiningHotmForgeItem | null; + slot2: SkyBlockMemberMiningHotmForgeItem | null; + slot3: SkyBlockMemberMiningHotmForgeItem | null; + slot4: SkyBlockMemberMiningHotmForgeItem | null; + slot5: SkyBlockMemberMiningHotmForgeItem | null; + slot6: SkyBlockMemberMiningHotmForgeItem | null; + slot7: SkyBlockMemberMiningHotmForgeItem | null; + constructor(data: Record, quickForgeTime: number = 0) { + this.slot1 = data?.['1'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['1'], quickForgeTime) : null; + this.slot2 = data?.['2'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['2'], quickForgeTime) : null; + this.slot3 = data?.['3'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['3'], quickForgeTime) : null; + this.slot4 = data?.['4'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['4'], quickForgeTime) : null; + this.slot5 = data?.['5'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['5'], quickForgeTime) : null; + this.slot6 = data?.['6'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['6'], quickForgeTime) : null; + this.slot7 = data?.['7'] ? new SkyBlockMemberMiningHotmForgeItem(data?.['7'], quickForgeTime) : null; + } +} + +export default SkyBlockMemberMiningHotmForge; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.test.ts new file mode 100644 index 000000000..b639a10c6 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.test.ts @@ -0,0 +1,40 @@ +import SkyBlockMemberMiningHotmForgeItem from './SkyBlockMemberMiningHotmForgeItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ForgeItemType, MiningForgeItemId, MiningForgeItemName } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberMiningHotmForgeItem', () => { + const data = new SkyBlockMemberMiningHotmForgeItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningHotmForgeItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.startTime).toBeDefined(); + expect(data.startTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startTime).toEqualTypeOf(); + expect(data.startTimeAt).toBeDefined(); + expect(data.startTimeAt).toBeInstanceOf(Date); + expectTypeOf(data.startTimeAt).toEqualTypeOf(); + expect(data.endTime).toBeDefined(); + expect(data.endTime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.endTime).toEqualTypeOf(); + expect(data.endTimeAt).toBeDefined(); + expect(data.endTimeAt).toBeInstanceOf(Date); + expectTypeOf(data.endTimeAt).toEqualTypeOf(); + expect(data.slot).toBeDefined(); + expect(data.slot).toBeGreaterThanOrEqual(0); + expectTypeOf(data.slot).toEqualTypeOf(); + expect(data.notified).toBeDefined(); + expectTypeOf(data.notified).toEqualTypeOf(); + expect(data.oldItem).toBeDefined(); + expectTypeOf(data.oldItem).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => MiningForgeItemName | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.ts new file mode 100644 index 000000000..ff7f4c8a8 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.ts @@ -0,0 +1,35 @@ +import { MiningForgeItems, MiningForgeQuickForgeMultiplier } from '../../../../Utils/Constants.js'; +import type { ForgeItemType, MiningForgeItemId, MiningForgeItemName } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberMiningHotmForgeItem { + type: ForgeItemType | 'UNKNOWN'; + id: MiningForgeItemId | 'UNKNOWN'; + name: MiningForgeItemName | 'UNKNOWN'; + startTime: number; + startTimeAt: Date; + endTime: number; + endTimeAt: Date; + slot: number; + notified: boolean; + oldItem: string | null; + constructor(data: Record, quickForgeTime: number = 0) { + this.type = data?.type || 'UNKNOWN'; + this.id = data?.id || 'UNKNOWN'; + this.name = MiningForgeItems?.[this.id]?.name || 'UNKNOWN'; + this.startTime = data?.startTime || 0; + this.startTimeAt = new Date(this.startTime); + this.endTime = + this.startTime + + (MiningForgeItems?.[this.id]?.duration ?? 0) * (MiningForgeQuickForgeMultiplier[quickForgeTime] ?? 1); + this.endTimeAt = new Date(this.endTime); + this.slot = data?.slot ?? 0; + this.notified = data?.notified ?? false; + this.oldItem = data?.oldItem ?? null; + } + + toString(): MiningForgeItemName | 'UNKNOWN' { + return this.name; + } +} + +export default SkyBlockMemberMiningHotmForgeItem; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.test.ts new file mode 100644 index 000000000..268fa81a5 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberMiningPowder from './SkyBlockMemberMiningPowder.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberMiningPowder', () => { + const data = new SkyBlockMemberMiningPowder({ stats: 'meow' }, 'gemstone'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningPowder); + expectTypeOf(data).toEqualTypeOf(); + expect(data.spent).toBeDefined(); + expect(data.spent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spent).toEqualTypeOf(); + expect(data.powder).toBeDefined(); + expect(data.powder).toBeGreaterThanOrEqual(0); + expectTypeOf(data.powder).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.ts new file mode 100644 index 000000000..62aefce52 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.ts @@ -0,0 +1,18 @@ +import type { MiningPower } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberMiningPowder { + spent: number; + powder: number; + total: number; + constructor(data: Record, type: MiningPower) { + this.spent = data?.[`powder_spent_${type}`] || 0; + this.powder = data?.[`powder_${type}`] || 0; + this.total = this.spent + this.powder; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberMiningPowder; diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.test.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.test.ts new file mode 100644 index 000000000..68b3ef6fd --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.test.ts @@ -0,0 +1,19 @@ +import SkyBlockMemberMiningPowder from './SkyBlockMemberMiningPowder.js'; +import SkyBlockMemberMiningPowders from './SkyBlockMemberMiningPowders.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberMiningPowders', () => { + const data = new SkyBlockMemberMiningPowders({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberMiningPowders); + expectTypeOf(data).toEqualTypeOf(); + expect(data.mithril).toBeDefined(); + expect(data.mithril).toBeInstanceOf(SkyBlockMemberMiningPowder); + expectTypeOf(data.mithril).toEqualTypeOf(); + expect(data.gemstone).toBeDefined(); + expect(data.gemstone).toBeInstanceOf(SkyBlockMemberMiningPowder); + expectTypeOf(data.gemstone).toEqualTypeOf(); + expect(data.glacite).toBeDefined(); + expect(data.glacite).toBeInstanceOf(SkyBlockMemberMiningPowder); + expectTypeOf(data.glacite).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.ts b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.ts new file mode 100644 index 000000000..e5e99590c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.ts @@ -0,0 +1,14 @@ +import SkyBlockMemberMiningPowder from './SkyBlockMemberMiningPowder.js'; + +class SkyBlockMemberMiningPowders { + mithril: SkyBlockMemberMiningPowder; + gemstone: SkyBlockMemberMiningPowder; + glacite: SkyBlockMemberMiningPowder; + constructor(data: Record) { + this.mithril = new SkyBlockMemberMiningPowder(data || {}, 'mithril'); + this.gemstone = new SkyBlockMemberMiningPowder(data || {}, 'gemstone'); + this.glacite = new SkyBlockMemberMiningPowder(data || {}, 'glacite'); + } +} + +export default SkyBlockMemberMiningPowders; diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.test.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.test.ts new file mode 100644 index 000000000..c7340fa2b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.test.ts @@ -0,0 +1,35 @@ +import SkyBlockMemberPet from './SkyBlockMemberPet.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { LevelData, Rarity, SkyBlockPetId } from '../../../../Types/SkyBlock.js'; +import type { UUID } from '../../../../Types/Global.js'; + +test('SkyBlockMemberPet', () => { + const data = new SkyBlockMemberPet({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPet); + expectTypeOf(data).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.uniqueId).toBeDefined(); + expectTypeOf(data.uniqueId).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.active).toBeDefined(); + expectTypeOf(data.active).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.heldItem).toBeDefined(); + expectTypeOf(data.heldItem).toEqualTypeOf(); + expect(data.candyUsed).toBeDefined(); + expect(data.candyUsed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.candyUsed).toEqualTypeOf(); + expect(data.skin).toBeDefined(); + expectTypeOf(data.skin).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockPetId | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.type); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.ts new file mode 100644 index 000000000..6f7d91b22 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.ts @@ -0,0 +1,32 @@ +import { getPetLevel } from '../../../../Utils/SkyBlockUtils.js'; +import type { LevelData, Rarity, SkyBlockPetId } from '../../../../Types/SkyBlock.js'; +import type { UUID } from '../../../../Types/Global.js'; + +class SkyBlockMemberPet { + uuid: UUID; + uniqueId: string; + type: SkyBlockPetId | 'UNKNOWN'; + active: boolean; + tier: Rarity | 'UNKNOWN'; + heldItem: string | null; + candyUsed: number; + skin: string | null; + level: LevelData; + constructor(data: Record) { + this.uuid = data?.uuid || 'UNKNOWN'; + this.uniqueId = data?.uniqueId || 'UNKNOWN'; + this.type = data?.type || 'UNKNOWN'; + this.active = data?.active || false; + this.tier = data?.tier || 'UNKNOWN'; + this.heldItem = data?.heldItem || null; + this.candyUsed = data?.candyUsed || 0; + this.skin = data?.skin || null; + this.level = getPetLevel(data?.exp || 0, this.type, this.tier); + } + + toString(): SkyBlockPetId | 'UNKNOWN' { + return this.type; + } +} + +export default SkyBlockMemberPet; diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.test.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.test.ts new file mode 100644 index 000000000..9a60f2365 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberPet from './SkyBlockMemberPet.js'; +import SkyBlockMemberPets from './SkyBlockMemberPets.js'; +import SkyBlockMemberPetsAutoPets from './SkyBlockMemberPetsAutoPets.js'; +import SkyBlockMemberPetsCare from './SkyBlockMemberPetsCare.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPets', () => { + const data = new SkyBlockMemberPets({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPets); + expectTypeOf(data).toEqualTypeOf(); + expect(data.petCare).toBeDefined(); + expect(data.petCare).toBeInstanceOf(SkyBlockMemberPetsCare); + expectTypeOf(data.petCare).toEqualTypeOf(); + expect(data.autoPetRules).toBeDefined(); + expect(data.autoPetRules).toBeInstanceOf(SkyBlockMemberPetsAutoPets); + expectTypeOf(data.autoPetRules).toEqualTypeOf(); + expect(data.pets).toBeDefined(); + expectTypeOf(data.pets).toEqualTypeOf(); + expect(data.oresMined).toBeDefined(); + expect(data.oresMined).toBeGreaterThanOrEqual(0); + expectTypeOf(data.oresMined).toEqualTypeOf(); + expect(data.seaCreaturesKilled).toBeDefined(); + expect(data.seaCreaturesKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.seaCreaturesKilled).toEqualTypeOf(); + expect(data.totalExpGained).toBeDefined(); + expect(data.totalExpGained).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalExpGained).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.ts new file mode 100644 index 000000000..7acb8096f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.ts @@ -0,0 +1,62 @@ +import SkyBlockMemberPet from './SkyBlockMemberPet.js'; +import SkyBlockMemberPetsAutoPets from './SkyBlockMemberPetsAutoPets.js'; +import SkyBlockMemberPetsCare from './SkyBlockMemberPetsCare.js'; + +class SkyBlockMemberPets { + petCare: SkyBlockMemberPetsCare; + autoPetRules: SkyBlockMemberPetsAutoPets; + pets: SkyBlockMemberPet[]; + oresMined: number; + seaCreaturesKilled: number; + totalExpGained: number; + constructor(data: Record) { + this.petCare = new SkyBlockMemberPetsCare(data?.pet_care || {}); + this.autoPetRules = new SkyBlockMemberPetsAutoPets(data?.autopet || {}); + this.pets = (data?.pets || []).map((pet: Record) => new SkyBlockMemberPet(pet)); + this.oresMined = data?.milestone?.ores_mined || 0; + this.seaCreaturesKilled = data?.milestone?.sea_creatures_killed || 0; + this.totalExpGained = data?.total_exp_gained || 0; + } + + // CREDIT: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/2d4d0317b1f7a9f27e59d25afd4df24c0e49b0da/src/lib/server/stats/pets.ts#L346-L400 (modified) + getPetScore(): number { + const RARITIES = [ + 'common', + 'uncommon', + 'rare', + 'epic', + 'legendary', + 'mythic', + 'divine', + 'supreme', + 'special', + 'very_special', + 'admin' + ]; + const highestRarity = {} as Record; + const highestLevel = {} as Record; + for (const pet of this.pets) { + if (pet.type === 'UNKNOWN') continue; + if (pet.tier === 'UNKNOWN') continue; + + // ? NOTE: FRACTURED_MONTEZUMA_SOUL is a rift pet so it's not accounted in the calculation + if (pet.type === 'FRACTURED_MONTEZUMA_SOUL') { + continue; + } + + const rarityIndex = RARITIES.indexOf(pet.tier.toLowerCase()) + 1; + if (rarityIndex > (highestRarity[pet.type] ?? 0)) highestRarity[pet.type] = rarityIndex; + + if (pet.level.level > (highestLevel[pet.type] ?? 0)) { + if (pet.level.level < pet.level.maxLevel) continue; + highestLevel[pet.type] = 1; + } + } + + const total = + Object.values(highestRarity).reduce((a, b) => a + b, 0) + Object.values(highestLevel).reduce((a, b) => a + b, 0); + return total; + } +} + +export default SkyBlockMemberPets; diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.test.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.test.ts new file mode 100644 index 000000000..cb05dd77c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberPetsAutoPetRule from './SkyBlockMemberPetsAutoPetRule.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UUID, UserInput } from '../../../../Types/Global.js'; + +test('SkyBlockMemberPetsAutoPetRule', () => { + const data = new SkyBlockMemberPetsAutoPetRule({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPetsAutoPetRule); + expectTypeOf(data).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.uniqueId).toBeDefined(); + expectTypeOf(data.uniqueId).toEqualTypeOf(); + expect(data.exceptions).toBeDefined(); + expectTypeOf(data.exceptions).toEqualTypeOf[]>(); + expect(data.disabled).toBeDefined(); + expectTypeOf(data.disabled).toEqualTypeOf(); + expect(data.data).toBeDefined(); + expectTypeOf(data.data).toEqualTypeOf>(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.ts new file mode 100644 index 000000000..1f9d8663f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.ts @@ -0,0 +1,26 @@ +import type { UUID, UserInput } from '../../../../Types/Global.js'; + +class SkyBlockMemberPetsAutoPetRule { + uuid: UUID; + id: string; + name: UserInput | 'UNKNOWN'; + uniqueId: string; + exceptions: Record[]; + disabled: boolean; + data: Record; + constructor(data: Record) { + this.uuid = data?.uuid || 'UNKNOWN'; + this.id = data?.id || 'UNKNOWN'; + this.name = data?.name || 'UNKNOWN'; + this.uniqueId = data?.uniqueId || 'UNKNOWN'; + this.exceptions = data?.exceptions || []; + this.disabled = data?.disabled || false; + this.data = data?.data || {}; + } + + toString(): string { + return this.name; + } +} + +export default SkyBlockMemberPetsAutoPetRule; diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.test.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.test.ts new file mode 100644 index 000000000..5cd1e9f2c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.test.ts @@ -0,0 +1,15 @@ +import SkyBlockMemberPetsAutoPetRule from './SkyBlockMemberPetsAutoPetRule.js'; +import SkyBlockMemberPetsAutoPets from './SkyBlockMemberPetsAutoPets.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPetsAutoPets', () => { + const data = new SkyBlockMemberPetsAutoPets({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPetsAutoPets); + expectTypeOf(data).toEqualTypeOf(); + expect(data.rulesLimit).toBeDefined(); + expect(data.rulesLimit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rulesLimit).toEqualTypeOf(); + expect(data.rules).toBeDefined(); + expectTypeOf(data.rules).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.ts new file mode 100644 index 000000000..cf21bc3bd --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.ts @@ -0,0 +1,12 @@ +import SkyBlockMemberPetsAutoPetRule from './SkyBlockMemberPetsAutoPetRule.js'; + +class SkyBlockMemberPetsAutoPets { + rulesLimit: number; + rules: SkyBlockMemberPetsAutoPetRule[]; + constructor(data: Record) { + this.rulesLimit = data?.rules_limit || 0; + this.rules = (data?.rules || []).map((rule: Record) => new SkyBlockMemberPetsAutoPetRule(rule)); + } +} + +export default SkyBlockMemberPetsAutoPets; diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.test.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.test.ts new file mode 100644 index 000000000..8b629b89a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.test.ts @@ -0,0 +1,20 @@ +import SkyBlockMemberPetsCare from './SkyBlockMemberPetsCare.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SacrificedPets } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberPetsCare', () => { + const data = new SkyBlockMemberPetsCare({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPetsCare); + expectTypeOf(data).toEqualTypeOf(); + expect(data.coinsSpent).toBeDefined(); + expect(data.coinsSpent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.coinsSpent).toEqualTypeOf(); + expect(data.petsSacrificed).toBeDefined(); + expectTypeOf(data.petsSacrificed).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.coinsSpent); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.ts b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.ts new file mode 100644 index 000000000..3a2a74472 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.ts @@ -0,0 +1,16 @@ +import type { SacrificedPets } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPetsCare { + coinsSpent: number; + petsSacrificed: SacrificedPets[]; + constructor(data: Record) { + this.coinsSpent = data?.coins_spent || 0; + this.petsSacrificed = data?.pet_types_sacrificed || []; + } + + toString(): number { + return this.coinsSpent; + } +} + +export default SkyBlockMemberPetsCare; diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.test.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.test.ts new file mode 100644 index 000000000..eeae701f0 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.test.ts @@ -0,0 +1,50 @@ +import SkyBlockMemberPlayerData from './SkyBlockMemberPlayerData.js'; +import SkyBlockMemberPlayerDataActiveEffect from './SkyBlockMemberPlayerDataActiveEffect.js'; +import SkyBlockMemberPlayerDataMinions from './SkyBlockMemberPlayerDataMinions.js'; +import SkyBlockMemberPlayerDataSkills from './SkyBlockMemberPlayerDataSkills.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockArea, SkyBlockPotionEffectName } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberPlayerData', () => { + const data = new SkyBlockMemberPlayerData({ stats: 'meow' }, { farmingCap: 0, tamingCap: 0 }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerData); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeEffects).toBeDefined(); + expectTypeOf(data.activeEffects).toEqualTypeOf(); + expect(data.pausedEffects).toBeDefined(); + expectTypeOf(data.pausedEffects).toEqualTypeOf(); + expect(data.disabledPotionEffects).toBeDefined(); + expectTypeOf(data.disabledPotionEffects).toEqualTypeOf(); + expect(data.reaperPeppersEaten).toBeDefined(); + expect(data.reaperPeppersEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.reaperPeppersEaten).toEqualTypeOf(); + expect(data.deaths).toBeDefined(); + expect(data.deaths).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deaths).toEqualTypeOf(); + expect(data.lastDeath).toBeDefined(); + expect(data.lastDeath).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastDeath).toEqualTypeOf(); + expect(data.visitedZones).toBeDefined(); + expectTypeOf(data.visitedZones).toEqualTypeOf(); + expect(data.visitedModes).toBeDefined(); + expectTypeOf(data.visitedModes).toEqualTypeOf(); + expect(data.achievementSpawnedIslandTypes).toBeDefined(); + expectTypeOf(data.achievementSpawnedIslandTypes).toEqualTypeOf(); + expect(data.unlockedCollTiers).toBeDefined(); + expectTypeOf(data.unlockedCollTiers).toEqualTypeOf(); + expect(data.perks).toBeDefined(); + expectTypeOf(data.perks).toEqualTypeOf>(); + expect(data.minions).toBeDefined(); + expect(data.minions).toBeInstanceOf(SkyBlockMemberPlayerDataMinions); + expectTypeOf(data.minions).toEqualTypeOf(); + expect(data.fastestTargetPractice).toBeDefined(); + expect(data.fastestTargetPractice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestTargetPractice).toEqualTypeOf(); + expect(data.fishingTreasureCaught).toBeDefined(); + expect(data.fishingTreasureCaught).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fishingTreasureCaught).toEqualTypeOf(); + expect(data.skills).toBeDefined(); + expect(data.skills).toBeInstanceOf(SkyBlockMemberPlayerDataSkills); + expectTypeOf(data.skills).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.ts new file mode 100644 index 000000000..f5ddbad81 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.ts @@ -0,0 +1,43 @@ +import SkyBlockMemberPlayerDataActiveEffect from './SkyBlockMemberPlayerDataActiveEffect.js'; +import SkyBlockMemberPlayerDataMinions from './SkyBlockMemberPlayerDataMinions.js'; +import SkyBlockMemberPlayerDataSkills from './SkyBlockMemberPlayerDataSkills.js'; +import type { SkyBlockArea, SkyBlockPotionEffectName } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPlayerData { + activeEffects: SkyBlockMemberPlayerDataActiveEffect[]; + pausedEffects: SkyBlockPotionEffectName[]; + disabledPotionEffects: SkyBlockPotionEffectName[]; + reaperPeppersEaten: number; + deaths: number; + lastDeath: number; + visitedZones: string[]; + visitedModes: SkyBlockArea[]; + achievementSpawnedIslandTypes: string[]; + unlockedCollTiers: string[]; + perks: Record; + minions: SkyBlockMemberPlayerDataMinions; + fastestTargetPractice: number; + fishingTreasureCaught: number; + skills: SkyBlockMemberPlayerDataSkills; + constructor(data: Record, skillCaps: { farmingCap: number; tamingCap: number }) { + this.activeEffects = (data?.active_effects || []).map( + (effect: Record) => new SkyBlockMemberPlayerDataActiveEffect(effect) + ); + this.pausedEffects = data?.paused_effects || []; + this.disabledPotionEffects = data?.disabled_potion_effects || []; + this.reaperPeppersEaten = data?.reaper_peppers_eaten || 0; + this.deaths = data?.death_count || 0; + this.lastDeath = data?.last_death || 0; + this.visitedZones = data?.visited_zones || []; + this.visitedModes = data?.visited_modes || []; + this.achievementSpawnedIslandTypes = data?.achievement_spawned_island_types || []; + this.unlockedCollTiers = data?.unlocked_coll_tiers || []; + this.perks = data?.perks || {}; + this.minions = new SkyBlockMemberPlayerDataMinions(data?.crafted_generators || {}); + this.fastestTargetPractice = data?.fastest_target_practice || 0; + this.fishingTreasureCaught = data?.fishing_treasure_caught || 0; + this.skills = new SkyBlockMemberPlayerDataSkills(data?.experience || {}, skillCaps); + } +} + +export default SkyBlockMemberPlayerData; diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.test.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.test.ts new file mode 100644 index 000000000..5d82f3a0f --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.test.ts @@ -0,0 +1,15 @@ +import SkyBlockMemberPlayerDataActiveEffect from './SkyBlockMemberPlayerDataActiveEffect.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerDataActiveEffect', () => { + const data = new SkyBlockMemberPlayerDataActiveEffect({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerDataActiveEffect); + expectTypeOf(data).toEqualTypeOf(); + expect(data.expireAt).toBeDefined(); + expect(data.expireAt).toBeInstanceOf(Date); + expectTypeOf(data.expireAt).toEqualTypeOf(); + expect(data.expireTimestamp).toBeDefined(); + expect(data.expireTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.expireTimestamp).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.ts new file mode 100644 index 000000000..b93207c43 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.ts @@ -0,0 +1,16 @@ +import SkyBlockPotionEffect from '../../Potion/SkyBlockPotionEffect.js'; +import TicksToMilliseconds from '../../../../Utils/TicksToMilliseconds.js'; + +class SkyBlockMemberPlayerDataActiveEffect extends SkyBlockPotionEffect { + expireAt: Date; + expireTimestamp: number; + constructor(data: Record) { + super(data); + this.durationTicks = data?.ticks_remaining || 0; + this.duration = TicksToMilliseconds(this.durationTicks); + this.expireAt = new Date(new Date().getTime() + this.duration); + this.expireTimestamp = this.expireAt.getTime(); + } +} + +export default SkyBlockMemberPlayerDataActiveEffect; diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.test.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.test.ts new file mode 100644 index 000000000..b1ce99649 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.test.ts @@ -0,0 +1,36 @@ +import SkyBlockMemberPlayerDataMinion from './SkyBlockMemberPlayerDataMinion.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockMinionName } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberPlayerDataMinion', () => { + const data = new SkyBlockMemberPlayerDataMinion([], 'ACACIA'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data).toEqualTypeOf(); + expect(data.minion).toBeDefined(); + expectTypeOf(data.minion).toEqualTypeOf(); + expect(data.tier1).toBeDefined(); + expectTypeOf(data.tier1).toEqualTypeOf(); + expect(data.tier2).toBeDefined(); + expectTypeOf(data.tier2).toEqualTypeOf(); + expect(data.tier3).toBeDefined(); + expectTypeOf(data.tier3).toEqualTypeOf(); + expect(data.tier4).toBeDefined(); + expectTypeOf(data.tier4).toEqualTypeOf(); + expect(data.tier5).toBeDefined(); + expectTypeOf(data.tier5).toEqualTypeOf(); + expect(data.tier6).toBeDefined(); + expectTypeOf(data.tier6).toEqualTypeOf(); + expect(data.tier7).toBeDefined(); + expectTypeOf(data.tier7).toEqualTypeOf(); + expect(data.tier8).toBeDefined(); + expectTypeOf(data.tier8).toEqualTypeOf(); + expect(data.tier9).toBeDefined(); + expectTypeOf(data.tier9).toEqualTypeOf(); + expect(data.tier10).toBeDefined(); + expectTypeOf(data.tier10).toEqualTypeOf(); + expect(data.tier11).toBeDefined(); + expectTypeOf(data.tier11).toEqualTypeOf(); + expect(data.tier12).toBeDefined(); + expectTypeOf(data.tier12).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.ts new file mode 100644 index 000000000..f1f4a76e9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.ts @@ -0,0 +1,47 @@ +import type { SkyBlockMinion, SkyBlockMinionName } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPlayerDataMinion { + minion: SkyBlockMinionName; + tier1: boolean; + tier2: boolean; + tier3: boolean; + tier4: boolean; + tier5: boolean; + tier6: boolean; + tier7: boolean; + tier8: boolean; + tier9: boolean; + tier10: boolean; + tier11: boolean; + tier12: boolean; + constructor(data: SkyBlockMinion[], minion: SkyBlockMinionName) { + this.minion = minion; + // this.tier1 = data.includes(`${minion}_1`) || false; + // this.tier2 = data.includes(`${minion}_2`) || false; + // this.tier3 = data.includes(`${minion}_3`) || false; + // this.tier4 = data.includes(`${minion}_4`) || false; + // this.tier5 = data.includes(`${minion}_5`) || false; + // this.tier6 = data.includes(`${minion}_6`) || false; + // this.tier7 = data.includes(`${minion}_7`) || false; + // this.tier8 = data.includes(`${minion}_8`) || false; + // this.tier9 = data.includes(`${minion}_9`) || false; + // this.tier10 = data.includes(`${minion}_10`) || false; + // this.tier11 = data.includes(`${minion}_11`) || false; + // this.tier12 = data.includes(`${minion}_12`) || false; + + this.tier1 = false; + this.tier2 = false; + this.tier3 = false; + this.tier4 = false; + this.tier5 = false; + this.tier6 = false; + this.tier7 = false; + this.tier8 = false; + this.tier9 = false; + this.tier10 = false; + this.tier11 = false; + this.tier12 = false; + } +} + +export default SkyBlockMemberPlayerDataMinion; diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.test.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.test.ts new file mode 100644 index 000000000..5b0904034 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.test.ts @@ -0,0 +1,187 @@ +import SkyBlockMemberPlayerDataMinion from './SkyBlockMemberPlayerDataMinion.js'; +import SkyBlockMemberPlayerDataMinions from './SkyBlockMemberPlayerDataMinions.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerDataMinions', () => { + const data = new SkyBlockMemberPlayerDataMinions([]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerDataMinions); + expectTypeOf(data).toEqualTypeOf(); + expect(data.acacia).toBeDefined(); + expect(data.acacia).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.acacia).toEqualTypeOf(); + expect(data.birch).toBeDefined(); + expect(data.birch).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.birch).toEqualTypeOf(); + expect(data.blaze).toBeDefined(); + expect(data.blaze).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.blaze).toEqualTypeOf(); + expect(data.cactus).toBeDefined(); + expect(data.cactus).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.cactus).toEqualTypeOf(); + expect(data.carrot).toBeDefined(); + expect(data.carrot).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.carrot).toEqualTypeOf(); + expect(data.cavespider).toBeDefined(); + expect(data.cavespider).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.cavespider).toEqualTypeOf(); + expect(data.chicken).toBeDefined(); + expect(data.chicken).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.chicken).toEqualTypeOf(); + expect(data.clay).toBeDefined(); + expect(data.clay).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.clay).toEqualTypeOf(); + expect(data.coal).toBeDefined(); + expect(data.coal).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.coal).toEqualTypeOf(); + expect(data.cobblestone).toBeDefined(); + expect(data.cobblestone).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.cobblestone).toEqualTypeOf(); + expect(data.cocoa).toBeDefined(); + expect(data.cocoa).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.cocoa).toEqualTypeOf(); + expect(data.cow).toBeDefined(); + expect(data.cow).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.cow).toEqualTypeOf(); + expect(data.creeper).toBeDefined(); + expect(data.creeper).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.creeper).toEqualTypeOf(); + expect(data.darkOak).toBeDefined(); + expect(data.darkOak).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.darkOak).toEqualTypeOf(); + expect(data.diamond).toBeDefined(); + expect(data.diamond).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.diamond).toEqualTypeOf(); + expect(data.emerald).toBeDefined(); + expect(data.emerald).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.emerald).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.enderStone).toBeDefined(); + expect(data.enderStone).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.enderStone).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expect(data.fishing).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.flower).toBeDefined(); + expect(data.flower).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.flower).toEqualTypeOf(); + expect(data.ghast).toBeDefined(); + expect(data.ghast).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.ghast).toEqualTypeOf(); + expect(data.glowstone).toBeDefined(); + expect(data.glowstone).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.glowstone).toEqualTypeOf(); + expect(data.gold).toBeDefined(); + expect(data.gold).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.gold).toEqualTypeOf(); + expect(data.gravel).toBeDefined(); + expect(data.gravel).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.gravel).toEqualTypeOf(); + expect(data.hardStone).toBeDefined(); + expect(data.hardStone).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.hardStone).toEqualTypeOf(); + expect(data.ice).toBeDefined(); + expect(data.ice).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.ice).toEqualTypeOf(); + expect(data.inferno).toBeDefined(); + expect(data.inferno).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.inferno).toEqualTypeOf(); + expect(data.iron).toBeDefined(); + expect(data.iron).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.iron).toEqualTypeOf(); + expect(data.jungle).toBeDefined(); + expect(data.jungle).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.jungle).toEqualTypeOf(); + expect(data.lapis).toBeDefined(); + expect(data.lapis).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.lapis).toEqualTypeOf(); + expect(data.magmaCube).toBeDefined(); + expect(data.magmaCube).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.magmaCube).toEqualTypeOf(); + expect(data.melon).toBeDefined(); + expect(data.melon).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.melon).toEqualTypeOf(); + expect(data.mithril).toBeDefined(); + expect(data.mithril).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.mithril).toEqualTypeOf(); + expect(data.mushroom).toBeDefined(); + expect(data.mushroom).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.mushroom).toEqualTypeOf(); + expect(data.mycelium).toBeDefined(); + expect(data.mycelium).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.mycelium).toEqualTypeOf(); + expect(data.netherWart).toBeDefined(); + expect(data.netherWart).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.netherWart).toEqualTypeOf(); + expect(data.oak).toBeDefined(); + expect(data.oak).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.oak).toEqualTypeOf(); + expect(data.obsidian).toBeDefined(); + expect(data.obsidian).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.obsidian).toEqualTypeOf(); + expect(data.pig).toBeDefined(); + expect(data.pig).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.pig).toEqualTypeOf(); + expect(data.potato).toBeDefined(); + expect(data.potato).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.potato).toEqualTypeOf(); + expect(data.pumpkin).toBeDefined(); + expect(data.pumpkin).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.pumpkin).toEqualTypeOf(); + expect(data.quartz).toBeDefined(); + expect(data.quartz).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.quartz).toEqualTypeOf(); + expect(data.rabbit).toBeDefined(); + expect(data.rabbit).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.rabbit).toEqualTypeOf(); + expect(data.redstone).toBeDefined(); + expect(data.redstone).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.redstone).toEqualTypeOf(); + expect(data.redSand).toBeDefined(); + expect(data.redSand).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.redSand).toEqualTypeOf(); + expect(data.revenant).toBeDefined(); + expect(data.revenant).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.revenant).toEqualTypeOf(); + expect(data.sand).toBeDefined(); + expect(data.sand).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.sand).toEqualTypeOf(); + expect(data.sheep).toBeDefined(); + expect(data.sheep).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.sheep).toEqualTypeOf(); + expect(data.skeleton).toBeDefined(); + expect(data.skeleton).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.skeleton).toEqualTypeOf(); + expect(data.slime).toBeDefined(); + expect(data.slime).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.slime).toEqualTypeOf(); + expect(data.snow).toBeDefined(); + expect(data.snow).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.snow).toEqualTypeOf(); + expect(data.spider).toBeDefined(); + expect(data.spider).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.spider).toEqualTypeOf(); + expect(data.spruce).toBeDefined(); + expect(data.spruce).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.spruce).toEqualTypeOf(); + expect(data.sugarCane).toBeDefined(); + expect(data.sugarCane).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.sugarCane).toEqualTypeOf(); + expect(data.tarantula).toBeDefined(); + expect(data.tarantula).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.tarantula).toEqualTypeOf(); + expect(data.vampire).toBeDefined(); + expect(data.vampire).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.vampire).toEqualTypeOf(); + expect(data.voidling).toBeDefined(); + expect(data.voidling).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.voidling).toEqualTypeOf(); + expect(data.wheat).toBeDefined(); + expect(data.wheat).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.wheat).toEqualTypeOf(); + expect(data.zombie).toBeDefined(); + expect(data.zombie).toBeInstanceOf(SkyBlockMemberPlayerDataMinion); + expectTypeOf(data.zombie).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.ts new file mode 100644 index 000000000..3bcc02174 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.ts @@ -0,0 +1,127 @@ +import SkyBlockMemberPlayerDataMinion from './SkyBlockMemberPlayerDataMinion.js'; +import type { SkyBlockMinion } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPlayerDataMinions { + acacia: SkyBlockMemberPlayerDataMinion; + birch: SkyBlockMemberPlayerDataMinion; + blaze: SkyBlockMemberPlayerDataMinion; + cactus: SkyBlockMemberPlayerDataMinion; + carrot: SkyBlockMemberPlayerDataMinion; + cavespider: SkyBlockMemberPlayerDataMinion; + chicken: SkyBlockMemberPlayerDataMinion; + clay: SkyBlockMemberPlayerDataMinion; + coal: SkyBlockMemberPlayerDataMinion; + cobblestone: SkyBlockMemberPlayerDataMinion; + cocoa: SkyBlockMemberPlayerDataMinion; + cow: SkyBlockMemberPlayerDataMinion; + creeper: SkyBlockMemberPlayerDataMinion; + darkOak: SkyBlockMemberPlayerDataMinion; + diamond: SkyBlockMemberPlayerDataMinion; + emerald: SkyBlockMemberPlayerDataMinion; + enderman: SkyBlockMemberPlayerDataMinion; + enderStone: SkyBlockMemberPlayerDataMinion; + fishing: SkyBlockMemberPlayerDataMinion; + flower: SkyBlockMemberPlayerDataMinion; + ghast: SkyBlockMemberPlayerDataMinion; + glowstone: SkyBlockMemberPlayerDataMinion; + gold: SkyBlockMemberPlayerDataMinion; + gravel: SkyBlockMemberPlayerDataMinion; + hardStone: SkyBlockMemberPlayerDataMinion; + ice: SkyBlockMemberPlayerDataMinion; + inferno: SkyBlockMemberPlayerDataMinion; + iron: SkyBlockMemberPlayerDataMinion; + jungle: SkyBlockMemberPlayerDataMinion; + lapis: SkyBlockMemberPlayerDataMinion; + magmaCube: SkyBlockMemberPlayerDataMinion; + melon: SkyBlockMemberPlayerDataMinion; + mithril: SkyBlockMemberPlayerDataMinion; + mushroom: SkyBlockMemberPlayerDataMinion; + mycelium: SkyBlockMemberPlayerDataMinion; + netherWart: SkyBlockMemberPlayerDataMinion; + oak: SkyBlockMemberPlayerDataMinion; + obsidian: SkyBlockMemberPlayerDataMinion; + pig: SkyBlockMemberPlayerDataMinion; + potato: SkyBlockMemberPlayerDataMinion; + pumpkin: SkyBlockMemberPlayerDataMinion; + quartz: SkyBlockMemberPlayerDataMinion; + rabbit: SkyBlockMemberPlayerDataMinion; + redstone: SkyBlockMemberPlayerDataMinion; + redSand: SkyBlockMemberPlayerDataMinion; + revenant: SkyBlockMemberPlayerDataMinion; + sand: SkyBlockMemberPlayerDataMinion; + sheep: SkyBlockMemberPlayerDataMinion; + skeleton: SkyBlockMemberPlayerDataMinion; + slime: SkyBlockMemberPlayerDataMinion; + snow: SkyBlockMemberPlayerDataMinion; + spider: SkyBlockMemberPlayerDataMinion; + spruce: SkyBlockMemberPlayerDataMinion; + sugarCane: SkyBlockMemberPlayerDataMinion; + tarantula: SkyBlockMemberPlayerDataMinion; + vampire: SkyBlockMemberPlayerDataMinion; + voidling: SkyBlockMemberPlayerDataMinion; + wheat: SkyBlockMemberPlayerDataMinion; + zombie: SkyBlockMemberPlayerDataMinion; + constructor(data: SkyBlockMinion[]) { + this.acacia = new SkyBlockMemberPlayerDataMinion(data || [], 'ACACIA'); + this.birch = new SkyBlockMemberPlayerDataMinion(data || [], 'BIRCH'); + this.blaze = new SkyBlockMemberPlayerDataMinion(data || [], 'BLAZE'); + this.cactus = new SkyBlockMemberPlayerDataMinion(data || [], 'CACTUS'); + this.carrot = new SkyBlockMemberPlayerDataMinion(data || [], 'CARROT'); + this.cavespider = new SkyBlockMemberPlayerDataMinion(data || [], 'CAVESPIDER'); + this.chicken = new SkyBlockMemberPlayerDataMinion(data || [], 'CHICKEN'); + this.clay = new SkyBlockMemberPlayerDataMinion(data || [], 'CLAY'); + this.coal = new SkyBlockMemberPlayerDataMinion(data || [], 'COAL'); + this.cobblestone = new SkyBlockMemberPlayerDataMinion(data || [], 'COBBLESTONE'); + this.cocoa = new SkyBlockMemberPlayerDataMinion(data || [], 'COCOA'); + this.cow = new SkyBlockMemberPlayerDataMinion(data || [], 'COW'); + this.creeper = new SkyBlockMemberPlayerDataMinion(data || [], 'CREEPER'); + this.darkOak = new SkyBlockMemberPlayerDataMinion(data || [], 'DARK_OAK'); + this.diamond = new SkyBlockMemberPlayerDataMinion(data || [], 'DIAMOND'); + this.emerald = new SkyBlockMemberPlayerDataMinion(data || [], 'EMERALD'); + this.enderman = new SkyBlockMemberPlayerDataMinion(data || [], 'ENDERMAN'); + this.enderStone = new SkyBlockMemberPlayerDataMinion(data || [], 'ENDER_STONE'); + this.fishing = new SkyBlockMemberPlayerDataMinion(data || [], 'FISHING'); + this.flower = new SkyBlockMemberPlayerDataMinion(data || [], 'FLOWER'); + this.ghast = new SkyBlockMemberPlayerDataMinion(data || [], 'GHAST'); + this.glowstone = new SkyBlockMemberPlayerDataMinion(data || [], 'GLOWSTONE'); + this.gold = new SkyBlockMemberPlayerDataMinion(data || [], 'GOLD'); + this.gravel = new SkyBlockMemberPlayerDataMinion(data || [], 'GRAVEL'); + this.hardStone = new SkyBlockMemberPlayerDataMinion(data || [], 'HARD_STONE'); + this.ice = new SkyBlockMemberPlayerDataMinion(data || [], 'ICE'); + this.inferno = new SkyBlockMemberPlayerDataMinion(data || [], 'INFERNO'); + this.iron = new SkyBlockMemberPlayerDataMinion(data || [], 'IRON'); + this.jungle = new SkyBlockMemberPlayerDataMinion(data || [], 'JUNGLE'); + this.lapis = new SkyBlockMemberPlayerDataMinion(data || [], 'LAPIS'); + this.magmaCube = new SkyBlockMemberPlayerDataMinion(data || [], 'MAGMA_CUBE'); + this.melon = new SkyBlockMemberPlayerDataMinion(data || [], 'MELON'); + this.mithril = new SkyBlockMemberPlayerDataMinion(data || [], 'MITHRIL'); + this.mushroom = new SkyBlockMemberPlayerDataMinion(data || [], 'MUSHROOM'); + this.mycelium = new SkyBlockMemberPlayerDataMinion(data || [], 'MYCELIUM'); + this.netherWart = new SkyBlockMemberPlayerDataMinion(data || [], 'NETHER_WARTS'); + this.oak = new SkyBlockMemberPlayerDataMinion(data || [], 'OAK'); + this.obsidian = new SkyBlockMemberPlayerDataMinion(data || [], 'OBSIDIAN'); + this.pig = new SkyBlockMemberPlayerDataMinion(data || [], 'PIG'); + this.potato = new SkyBlockMemberPlayerDataMinion(data || [], 'POTATO'); + this.pumpkin = new SkyBlockMemberPlayerDataMinion(data || [], 'PUMPKIN'); + this.quartz = new SkyBlockMemberPlayerDataMinion(data || [], 'QUARTZ'); + this.rabbit = new SkyBlockMemberPlayerDataMinion(data || [], 'RABBIT'); + this.redstone = new SkyBlockMemberPlayerDataMinion(data || [], 'REDSTONE'); + this.redSand = new SkyBlockMemberPlayerDataMinion(data || [], 'RED_SAND'); + this.revenant = new SkyBlockMemberPlayerDataMinion(data || [], 'REVENANT'); + this.sand = new SkyBlockMemberPlayerDataMinion(data || [], 'SAND'); + this.sheep = new SkyBlockMemberPlayerDataMinion(data || [], 'SHEEP'); + this.skeleton = new SkyBlockMemberPlayerDataMinion(data || [], 'SKELETON'); + this.slime = new SkyBlockMemberPlayerDataMinion(data || [], 'SLIME'); + this.snow = new SkyBlockMemberPlayerDataMinion(data || [], 'SNOW'); + this.spider = new SkyBlockMemberPlayerDataMinion(data || [], 'SPIDER'); + this.spruce = new SkyBlockMemberPlayerDataMinion(data || [], 'SPRUCE'); + this.sugarCane = new SkyBlockMemberPlayerDataMinion(data || [], 'SUGAR_CANE'); + this.tarantula = new SkyBlockMemberPlayerDataMinion(data || [], 'TARANTULA'); + this.vampire = new SkyBlockMemberPlayerDataMinion(data || [], 'VAMPIRE'); + this.voidling = new SkyBlockMemberPlayerDataMinion(data || [], 'VOIDLING'); + this.wheat = new SkyBlockMemberPlayerDataMinion(data || [], 'WHEAT'); + this.zombie = new SkyBlockMemberPlayerDataMinion(data || [], 'ZOMBIE'); + } +} + +export default SkyBlockMemberPlayerDataMinions; diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.test.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.test.ts new file mode 100644 index 000000000..f4dd574d5 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.test.ts @@ -0,0 +1,43 @@ +import SkyBlockMemberPlayerDataSkills from './SkyBlockMemberPlayerDataSkills.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkillLevelData } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberPlayerDataSkills', () => { + const data = new SkyBlockMemberPlayerDataSkills({ stats: 'meow' }, { farmingCap: 0, tamingCap: 0 }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerDataSkills); + expectTypeOf(data).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.alchemy).toBeDefined(); + expectTypeOf(data.alchemy).toEqualTypeOf(); + expect(data.runecrafting).toBeDefined(); + expectTypeOf(data.runecrafting).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.farming).toBeDefined(); + expectTypeOf(data.farming).toEqualTypeOf(); + expect(data.enchanting).toBeDefined(); + expectTypeOf(data.enchanting).toEqualTypeOf(); + expect(data.taming).toBeDefined(); + expectTypeOf(data.taming).toEqualTypeOf(); + expect(data.foraging).toBeDefined(); + expectTypeOf(data.foraging).toEqualTypeOf(); + expect(data.social).toBeDefined(); + expectTypeOf(data.social).toEqualTypeOf(); + expect(data.carpentry).toBeDefined(); + expectTypeOf(data.carpentry).toEqualTypeOf(); + expect(data.combat).toBeDefined(); + expectTypeOf(data.combat).toEqualTypeOf(); + expect(data.average).toBeDefined(); + expect(data.average).toBeGreaterThanOrEqual(0); + expectTypeOf(data.average).toEqualTypeOf(); + expect(data.nonCosmeticAverage).toBeDefined(); + expect(data.nonCosmeticAverage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.nonCosmeticAverage).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.average); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.ts b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.ts new file mode 100644 index 000000000..bd5c80130 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.ts @@ -0,0 +1,61 @@ +import { getLevelByXp } from '../../../../Utils/SkyBlockUtils.js'; +import type { SkillLevelData } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPlayerDataSkills { + fishing: SkillLevelData; + alchemy: SkillLevelData; + runecrafting: SkillLevelData; + mining: SkillLevelData; + farming: SkillLevelData; + enchanting: SkillLevelData; + taming: SkillLevelData; + foraging: SkillLevelData; + social: SkillLevelData; + carpentry: SkillLevelData; + combat: SkillLevelData; + average: number; + nonCosmeticAverage: number; + constructor(data: Record, skillCaps: { farmingCap: number; tamingCap: number }) { + this.fishing = getLevelByXp(data?.SKILL_FISHING || 0, { type: 'fishing' }); + this.alchemy = getLevelByXp(data?.SKILL_ALCHEMY || 0, { type: 'alchemy' }); + this.runecrafting = getLevelByXp(data?.SKILL_RUNECRAFTING || 0, { type: 'runecrafting' }); + this.mining = getLevelByXp(data?.SKILL_MINING || 0, { type: 'mining' }); + this.farming = getLevelByXp(data?.SKILL_FARMING || 0, { type: 'farming', cap: 50 + skillCaps.farmingCap }); + this.enchanting = getLevelByXp(data?.SKILL_ENCHANTING || 0, { type: 'enchanting' }); + this.taming = getLevelByXp(data?.SKILL_TAMING || 0, { type: 'taming', cap: 50 + skillCaps.tamingCap }); + this.foraging = getLevelByXp(data?.SKILL_FORAGING || 0, { type: 'foraging' }); + this.social = getLevelByXp(data?.SKILL_SOCIAL || 0, { type: 'social' }); + this.carpentry = getLevelByXp(data?.SKILL_CARPENTRY || 0, { type: 'carpentry' }); + this.combat = getLevelByXp(data?.SKILL_COMBAT || 0, { type: 'combat' }); + this.average = + (this.fishing.level + + this.alchemy.level + + this.runecrafting.level + + this.mining.level + + this.farming.level + + this.enchanting.level + + this.taming.level + + this.foraging.level + + this.social.level + + this.carpentry.level + + this.combat.level) / + 11; + this.nonCosmeticAverage = + (this.fishing.level + + this.alchemy.level + + this.mining.level + + this.farming.level + + this.enchanting.level + + this.taming.level + + this.foraging.level + + this.carpentry.level + + this.combat.level) / + 9; + } + + toString(): number { + return this.average; + } +} + +export default SkyBlockMemberPlayerDataSkills; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.test.ts new file mode 100644 index 000000000..6281c8106 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.test.ts @@ -0,0 +1,52 @@ +import SkyBlockMemberPlayerStats from './SkyBlockMemberPlayerStats.js'; +import SkyBlockMemberPlayerStatsAuctions from './SkyBlockMemberPlayerStatsAuctions.js'; +import SkyBlockMemberPlayerStatsCandy from './SkyBlockMemberPlayerStatsCandy.js'; +import SkyBlockMemberPlayerStatsEndIsland from './SkyBlockMemberPlayerStatsEndIsland.js'; +import SkyBlockMemberPlayerStatsFishing from './SkyBlockMemberPlayerStatsFishing.js'; +import SkyBlockMemberPlayerStatsGifts from './SkyBlockMemberPlayerStatsGifts.js'; +import SkyBlockMemberPlayerStatsMythos from './SkyBlockMemberPlayerStatsMythos.js'; +import SkyBlockMemberPlayerStatsWinter from './SkyBlockMemberPlayerStatsWinter.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStats', () => { + const data = new SkyBlockMemberPlayerStats({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expect(data.fishing).toBeInstanceOf(SkyBlockMemberPlayerStatsFishing); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.glowingMushroomsBroken).toBeDefined(); + expect(data.glowingMushroomsBroken).toBeGreaterThanOrEqual(0); + expectTypeOf(data.glowingMushroomsBroken).toEqualTypeOf(); + expect(data.highestDamage).toBeDefined(); + expect(data.highestDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestDamage).toEqualTypeOf(); + expect(data.highestCriticalDamage).toBeDefined(); + expect(data.highestCriticalDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestCriticalDamage).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expectTypeOf(data.kills).toEqualTypeOf>(); + expect(data.deaths).toBeDefined(); + expectTypeOf(data.deaths).toEqualTypeOf>(); + expect(data.auctions).toBeDefined(); + expect(data.auctions).toBeInstanceOf(SkyBlockMemberPlayerStatsAuctions); + expectTypeOf(data.auctions).toEqualTypeOf(); + expect(data.candy).toBeDefined(); + expect(data.candy).toBeInstanceOf(SkyBlockMemberPlayerStatsCandy); + expectTypeOf(data.candy).toEqualTypeOf(); + expect(data.gifts).toBeDefined(); + expect(data.gifts).toBeInstanceOf(SkyBlockMemberPlayerStatsGifts); + expectTypeOf(data.gifts).toEqualTypeOf(); + expect(data.mythos).toBeDefined(); + expect(data.mythos).toBeInstanceOf(SkyBlockMemberPlayerStatsMythos); + expectTypeOf(data.mythos).toEqualTypeOf(); + expect(data.winter).toBeDefined(); + expect(data.winter).toBeInstanceOf(SkyBlockMemberPlayerStatsWinter); + expectTypeOf(data.winter).toEqualTypeOf(); + expect(data.endIsland).toBeDefined(); + expect(data.endIsland).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIsland); + expectTypeOf(data.endIsland).toEqualTypeOf(); + expect(data.races).toBeDefined(); + expectTypeOf(data.races).toEqualTypeOf>>(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.ts new file mode 100644 index 000000000..f4c8e7610 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.ts @@ -0,0 +1,60 @@ +import SkyBlockMemberPlayerStatsAuctions from './SkyBlockMemberPlayerStatsAuctions.js'; +import SkyBlockMemberPlayerStatsCandy from './SkyBlockMemberPlayerStatsCandy.js'; +import SkyBlockMemberPlayerStatsEndIsland from './SkyBlockMemberPlayerStatsEndIsland.js'; +import SkyBlockMemberPlayerStatsFishing from './SkyBlockMemberPlayerStatsFishing.js'; +import SkyBlockMemberPlayerStatsGifts from './SkyBlockMemberPlayerStatsGifts.js'; +import SkyBlockMemberPlayerStatsMythos from './SkyBlockMemberPlayerStatsMythos.js'; +import SkyBlockMemberPlayerStatsWinter from './SkyBlockMemberPlayerStatsWinter.js'; + +class SkyBlockMemberPlayerStats { + fishing: SkyBlockMemberPlayerStatsFishing; + glowingMushroomsBroken: number; + highestDamage: number; + highestCriticalDamage: number; + kills: Record; + deaths: Record; + auctions: SkyBlockMemberPlayerStatsAuctions; + candy: SkyBlockMemberPlayerStatsCandy; + gifts: SkyBlockMemberPlayerStatsGifts; + mythos: SkyBlockMemberPlayerStatsMythos; + winter: SkyBlockMemberPlayerStatsWinter; + endIsland: SkyBlockMemberPlayerStatsEndIsland; + races: Record>; + constructor(data: Record) { + this.fishing = new SkyBlockMemberPlayerStatsFishing({ + seaCreatureKills: data?.sea_creature_kills || 0, + ...(data?.items_fished || {}) + }); + this.glowingMushroomsBroken = data?.glowing_mushrooms_broken || 0; + this.highestDamage = data?.highest_damage || 0; + this.highestCriticalDamage = data?.highest_critical_damage || 0; + this.kills = { + total: Object.values(data?.kills || {}).reduce((acc: any, curr) => acc + curr, 0) as number, + ...Object.keys(data?.kills || {}) + .filter((key) => key !== 'total') + .sort((a, b) => data?.kills[b] - data?.kills[a]) + .map((key) => ({ [key]: data?.kills[key] })) + .reduce((acc, curr) => ({ ...acc, ...curr }), {}) + }; + this.deaths = { + total: Object.values(data?.deaths || {}).reduce((acc: any, curr) => acc + curr, 0) as number, + ...Object.keys(data?.deaths || {}) + .filter((key) => key !== 'total') + .sort((a, b) => data?.deaths[b] - data?.deaths[a]) + .map((key) => ({ [key]: data?.deaths[key] })) + .reduce((acc, curr) => ({ ...acc, ...curr }), {}) + }; + this.auctions = new SkyBlockMemberPlayerStatsAuctions(data?.auctions || {}); + this.candy = new SkyBlockMemberPlayerStatsCandy({ + ...(data?.candy_collected || {}), + ...(data?.spooky?.bats_spawned || {}) + }); + this.gifts = new SkyBlockMemberPlayerStatsGifts(data?.gifts || {}); + this.mythos = new SkyBlockMemberPlayerStatsMythos(data?.mythos || {}); + this.winter = new SkyBlockMemberPlayerStatsWinter(data?.winter || {}); + this.endIsland = new SkyBlockMemberPlayerStatsEndIsland(data?.end_island || {}); + this.races = data?.races || {}; + } +} + +export default SkyBlockMemberPlayerStats; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.test.ts new file mode 100644 index 000000000..f14468d99 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.test.ts @@ -0,0 +1,43 @@ +import SkyBlockMemberPlayerStatsAuctions from './SkyBlockMemberPlayerStatsAuctions.js'; +import SkyBlockMemberPlayerStatsAuctionsStats from './SkyBlockMemberPlayerStatsAuctionsStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsAuctions', () => { + const data = new SkyBlockMemberPlayerStatsAuctions({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsAuctions); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bids).toBeDefined(); + expect(data.bids).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bids).toEqualTypeOf(); + expect(data.highestBid).toBeDefined(); + expect(data.highestBid).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestBid).toEqualTypeOf(); + expect(data.won).toBeDefined(); + expect(data.won).toBeGreaterThanOrEqual(0); + expectTypeOf(data.won).toEqualTypeOf(); + expect(data.goldSpent).toBeDefined(); + expect(data.goldSpent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldSpent).toEqualTypeOf(); + expect(data.created).toBeDefined(); + expect(data.created).toBeGreaterThanOrEqual(0); + expectTypeOf(data.created).toEqualTypeOf(); + expect(data.fees).toBeDefined(); + expect(data.fees).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fees).toEqualTypeOf(); + expect(data.completed).toBeDefined(); + expect(data.completed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completed).toEqualTypeOf(); + expect(data.goldEarned).toBeDefined(); + expect(data.goldEarned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldEarned).toEqualTypeOf(); + expect(data.noBids).toBeDefined(); + expect(data.noBids).toBeGreaterThanOrEqual(0); + expectTypeOf(data.noBids).toEqualTypeOf(); + expect(data.auctionsSold).toBeDefined(); + expect(data.auctionsSold).toBeInstanceOf(SkyBlockMemberPlayerStatsAuctionsStats); + expectTypeOf(data.auctionsSold).toEqualTypeOf(); + expect(data.auctionsBought).toBeDefined(); + expect(data.auctionsBought).toBeInstanceOf(SkyBlockMemberPlayerStatsAuctionsStats); + expectTypeOf(data.auctionsBought).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.ts new file mode 100644 index 000000000..d7304ebe2 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.ts @@ -0,0 +1,30 @@ +import SkyBlockMemberPlayerStatsAuctionsStats from './SkyBlockMemberPlayerStatsAuctionsStats.js'; + +class SkyBlockMemberPlayerStatsAuctions { + bids: number; + highestBid: number; + won: number; + goldSpent: number; + created: number; + fees: number; + completed: number; + goldEarned: number; + noBids: number; + auctionsSold: SkyBlockMemberPlayerStatsAuctionsStats; + auctionsBought: SkyBlockMemberPlayerStatsAuctionsStats; + constructor(data: Record) { + this.bids = data?.bids || 0; + this.highestBid = data?.highest_bid || 0; + this.won = data?.won || 0; + this.goldSpent = data?.gold_spent || 0; + this.created = data?.created || 0; + this.fees = data?.fees || 0; + this.completed = data?.completed || 0; + this.goldEarned = data?.gold_earned || 0; + this.noBids = data?.no_bids || 0; + this.auctionsSold = new SkyBlockMemberPlayerStatsAuctionsStats(data?.total_sold || {}); + this.auctionsBought = new SkyBlockMemberPlayerStatsAuctionsStats(data?.total_bought || {}); + } +} + +export default SkyBlockMemberPlayerStatsAuctions; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.test.ts new file mode 100644 index 000000000..6db507a57 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.test.ts @@ -0,0 +1,38 @@ +import SkyBlockMemberPlayerStatsAuctionsStats from './SkyBlockMemberPlayerStatsAuctionsStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsAuctionsStats', () => { + const data = new SkyBlockMemberPlayerStatsAuctionsStats({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsAuctionsStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.common).toBeDefined(); + expect(data.common).toBeGreaterThanOrEqual(0); + expectTypeOf(data.common).toEqualTypeOf(); + expect(data.uncommon).toBeDefined(); + expect(data.uncommon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.uncommon).toEqualTypeOf(); + expect(data.rare).toBeDefined(); + expect(data.rare).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rare).toEqualTypeOf(); + expect(data.epic).toBeDefined(); + expect(data.epic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.epic).toEqualTypeOf(); + expect(data.legendary).toBeDefined(); + expect(data.legendary).toBeGreaterThanOrEqual(0); + expectTypeOf(data.legendary).toEqualTypeOf(); + expect(data.special).toBeDefined(); + expect(data.special).toBeGreaterThanOrEqual(0); + expectTypeOf(data.special).toEqualTypeOf(); + expect(data.mythic).toBeDefined(); + expect(data.mythic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mythic).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.ts new file mode 100644 index 000000000..cbf4f0d29 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.ts @@ -0,0 +1,26 @@ +class SkyBlockMemberPlayerStatsAuctionsStats { + common: number; + uncommon: number; + rare: number; + epic: number; + legendary: number; + special: number; + mythic: number; + total: number; + constructor(data: Record) { + this.common = data?.COMMON || 0; + this.uncommon = data?.UNCOMMON || 0; + this.rare = data?.RARE || 0; + this.epic = data?.EPIC || 0; + this.legendary = data?.LEGENDARY || 0; + this.special = data?.SPECIAL || 0; + this.mythic = data?.MYTHIC || 0; + this.total = this.common + this.uncommon + this.rare + this.epic + this.legendary + this.special + this.mythic; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberPlayerStatsAuctionsStats; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.test.ts new file mode 100644 index 000000000..1ecbc598b --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.test.ts @@ -0,0 +1,28 @@ +import SkyBlockMemberPlayerStatsCandy from './SkyBlockMemberPlayerStatsCandy.js'; +import SkyBlockMemberPlayerStatsSpookyFestival from './SkyBlockMemberPlayerStatsSpookyFestival.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsCandy', () => { + const data = new SkyBlockMemberPlayerStatsCandy({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsCandy); + expectTypeOf(data).toEqualTypeOf(); + expect(data.green).toBeDefined(); + expect(data.green).toBeGreaterThanOrEqual(0); + expectTypeOf(data.green).toEqualTypeOf(); + expect(data.purple).toBeDefined(); + expect(data.purple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.purple).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.batsSpawned).toBeDefined(); + expectTypeOf(data.batsSpawned).toEqualTypeOf>(); + expect(data.festivals).toBeDefined(); + expectTypeOf(data.festivals).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.ts new file mode 100644 index 000000000..51e53dc43 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.ts @@ -0,0 +1,28 @@ +import SkyBlockMemberPlayerStatsSpookyFestival from './SkyBlockMemberPlayerStatsSpookyFestival.js'; + +class SkyBlockMemberPlayerStatsCandy { + green: number; + purple: number; + total: number; + batsSpawned: Record; + festivals: SkyBlockMemberPlayerStatsSpookyFestival[]; + constructor(data: Record) { + this.green = data?.green_candy || 0; + this.purple = data?.purple_candy || 0; + this.total = this.green + this.purple; + this.batsSpawned = data?.bats_spawned || {}; + this.festivals = Object.keys(data || {}) + .filter((key) => key.startsWith('spooky_festival_')) + .map( + (key) => + new SkyBlockMemberPlayerStatsSpookyFestival(data?.[key], Number(key.split('spooky_festival_')[1] || '0')) + ) + .sort((a, b) => a.year - b.year); + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberPlayerStatsCandy; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.test.ts new file mode 100644 index 000000000..3952ca0ed --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.test.ts @@ -0,0 +1,19 @@ +import SkyBlockMemberPlayerStatsEndIsland from './SkyBlockMemberPlayerStatsEndIsland.js'; +import SkyBlockMemberPlayerStatsEndIslandDragonFight from './SkyBlockMemberPlayerStatsEndIslandDragonFight.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsEndIsland', () => { + const data = new SkyBlockMemberPlayerStatsEndIsland({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIsland); + expectTypeOf(data).toEqualTypeOf(); + expect(data.dragonFight).toBeDefined(); + expect(data.dragonFight).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFight); + expectTypeOf(data.dragonFight).toEqualTypeOf(); + expect(data.summoningEyesCollected).toBeDefined(); + expect(data.summoningEyesCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.summoningEyesCollected).toEqualTypeOf(); + expect(data.specialZealotLootCollected).toBeDefined(); + expect(data.specialZealotLootCollected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.specialZealotLootCollected).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.ts new file mode 100644 index 000000000..efb67f54b --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.ts @@ -0,0 +1,14 @@ +import SkyBlockMemberPlayerStatsEndIslandDragonFight from './SkyBlockMemberPlayerStatsEndIslandDragonFight.js'; + +class SkyBlockMemberPlayerStatsEndIsland { + dragonFight: SkyBlockMemberPlayerStatsEndIslandDragonFight; + summoningEyesCollected: number; + specialZealotLootCollected: number; + constructor(data: Record) { + this.dragonFight = new SkyBlockMemberPlayerStatsEndIslandDragonFight(data?.dragon_fight || {}); + this.summoningEyesCollected = data?.summoning_eyes_collected || 0; + this.specialZealotLootCollected = data?.special_zealot_loot_collected || 0; + } +} + +export default SkyBlockMemberPlayerStatsEndIsland; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.test.ts new file mode 100644 index 000000000..958bd476d --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.test.ts @@ -0,0 +1,35 @@ +/* eslint-disable @stylistic/max-len */ +import SkyBlockMemberPlayerStatsEndIslandDragonFight from './SkyBlockMemberPlayerStatsEndIslandDragonFight.js'; +import SkyBlockMemberPlayerStatsEndIslandDragonFightDragon from './SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsEndIslandDragonFight', () => { + const data = new SkyBlockMemberPlayerStatsEndIslandDragonFight({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFight); + expectTypeOf(data).toEqualTypeOf(); + expect(data.enderCrystalsDestroyed).toBeDefined(); + expect(data.enderCrystalsDestroyed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.enderCrystalsDestroyed).toEqualTypeOf(); + expect(data.protector).toBeDefined(); + expect(data.protector).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.protector).toEqualTypeOf(); + expect(data.old).toBeDefined(); + expect(data.old).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.old).toEqualTypeOf(); + expect(data.unstable).toBeDefined(); + expect(data.unstable).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.unstable).toEqualTypeOf(); + expect(data.young).toBeDefined(); + expect(data.young).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.young).toEqualTypeOf(); + expect(data.strong).toBeDefined(); + expect(data.strong).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.strong).toEqualTypeOf(); + expect(data.wise).toBeDefined(); + expect(data.wise).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.wise).toEqualTypeOf(); + expect(data.superior).toBeDefined(); + expect(data.superior).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data.superior).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.ts new file mode 100644 index 000000000..e9ab9e178 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.ts @@ -0,0 +1,25 @@ +// eslint-disable-next-line @stylistic/max-len +import SkyBlockMemberPlayerStatsEndIslandDragonFightDragon from './SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.js'; + +class SkyBlockMemberPlayerStatsEndIslandDragonFight { + enderCrystalsDestroyed: number; + protector: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + old: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + unstable: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + young: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + strong: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + wise: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + superior: SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; + constructor(data: Record) { + this.enderCrystalsDestroyed = data?.ender_crystals_destroyed || 0; + this.protector = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'protector'); + this.old = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'old'); + this.unstable = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'unstable'); + this.young = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'young'); + this.strong = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'strong'); + this.wise = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'wise'); + this.superior = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon(data || {}, 'superior'); + } +} + +export default SkyBlockMemberPlayerStatsEndIslandDragonFight; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.test.ts new file mode 100644 index 000000000..6d97bdae9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.test.ts @@ -0,0 +1,30 @@ +/* eslint-disable @stylistic/max-len */ +import SkyBlockMemberPlayerStatsEndIslandDragonFightDragon from './SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsEndIslandDragonFightDragon', () => { + const data = new SkyBlockMemberPlayerStatsEndIslandDragonFightDragon({ stats: 'meow' }, 'old'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsEndIslandDragonFightDragon); + expectTypeOf(data).toEqualTypeOf(); + expect(data.mostDamage).toBeDefined(); + expect(data.mostDamage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamage).toEqualTypeOf(); + expect(data.highestRank).toBeDefined(); + expect(data.highestRank).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestRank).toEqualTypeOf(); + expect(data.fastestKill).toBeDefined(); + expect(data.fastestKill).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fastestKill).toEqualTypeOf(); + expect(data.amountSummoned).toBeDefined(); + expect(data.amountSummoned).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amountSummoned).toEqualTypeOf(); + expect(data.summoningEyesContributed).toBeDefined(); + expect(data.summoningEyesContributed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.summoningEyesContributed).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.amountSummoned); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.ts new file mode 100644 index 000000000..6bb28d6d2 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.ts @@ -0,0 +1,22 @@ +import type { SkyBlockDragon } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberPlayerStatsEndIslandDragonFightDragon { + mostDamage: number; + highestRank: number; + fastestKill: number; + amountSummoned: number; + summoningEyesContributed: number; + constructor(data: Record, dragon: SkyBlockDragon) { + this.mostDamage = data?.most_damage?.[dragon] || 0; + this.highestRank = data?.highest_rank?.[dragon] || 0; + this.fastestKill = data?.fastest_kill?.[dragon] || 0; + this.amountSummoned = data?.amount_summoned?.[dragon] || 0; + this.summoningEyesContributed = data?.summoning_eyes_contributed?.[dragon] || 0; + } + + toString(): number { + return this.amountSummoned; + } +} + +export default SkyBlockMemberPlayerStatsEndIslandDragonFightDragon; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.test.ts new file mode 100644 index 000000000..4df347269 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.test.ts @@ -0,0 +1,32 @@ +import SkyBlockMemberPlayerStatsFishing from './SkyBlockMemberPlayerStatsFishing.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsFishing', () => { + const data = new SkyBlockMemberPlayerStatsFishing({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsFishing); + expectTypeOf(data).toEqualTypeOf(); + expect(data.seaCreaturesKills).toBeDefined(); + expect(data.seaCreaturesKills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.seaCreaturesKills).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.treasure).toBeDefined(); + expect(data.treasure).toBeGreaterThanOrEqual(0); + expectTypeOf(data.treasure).toEqualTypeOf(); + expect(data.largeTreasure).toBeDefined(); + expect(data.largeTreasure).toBeGreaterThanOrEqual(0); + expectTypeOf(data.largeTreasure).toEqualTypeOf(); + expect(data.trophyFish).toBeDefined(); + expect(data.trophyFish).toBeGreaterThanOrEqual(0); + expectTypeOf(data.trophyFish).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.ts new file mode 100644 index 000000000..bce29e876 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.ts @@ -0,0 +1,22 @@ +class SkyBlockMemberPlayerStatsFishing { + seaCreaturesKills: number; + normal: number; + treasure: number; + largeTreasure: number; + trophyFish: number; + total: number; + constructor(data: Record) { + this.seaCreaturesKills = data?.seaCreatureKills || 0; + this.normal = data?.normal || 0; + this.treasure = data?.treasure || 0; + this.largeTreasure = data?.large_treasure || 0; + this.trophyFish = data?.trophy_fish || 0; + this.total = this.normal + this.treasure + this.largeTreasure + this.trophyFish; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberPlayerStatsFishing; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.test.ts new file mode 100644 index 000000000..f3cdeb597 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberPlayerStatsGifts from './SkyBlockMemberPlayerStatsGifts.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsGifts', () => { + const data = new SkyBlockMemberPlayerStatsGifts({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsGifts); + expectTypeOf(data).toEqualTypeOf(); + expect(data.received).toBeDefined(); + expect(data.received).toBeGreaterThanOrEqual(0); + expectTypeOf(data.received).toEqualTypeOf(); + expect(data.given).toBeDefined(); + expect(data.given).toBeGreaterThanOrEqual(0); + expectTypeOf(data.given).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.ts new file mode 100644 index 000000000..5b2094b5f --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberPlayerStatsGifts { + received: number; + given: number; + total: number; + constructor(data: Record) { + this.received = data?.total_received || 0; + this.given = data?.total_given || 0; + this.total = this.received + this.given; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberPlayerStatsGifts; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.test.ts new file mode 100644 index 000000000..b70380e5a --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberPlayerStatsMythos from './SkyBlockMemberPlayerStatsMythos.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsMythos', () => { + const data = new SkyBlockMemberPlayerStatsMythos({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsMythos); + expectTypeOf(data).toEqualTypeOf(); + expect(data.kills).toBeDefined(); + expect(data.kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kills).toEqualTypeOf(); + expect(data.burrowsDugNext).toBeDefined(); + expect(data.burrowsDugNext).toBeGreaterThanOrEqual(0); + expectTypeOf(data.burrowsDugNext).toEqualTypeOf(); + expect(data.burrowsDugCombat).toBeDefined(); + expect(data.burrowsDugCombat).toBeGreaterThanOrEqual(0); + expectTypeOf(data.burrowsDugCombat).toEqualTypeOf(); + expect(data.burrowsDugTreasure).toBeDefined(); + expect(data.burrowsDugTreasure).toBeGreaterThanOrEqual(0); + expectTypeOf(data.burrowsDugTreasure).toEqualTypeOf(); + expect(data.burrowsChainsComplete).toBeDefined(); + expect(data.burrowsChainsComplete).toBeGreaterThanOrEqual(0); + expectTypeOf(data.burrowsChainsComplete).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.kills); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.ts new file mode 100644 index 000000000..f221acd4a --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.ts @@ -0,0 +1,20 @@ +class SkyBlockMemberPlayerStatsMythos { + kills: number; + burrowsDugNext: number; + burrowsDugCombat: number; + burrowsDugTreasure: number; + burrowsChainsComplete: number; + constructor(data: Record) { + this.kills = data?.kills || 0; + this.burrowsDugNext = data?.burrows_dug_next?.total || 0; + this.burrowsDugCombat = data?.burrows_dug_combat?.total || 0; + this.burrowsDugTreasure = data?.burrows_dug_treasure?.total || 0; + this.burrowsChainsComplete = data?.burrows_chains_complete?.total || 0; + } + + toString(): number { + return this.kills; + } +} + +export default SkyBlockMemberPlayerStatsMythos; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.test.ts new file mode 100644 index 000000000..336710fd1 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.test.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberPlayerStatsSpookyFestival from './SkyBlockMemberPlayerStatsSpookyFestival.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsSpookyFestival', () => { + const data = new SkyBlockMemberPlayerStatsSpookyFestival({ stats: 'meow' }, 100); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsSpookyFestival); + expectTypeOf(data).toEqualTypeOf(); + expect(data.year).toBeDefined(); + expect(data.year).toBeGreaterThanOrEqual(0); + expectTypeOf(data.year).toEqualTypeOf(); + expect(data.green).toBeDefined(); + expect(data.green).toBeGreaterThanOrEqual(0); + expectTypeOf(data.green).toEqualTypeOf(); + expect(data.purple).toBeDefined(); + expect(data.purple).toBeGreaterThanOrEqual(0); + expectTypeOf(data.purple).toEqualTypeOf(); + expect(data.total).toBeDefined(); + expect(data.total).toBeGreaterThanOrEqual(0); + expectTypeOf(data.total).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.total); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.ts new file mode 100644 index 000000000..f502710be --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.ts @@ -0,0 +1,18 @@ +class SkyBlockMemberPlayerStatsSpookyFestival { + year: number; + green: number; + purple: number; + total: number; + constructor(data: Record, year: number) { + this.year = year; + this.green = data?.green_candy || 0; + this.purple = data?.purple_candy || 0; + this.total = this.green + this.purple; + } + + toString(): number { + return this.total; + } +} + +export default SkyBlockMemberPlayerStatsSpookyFestival; diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.test.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.test.ts new file mode 100644 index 000000000..35da5e943 --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.test.ts @@ -0,0 +1,21 @@ +import SkyBlockMemberPlayerStatsWinter from './SkyBlockMemberPlayerStatsWinter.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberPlayerStatsWinter', () => { + const data = new SkyBlockMemberPlayerStatsWinter({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberPlayerStatsWinter); + expectTypeOf(data).toEqualTypeOf(); + expect(data.mostSnowballsHit).toBeDefined(); + expect(data.mostSnowballsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostSnowballsHit).toEqualTypeOf(); + expect(data.mostDamageDealt).toBeDefined(); + expect(data.mostDamageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostDamageDealt).toEqualTypeOf(); + expect(data.mostMagmaDamageDealt).toBeDefined(); + expect(data.mostMagmaDamageDealt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostMagmaDamageDealt).toEqualTypeOf(); + expect(data.mostCannonballsHit).toBeDefined(); + expect(data.mostCannonballsHit).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mostCannonballsHit).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.ts b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.ts new file mode 100644 index 000000000..69ed854bb --- /dev/null +++ b/src/Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.ts @@ -0,0 +1,14 @@ +class SkyBlockMemberPlayerStatsWinter { + mostSnowballsHit: number; + mostDamageDealt: number; + mostMagmaDamageDealt: number; + mostCannonballsHit: number; + constructor(data: Record) { + this.mostSnowballsHit = data?.most_snowballs_hit || 0; + this.mostDamageDealt = data?.most_damage_dealt || 0; + this.mostMagmaDamageDealt = data?.most_magma_damage_dealt || 0; + this.mostCannonballsHit = data?.most_cannonballs_hit || 0; + } +} + +export default SkyBlockMemberPlayerStatsWinter; diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.test.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.test.ts new file mode 100644 index 000000000..fe0dd6155 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.test.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberQuests from './SkyBlockMemberQuests.js'; +import SkyBlockMemberQuestsHarp from './SkyBlockMemberQuestsHarp.js'; +import SkyBlockMemberQuestsTrapper from './SkyBlockMemberQuestsTrapper.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberQuests', () => { + const data = new SkyBlockMemberQuests({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberQuests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.harp).toBeDefined(); + expect(data.harp).toBeInstanceOf(SkyBlockMemberQuestsHarp); + expectTypeOf(data.harp).toEqualTypeOf(); + expect(data.trapper).toBeDefined(); + expect(data.trapper).toBeInstanceOf(SkyBlockMemberQuestsTrapper); + expectTypeOf(data.trapper).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.ts new file mode 100644 index 000000000..7ecaf47c6 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.ts @@ -0,0 +1,13 @@ +import SkyBlockMemberQuestsHarp from './SkyBlockMemberQuestsHarp.js'; +import SkyBlockMemberQuestsTrapper from './SkyBlockMemberQuestsTrapper.js'; + +class SkyBlockMemberQuests { + harp: SkyBlockMemberQuestsHarp; + trapper: SkyBlockMemberQuestsTrapper; + constructor(data: Record) { + this.harp = new SkyBlockMemberQuestsHarp(data?.harp_quest || {}); + this.trapper = new SkyBlockMemberQuestsTrapper(data?.trapper_quest || {}); + } +} + +export default SkyBlockMemberQuests; diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.test.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.test.ts new file mode 100644 index 000000000..00cb99b3e --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.test.ts @@ -0,0 +1,65 @@ +import SkyBlockMemberQuestsHarp from './SkyBlockMemberQuestsHarp.js'; +import SkyBlockMemberQuestsHarpSong from './SkyBlockMemberQuestsHarpSong.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { HarpSong } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberQuestsHarp', () => { + const data = new SkyBlockMemberQuestsHarp({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberQuestsHarp); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selectedSong).toBeDefined(); + expectTypeOf(data.selectedSong).toEqualTypeOf(); + expect(data.selectedSongTimestamp).toBeDefined(); + expect(data.selectedSongTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.selectedSongTimestamp).toEqualTypeOf(); + expect(data.selectedSongDate).toBeDefined(); + expect(data.selectedSongDate).toBeInstanceOf(Date); + expectTypeOf(data.selectedSongDate).toEqualTypeOf(); + expect(data.claimedTalisman).toBeDefined(); + expectTypeOf(data.claimedTalisman).toEqualTypeOf(); + expect(data.hymnJoy).toBeDefined(); + expect(data.hymnJoy).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.hymnJoy).toEqualTypeOf(); + expect(data.frereJacques).toBeDefined(); + expect(data.frereJacques).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.frereJacques).toEqualTypeOf(); + expect(data.amazingGrace).toBeDefined(); + expect(data.amazingGrace).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.amazingGrace).toEqualTypeOf(); + expect(data.brahms).toBeDefined(); + expect(data.brahms).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.brahms).toEqualTypeOf(); + expect(data.happyBirthday).toBeDefined(); + expect(data.happyBirthday).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.happyBirthday).toEqualTypeOf(); + expect(data.greensleeves).toBeDefined(); + expect(data.greensleeves).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.greensleeves).toEqualTypeOf(); + expect(data.jeopardy).toBeDefined(); + expect(data.jeopardy).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.jeopardy).toEqualTypeOf(); + expect(data.minuet).toBeDefined(); + expect(data.minuet).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.minuet).toEqualTypeOf(); + expect(data.joyWorld).toBeDefined(); + expect(data.joyWorld).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.joyWorld).toEqualTypeOf(); + expect(data.pureImagination).toBeDefined(); + expect(data.pureImagination).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.pureImagination).toEqualTypeOf(); + expect(data.vieEnRose).toBeDefined(); + expect(data.vieEnRose).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.vieEnRose).toEqualTypeOf(); + expect(data.fireAndFlames).toBeDefined(); + expect(data.fireAndFlames).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.fireAndFlames).toEqualTypeOf(); + expect(data.pachelbel).toBeDefined(); + expect(data.pachelbel).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data.pachelbel).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => HarpSong | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.selectedSong); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.ts new file mode 100644 index 000000000..3883cdc9b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.ts @@ -0,0 +1,47 @@ +import SkyBlockMemberQuestsHarpSong from './SkyBlockMemberQuestsHarpSong.js'; +import type { HarpSong } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberQuestsHarp { + selectedSong: HarpSong | 'UNKNOWN'; + selectedSongTimestamp: number; + selectedSongDate: Date; + claimedTalisman: boolean; + hymnJoy: SkyBlockMemberQuestsHarpSong; + frereJacques: SkyBlockMemberQuestsHarpSong; + amazingGrace: SkyBlockMemberQuestsHarpSong; + brahms: SkyBlockMemberQuestsHarpSong; + happyBirthday: SkyBlockMemberQuestsHarpSong; + greensleeves: SkyBlockMemberQuestsHarpSong; + jeopardy: SkyBlockMemberQuestsHarpSong; + minuet: SkyBlockMemberQuestsHarpSong; + joyWorld: SkyBlockMemberQuestsHarpSong; + pureImagination: SkyBlockMemberQuestsHarpSong; + vieEnRose: SkyBlockMemberQuestsHarpSong; + fireAndFlames: SkyBlockMemberQuestsHarpSong; + pachelbel: SkyBlockMemberQuestsHarpSong; + constructor(data: Record) { + this.selectedSong = data?.selected_song || 'UNKNOWN'; + this.selectedSongTimestamp = data?.selected_song_epoch || 0; + this.selectedSongDate = new Date(this.selectedSongTimestamp); + this.claimedTalisman = data?.claimed_talisman || false; + this.hymnJoy = new SkyBlockMemberQuestsHarpSong(data || {}, 'hymn_joy'); + this.frereJacques = new SkyBlockMemberQuestsHarpSong(data || {}, 'frere_jacques'); + this.amazingGrace = new SkyBlockMemberQuestsHarpSong(data || {}, 'amazing_grace'); + this.brahms = new SkyBlockMemberQuestsHarpSong(data || {}, 'brahms'); + this.happyBirthday = new SkyBlockMemberQuestsHarpSong(data || {}, 'happy_birthday'); + this.greensleeves = new SkyBlockMemberQuestsHarpSong(data || {}, 'greensleeves'); + this.jeopardy = new SkyBlockMemberQuestsHarpSong(data || {}, 'jeopardy'); + this.minuet = new SkyBlockMemberQuestsHarpSong(data || {}, 'minuet'); + this.joyWorld = new SkyBlockMemberQuestsHarpSong(data || {}, 'joy_world'); + this.pureImagination = new SkyBlockMemberQuestsHarpSong(data || {}, 'pure_imagination'); + this.vieEnRose = new SkyBlockMemberQuestsHarpSong(data || {}, 'vie_en_rose'); + this.fireAndFlames = new SkyBlockMemberQuestsHarpSong(data || {}, 'fire_and_flames'); + this.pachelbel = new SkyBlockMemberQuestsHarpSong(data || {}, 'pachelbel'); + } + + toString(): HarpSong | 'UNKNOWN' { + return this.selectedSong; + } +} + +export default SkyBlockMemberQuestsHarp; diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.test.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.test.ts new file mode 100644 index 000000000..f705c1193 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.test.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberQuestsHarpSong from './SkyBlockMemberQuestsHarpSong.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { HarpSong } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberQuestsHarpSong', () => { + const data = new SkyBlockMemberQuestsHarpSong({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberQuestsHarpSong); + expectTypeOf(data).toEqualTypeOf(); + expect(data.song).toBeDefined(); + expectTypeOf(data.song).toEqualTypeOf(); + expect(data.completions).toBeDefined(); + expect(data.completions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completions).toEqualTypeOf(); + expect(data.bestCompletions).toBeDefined(); + expect(data.bestCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bestCompletions).toEqualTypeOf(); + expect(data.perfectCompletions).toBeDefined(); + expect(data.perfectCompletions).toBeGreaterThanOrEqual(0); + expectTypeOf(data.perfectCompletions).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => HarpSong | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.song); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.ts new file mode 100644 index 000000000..76c160daf --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.ts @@ -0,0 +1,20 @@ +import type { HarpSong } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberQuestsHarpSong { + song: HarpSong | 'UNKNOWN'; + completions: number; + bestCompletions: number; + perfectCompletions: number; + constructor(data: Record, song: HarpSong | 'UNKNOWN' = 'UNKNOWN') { + this.song = song; + this.completions = data?.[`song_${song}_completions`] || 0; + this.bestCompletions = data?.[`song_${song}_best_completions`] || 0; + this.perfectCompletions = data?.[`song_${song}_perfect_completions`] || 0; + } + + toString(): HarpSong | 'UNKNOWN' { + return this.song; + } +} + +export default SkyBlockMemberQuestsHarpSong; diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.test.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.test.ts new file mode 100644 index 000000000..b0aa40612 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberQuestsTrapper from './SkyBlockMemberQuestsTrapper.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberQuestsTrapper', () => { + const data = new SkyBlockMemberQuestsTrapper({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberQuestsTrapper); + expectTypeOf(data).toEqualTypeOf(); + expect(data.peltCount).toBeDefined(); + expect(data.peltCount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.peltCount).toEqualTypeOf(); + expect(data.lastCompletedTimestamp).toBeDefined(); + expect(data.lastCompletedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastCompletedTimestamp).toEqualTypeOf(); + expect(data.lastCompletedAt).toBeDefined(); + expect(data.lastCompletedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastCompletedAt).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.peltCount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.ts b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.ts new file mode 100644 index 000000000..59083375a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberQuestsTrapper { + peltCount: number; + lastCompletedTimestamp: number; + lastCompletedAt: Date; + constructor(data: Record) { + this.peltCount = data?.pelt_count || 0; + this.lastCompletedTimestamp = data?.last_task_time || 0; + this.lastCompletedAt = new Date(this.lastCompletedTimestamp); + } + + toString(): number { + return this.peltCount; + } +} + +export default SkyBlockMemberQuestsTrapper; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.test.ts new file mode 100644 index 000000000..34012683b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.test.ts @@ -0,0 +1,59 @@ +import SkyBlockMemberRift from './SkyBlockMemberRift.js'; +import SkyBlockMemberRiftAccess from './SkyBlockMemberRiftAccess.js'; +import SkyBlockMemberRiftBlackLagoon from './SkyBlockMemberRiftBlackLagoon.js'; +import SkyBlockMemberRiftCastle from './SkyBlockMemberRiftCastle.js'; +import SkyBlockMemberRiftDeadCats from './SkyBlockMemberRiftDeadCats.js'; +import SkyBlockMemberRiftDreamFarm from './SkyBlockMemberRiftDreamFarm.js'; +import SkyBlockMemberRiftEnigma from './SkyBlockMemberRiftEnigma.js'; +import SkyBlockMemberRiftGallery from './SkyBlockMemberRiftGallery.js'; +import SkyBlockMemberRiftInventory from './SkyBlockMemberRiftInventory.js'; +import SkyBlockMemberRiftVillagePlaza from './VillagePlaza/SkyBlockMemberRiftVillagePlaza.js'; +import SkyBlockMemberRiftWestVillage from './WestVillage/SkyBlockMemberRiftWestVillage.js'; +import SkyBlockMemberRiftWitherCage from './SkyBlockMemberRiftWitherCage.js'; +import SkyBlockMemberRiftWizardTower from './SkyBlockMemberRiftWizardTower.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRift', () => { + const data = new SkyBlockMemberRift({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRift); + expectTypeOf(data).toEqualTypeOf(); + expect(data.villagePlaza).toBeDefined(); + expect(data.villagePlaza).toBeInstanceOf(SkyBlockMemberRiftVillagePlaza); + expectTypeOf(data.villagePlaza).toEqualTypeOf(); + expect(data.witherCage).toBeDefined(); + expect(data.witherCage).toBeInstanceOf(SkyBlockMemberRiftWitherCage); + expectTypeOf(data.witherCage).toEqualTypeOf(); + expect(data.blackLagoon).toBeDefined(); + expect(data.blackLagoon).toBeInstanceOf(SkyBlockMemberRiftBlackLagoon); + expectTypeOf(data.blackLagoon).toEqualTypeOf(); + expect(data.deadCats).toBeDefined(); + expect(data.deadCats).toBeInstanceOf(SkyBlockMemberRiftDeadCats); + expectTypeOf(data.deadCats).toEqualTypeOf(); + expect(data.wizardTower).toBeDefined(); + expect(data.wizardTower).toBeInstanceOf(SkyBlockMemberRiftWizardTower); + expectTypeOf(data.wizardTower).toEqualTypeOf(); + expect(data.enigma).toBeDefined(); + expect(data.enigma).toBeInstanceOf(SkyBlockMemberRiftEnigma); + expectTypeOf(data.enigma).toEqualTypeOf(); + expect(data.gallery).toBeDefined(); + expect(data.gallery).toBeInstanceOf(SkyBlockMemberRiftGallery); + expectTypeOf(data.gallery).toEqualTypeOf(); + expect(data.lifetimePurchasedBoundaries).toBeDefined(); + expectTypeOf(data.lifetimePurchasedBoundaries).toEqualTypeOf(); + expect(data.westVillage).toBeDefined(); + expect(data.westVillage).toBeInstanceOf(SkyBlockMemberRiftWestVillage); + expectTypeOf(data.westVillage).toEqualTypeOf(); + expect(data.castle).toBeDefined(); + expect(data.castle).toBeInstanceOf(SkyBlockMemberRiftCastle); + expectTypeOf(data.castle).toEqualTypeOf(); + expect(data.access).toBeDefined(); + expect(data.access).toBeInstanceOf(SkyBlockMemberRiftAccess); + expectTypeOf(data.access).toEqualTypeOf(); + expect(data.dreamFarm).toBeDefined(); + expect(data.dreamFarm).toBeInstanceOf(SkyBlockMemberRiftDreamFarm); + expectTypeOf(data.dreamFarm).toEqualTypeOf(); + expect(data.inventory).toBeDefined(); + expect(data.inventory).toBeInstanceOf(SkyBlockMemberRiftInventory); + expectTypeOf(data.inventory).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.ts new file mode 100644 index 000000000..b2e5ee33e --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.ts @@ -0,0 +1,45 @@ +import SkyBlockMemberRiftAccess from './SkyBlockMemberRiftAccess.js'; +import SkyBlockMemberRiftBlackLagoon from './SkyBlockMemberRiftBlackLagoon.js'; +import SkyBlockMemberRiftCastle from './SkyBlockMemberRiftCastle.js'; +import SkyBlockMemberRiftDeadCats from './SkyBlockMemberRiftDeadCats.js'; +import SkyBlockMemberRiftDreamFarm from './SkyBlockMemberRiftDreamFarm.js'; +import SkyBlockMemberRiftEnigma from './SkyBlockMemberRiftEnigma.js'; +import SkyBlockMemberRiftGallery from './SkyBlockMemberRiftGallery.js'; +import SkyBlockMemberRiftInventory from './SkyBlockMemberRiftInventory.js'; +import SkyBlockMemberRiftVillagePlaza from './VillagePlaza/SkyBlockMemberRiftVillagePlaza.js'; +import SkyBlockMemberRiftWestVillage from './WestVillage/SkyBlockMemberRiftWestVillage.js'; +import SkyBlockMemberRiftWitherCage from './SkyBlockMemberRiftWitherCage.js'; +import SkyBlockMemberRiftWizardTower from './SkyBlockMemberRiftWizardTower.js'; + +class SkyBlockMemberRift { + villagePlaza: SkyBlockMemberRiftVillagePlaza; + witherCage: SkyBlockMemberRiftWitherCage; + blackLagoon: SkyBlockMemberRiftBlackLagoon; + deadCats: SkyBlockMemberRiftDeadCats; + wizardTower: SkyBlockMemberRiftWizardTower; + enigma: SkyBlockMemberRiftEnigma; + gallery: SkyBlockMemberRiftGallery; + lifetimePurchasedBoundaries: string[]; + westVillage: SkyBlockMemberRiftWestVillage; + castle: SkyBlockMemberRiftCastle; + access: SkyBlockMemberRiftAccess; + dreamFarm: SkyBlockMemberRiftDreamFarm; + inventory: SkyBlockMemberRiftInventory; + constructor(data: Record) { + this.villagePlaza = new SkyBlockMemberRiftVillagePlaza(data?.village_plaza || {}); + this.witherCage = new SkyBlockMemberRiftWitherCage(data?.wither_cage || {}); + this.blackLagoon = new SkyBlockMemberRiftBlackLagoon(data?.black_lagoon || {}); + this.deadCats = new SkyBlockMemberRiftDeadCats(data?.dead_cats || {}); + this.wizardTower = new SkyBlockMemberRiftWizardTower(data?.wizard_tower || {}); + this.enigma = new SkyBlockMemberRiftEnigma(data?.enigma || {}); + this.gallery = new SkyBlockMemberRiftGallery(data?.gallery || {}); + this.lifetimePurchasedBoundaries = data?.lifetime_purchased_boundaries || []; + this.westVillage = new SkyBlockMemberRiftWestVillage(data?.west_village || {}); + this.castle = new SkyBlockMemberRiftCastle(data?.castle || {}); + this.access = new SkyBlockMemberRiftAccess(data?.access || {}); + this.dreamFarm = new SkyBlockMemberRiftDreamFarm(data?.dreamfarm || {}); + this.inventory = new SkyBlockMemberRiftInventory(data?.inventory || {}); + } +} + +export default SkyBlockMemberRift; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.test.ts new file mode 100644 index 000000000..d0a1ab02a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberRiftAccess from './SkyBlockMemberRiftAccess.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftAccess', () => { + const data = new SkyBlockMemberRiftAccess({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftAccess); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastFree).toBeDefined(); + expect(data.lastFree).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastFree).toEqualTypeOf(); + expect(data.lastFreeAt).toBeDefined(); + expect(data.lastFreeAt).toBeInstanceOf(Date); + expectTypeOf(data.lastFreeAt).toEqualTypeOf(); + expect(data.consumedPrism).toBeDefined(); + expectTypeOf(data.consumedPrism).toEqualTypeOf(); + expect(data.chargeTrackTimestamp).toBeDefined(); + expect(data.chargeTrackTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.chargeTrackTimestamp).toEqualTypeOf(); + expect(data.chargeTrackTimestampAt).toBeDefined(); + expect(data.chargeTrackTimestampAt).toBeInstanceOf(Date); + expectTypeOf(data.chargeTrackTimestampAt).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.ts new file mode 100644 index 000000000..f0ea9723c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberRiftAccess { + lastFree: number; + lastFreeAt: Date; + consumedPrism: boolean; + chargeTrackTimestamp: number; + chargeTrackTimestampAt: Date; + constructor(data: Record) { + this.lastFree = data?.last_free || 0; + this.lastFreeAt = new Date(this.lastFree); + this.consumedPrism = data?.consumed_prism || false; + this.chargeTrackTimestamp = data?.charge_track_timestamp || 0; + this.chargeTrackTimestampAt = new Date(this.chargeTrackTimestamp); + } +} + +export default SkyBlockMemberRiftAccess; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.test.ts new file mode 100644 index 000000000..8b56ab21f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberRiftBlackLagoon from './SkyBlockMemberRiftBlackLagoon.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftBlackLagoon', () => { + const data = new SkyBlockMemberRiftBlackLagoon({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftBlackLagoon); + expectTypeOf(data).toEqualTypeOf(); + expect(data.talkedToEdwin).toBeDefined(); + expectTypeOf(data.talkedToEdwin).toEqualTypeOf(); + expect(data.receivedSciencePaper).toBeDefined(); + expectTypeOf(data.receivedSciencePaper).toEqualTypeOf(); + expect(data.deliveredSciencePaper).toBeDefined(); + expectTypeOf(data.deliveredSciencePaper).toEqualTypeOf(); + expect(data.completedStep).toBeDefined(); + expect(data.completedStep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completedStep).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.ts new file mode 100644 index 000000000..6ae8d2540 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.ts @@ -0,0 +1,14 @@ +class SkyBlockMemberRiftBlackLagoon { + talkedToEdwin: boolean; + receivedSciencePaper: boolean; + deliveredSciencePaper: boolean; + completedStep: number; + constructor(data: Record) { + this.talkedToEdwin = data?.talked_to_edwin || false; + this.receivedSciencePaper = data?.received_science_paper || false; + this.deliveredSciencePaper = data?.delivered_science_paper || false; + this.completedStep = data?.completed_step || 0; + } +} + +export default SkyBlockMemberRiftBlackLagoon; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.test.ts new file mode 100644 index 000000000..0ad9f76fa --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.test.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberRiftCastle from './SkyBlockMemberRiftCastle.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftCastle', () => { + const data = new SkyBlockMemberRiftCastle({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftCastle); + expectTypeOf(data).toEqualTypeOf(); + expect(data.unlockedPathwaySkip).toBeDefined(); + expectTypeOf(data.unlockedPathwaySkip).toEqualTypeOf(); + expect(data.fairyStep).toBeDefined(); + expect(data.fairyStep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fairyStep).toEqualTypeOf(); + expect(data.grubberStacks).toBeDefined(); + expect(data.grubberStacks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.grubberStacks).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.ts new file mode 100644 index 000000000..4d46d132c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberRiftCastle { + unlockedPathwaySkip: boolean; + fairyStep: number; + grubberStacks: number; + constructor(data: Record) { + this.unlockedPathwaySkip = data?.unlocked_pathway_skip || false; + this.fairyStep = data?.fairy_step || 0; + this.grubberStacks = data?.grubber_stacks || 0; + } +} + +export default SkyBlockMemberRiftCastle; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.test.ts new file mode 100644 index 000000000..e7253dec3 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.test.ts @@ -0,0 +1,21 @@ +import SkyBlockMemberPet from '../Pets/SkyBlockMemberPet.js'; +import SkyBlockMemberRiftDeadCats from './SkyBlockMemberRiftDeadCats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftDeadCats', () => { + const data = new SkyBlockMemberRiftDeadCats({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftDeadCats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.talkedToJacquelle).toBeDefined(); + expectTypeOf(data.talkedToJacquelle).toEqualTypeOf(); + expect(data.pickedUpDetector).toBeDefined(); + expectTypeOf(data.pickedUpDetector).toEqualTypeOf(); + expect(data.foundCats).toBeDefined(); + expectTypeOf(data.foundCats).toEqualTypeOf(); + expect(data.unlockedPet).toBeDefined(); + expectTypeOf(data.unlockedPet).toEqualTypeOf(); + expect(data.montezuma).toBeDefined(); + expect(data.montezuma).toBeInstanceOf(SkyBlockMemberPet); + expectTypeOf(data.montezuma).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.ts new file mode 100644 index 000000000..e416499ca --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberPet from '../Pets/SkyBlockMemberPet.js'; + +class SkyBlockMemberRiftDeadCats { + talkedToJacquelle: boolean; + pickedUpDetector: boolean; + foundCats: string[]; + unlockedPet: boolean; + montezuma: SkyBlockMemberPet; + constructor(data: Record) { + this.talkedToJacquelle = data?.talked_to_jacquelle || false; + this.pickedUpDetector = data?.picked_up_detector || false; + this.foundCats = data?.found_cats || []; + this.unlockedPet = data?.unlocked_pet || false; + this.montezuma = new SkyBlockMemberPet(data?.montezuma || {}); + } +} + +export default SkyBlockMemberRiftDeadCats; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.test.ts new file mode 100644 index 000000000..3b997bbfe --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.test.ts @@ -0,0 +1,14 @@ +import SkyBlockMemberRiftDreamFarm from './SkyBlockMemberRiftDreamFarm.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftDreamFarm', () => { + const data = new SkyBlockMemberRiftDreamFarm({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftDreamFarm); + expectTypeOf(data).toEqualTypeOf(); + expect(data.shaniaStage).toBeDefined(); + expect(data.shaniaStage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.shaniaStage).toEqualTypeOf(); + expect(data.caducousFeederUses).toBeDefined(); + expectTypeOf(data.caducousFeederUses).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.ts new file mode 100644 index 000000000..a69de9947 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.ts @@ -0,0 +1,10 @@ +class SkyBlockMemberRiftDreamFarm { + shaniaStage: number; + caducousFeederUses: number[]; + constructor(data: Record) { + this.shaniaStage = data?.shania_stage || 0; + this.caducousFeederUses = data?.caducous_feeder_uses || []; + } +} + +export default SkyBlockMemberRiftDreamFarm; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.test.ts new file mode 100644 index 000000000..94940e725 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.test.ts @@ -0,0 +1,16 @@ +import SkyBlockMemberRiftEnigma from './SkyBlockMemberRiftEnigma.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftEnigma', () => { + const data = new SkyBlockMemberRiftEnigma({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftEnigma); + expectTypeOf(data).toEqualTypeOf(); + expect(data.boughtCloak).toBeDefined(); + expectTypeOf(data.boughtCloak).toEqualTypeOf(); + expect(data.foundSouls).toBeDefined(); + expectTypeOf(data.foundSouls).toEqualTypeOf(); + expect(data.claimedBonusIndex).toBeDefined(); + expect(data.claimedBonusIndex).toBeGreaterThanOrEqual(0); + expectTypeOf(data.claimedBonusIndex).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.ts new file mode 100644 index 000000000..d8bccc81b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberRiftEnigma { + boughtCloak: boolean; + foundSouls: string[]; + claimedBonusIndex: number; + constructor(data: Record) { + this.boughtCloak = data?.bought_cloak || false; + this.foundSouls = data?.found_souls || []; + this.claimedBonusIndex = data?.claimed_bonus_index || 0; + } +} + +export default SkyBlockMemberRiftEnigma; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.test.ts new file mode 100644 index 000000000..8be761eab --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberRiftGallery from './SkyBlockMemberRiftGallery.js'; +import SkyBlockMemberRiftGallerySecuredTrophy from './SkyBlockMemberRiftGallerySecuredTrophy.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { RiftGalleryTrophy } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberRiftGallery', () => { + const data = new SkyBlockMemberRiftGallery({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftGallery); + expectTypeOf(data).toEqualTypeOf(); + expect(data.eliseStep).toBeDefined(); + expect(data.eliseStep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eliseStep).toEqualTypeOf(); + expect(data.securedTrophies).toBeDefined(); + expectTypeOf(data.securedTrophies).toEqualTypeOf(); + expect(data.sentTrophyDialogues).toBeDefined(); + expectTypeOf(data.sentTrophyDialogues).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.ts new file mode 100644 index 000000000..7644a01cf --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberRiftGallerySecuredTrophy from './SkyBlockMemberRiftGallerySecuredTrophy.js'; +import type { RiftGalleryTrophy } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberRiftGallery { + eliseStep: number; + securedTrophies: SkyBlockMemberRiftGallerySecuredTrophy[]; + sentTrophyDialogues: RiftGalleryTrophy[]; + constructor(data: Record) { + this.eliseStep = data?.elise_step || 0; + this.securedTrophies = (data?.sent_trophy_dialogues || []).map((trophy: Record) => { + new SkyBlockMemberRiftGallerySecuredTrophy(trophy); + }); + this.sentTrophyDialogues = data?.sent_trophy_dialogues || []; + } +} + +export default SkyBlockMemberRiftGallery; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.test.ts new file mode 100644 index 000000000..ae2243a84 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.test.ts @@ -0,0 +1,21 @@ +import SkyBlockMemberRiftGallerySecuredTrophy from './SkyBlockMemberRiftGallerySecuredTrophy.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { RiftGalleryTrophy } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberRiftGallerySecuredTrophy', () => { + const data = new SkyBlockMemberRiftGallerySecuredTrophy({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftGallerySecuredTrophy); + expectTypeOf(data).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expect(data.timestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.timestampAt).toBeDefined(); + expect(data.timestampAt).toBeInstanceOf(Date); + expectTypeOf(data.timestampAt).toEqualTypeOf(); + expect(data.visits).toBeDefined(); + expect(data.visits).toBeGreaterThanOrEqual(0); + expectTypeOf(data.visits).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.ts new file mode 100644 index 000000000..9b56618a9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.ts @@ -0,0 +1,16 @@ +import type { RiftGalleryTrophy } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberRiftGallerySecuredTrophy { + type: RiftGalleryTrophy | 'UNKNOWN'; + timestamp: number; + timestampAt: Date; + visits: number; + constructor(data: Record) { + this.type = data?.type || 0; + this.timestamp = data?.timestamp || 0; + this.timestampAt = new Date(this.timestamp); + this.visits = data?.visits || 0; + } +} + +export default SkyBlockMemberRiftGallerySecuredTrophy; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.test.ts new file mode 100644 index 000000000..76944960c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.test.ts @@ -0,0 +1,26 @@ +import SkyBlockMemberInventoriesArmor from '../Inventories/Armor/SkyBlockMemberInventoriesArmor.js'; +import SkyBlockMemberInventoriesEquipment from '../Inventories/Equipment/SkyBlockMemberInventoriesEquipment.js'; +import SkyBlockMemberInventoriesInventory from '../Inventories/Inventory/SkyBlockMemberInventoriesInventory.js'; +import SkyBlockMemberRiftInventory from './SkyBlockMemberRiftInventory.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftInventory', () => { + const data = new SkyBlockMemberRiftInventory({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftInventory); + expectTypeOf(data).toEqualTypeOf(); + expect(data.enderChestPageIcons).toBeDefined(); + expectTypeOf(data.enderChestPageIcons).toEqualTypeOf<[]>(); + expect(data.inventory).toBeDefined(); + expect(data.inventory).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.inventory).toEqualTypeOf(); + expect(data.armor).toBeDefined(); + expect(data.armor).toBeInstanceOf(SkyBlockMemberInventoriesArmor); + expectTypeOf(data.armor).toEqualTypeOf(); + expect(data.equipment).toBeDefined(); + expect(data.equipment).toBeInstanceOf(SkyBlockMemberInventoriesEquipment); + expectTypeOf(data.equipment).toEqualTypeOf(); + expect(data.enderChest).toBeDefined(); + expect(data.enderChest).toBeInstanceOf(SkyBlockMemberInventoriesInventory); + expectTypeOf(data.enderChest).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.ts new file mode 100644 index 000000000..516830e00 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.ts @@ -0,0 +1,20 @@ +import SkyBlockMemberInventoriesArmor from '../Inventories/Armor/SkyBlockMemberInventoriesArmor.js'; +import SkyBlockMemberInventoriesEquipment from '../Inventories/Equipment/SkyBlockMemberInventoriesEquipment.js'; +import SkyBlockMemberInventoriesInventory from '../Inventories/Inventory/SkyBlockMemberInventoriesInventory.js'; + +class SkyBlockMemberRiftInventory { + enderChestPageIcons: []; + inventory: SkyBlockMemberInventoriesInventory; + armor: SkyBlockMemberInventoriesArmor; + equipment: SkyBlockMemberInventoriesEquipment; + enderChest: SkyBlockMemberInventoriesInventory; + constructor(data: Record) { + this.enderChestPageIcons = data?.ender_chest_page_icons || []; + this.inventory = new SkyBlockMemberInventoriesInventory(data?.inv_contents || {}); + this.armor = new SkyBlockMemberInventoriesArmor(data?.inv_armor || {}); + this.equipment = new SkyBlockMemberInventoriesEquipment(data?.equipment_contents || {}); + this.enderChest = new SkyBlockMemberInventoriesInventory(data?.ender_chest_contents || {}); + } +} + +export default SkyBlockMemberRiftInventory; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.test.ts new file mode 100644 index 000000000..6ea24c0af --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.test.ts @@ -0,0 +1,12 @@ +import SkyBlockMemberRiftWitherCage from './SkyBlockMemberRiftWitherCage.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { WitherCageKilledEye } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberRiftWitherCage', () => { + const data = new SkyBlockMemberRiftWitherCage({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWitherCage); + expectTypeOf(data).toEqualTypeOf(); + expect(data.killedEyes).toBeDefined(); + expectTypeOf(data.killedEyes).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.ts new file mode 100644 index 000000000..d2753246b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.ts @@ -0,0 +1,10 @@ +import type { WitherCageKilledEye } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberRiftWitherCage { + killedEyes: WitherCageKilledEye[]; + constructor(data: Record) { + this.killedEyes = data?.killed_eyes || []; + } +} + +export default SkyBlockMemberRiftWitherCage; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.test.ts new file mode 100644 index 000000000..558208042 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.test.ts @@ -0,0 +1,15 @@ +import SkyBlockMemberRiftWizardTower from './SkyBlockMemberRiftWizardTower.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWizardTower', () => { + const data = new SkyBlockMemberRiftWizardTower({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWizardTower); + expectTypeOf(data).toEqualTypeOf(); + expect(data.wizardQuestStep).toBeDefined(); + expect(data.wizardQuestStep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.wizardQuestStep).toEqualTypeOf(); + expect(data.crumbsLaidOut).toBeDefined(); + expect(data.crumbsLaidOut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crumbsLaidOut).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.ts new file mode 100644 index 000000000..b747dcdf6 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.ts @@ -0,0 +1,10 @@ +class SkyBlockMemberRiftWizardTower { + wizardQuestStep: number; + crumbsLaidOut: number; + constructor(data: Record) { + this.wizardQuestStep = data?.wizard_quest_step || 0; + this.crumbsLaidOut = data?.crumbs_laid_out || 0; + } +} + +export default SkyBlockMemberRiftWizardTower; diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.test.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.test.ts new file mode 100644 index 000000000..aad1b28c9 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.test.ts @@ -0,0 +1,22 @@ +import SkyBlockMemberRiftWyldWoods from './SkyBlockMemberRiftWyldWoods.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWyldWoods', () => { + const data = new SkyBlockMemberRiftWyldWoods({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWyldWoods); + expectTypeOf(data).toEqualTypeOf(); + expect(data.talkedThreebrothers).toBeDefined(); + expectTypeOf(data.talkedThreebrothers).toEqualTypeOf(); + expect(data.siriusStartedQA).toBeDefined(); + expectTypeOf(data.siriusStartedQA).toEqualTypeOf(); + expect(data.siriusQAChainDone).toBeDefined(); + expectTypeOf(data.siriusQAChainDone).toEqualTypeOf(); + expect(data.siriusCompletedQA).toBeDefined(); + expectTypeOf(data.siriusCompletedQA).toEqualTypeOf(); + expect(data.siriusClaimedDoubloon).toBeDefined(); + expectTypeOf(data.siriusClaimedDoubloon).toEqualTypeOf(); + expect(data.bughunterStep).toBeDefined(); + expect(data.bughunterStep).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bughunterStep).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.ts b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.ts new file mode 100644 index 000000000..c1a991c48 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.ts @@ -0,0 +1,18 @@ +class SkyBlockMemberRiftWyldWoods { + talkedThreebrothers: string[]; + siriusStartedQA: boolean; + siriusQAChainDone: boolean; + siriusCompletedQA: boolean; + siriusClaimedDoubloon: boolean; + bughunterStep: number; + constructor(data: Record) { + this.talkedThreebrothers = data?.talked_threebrothers || []; + this.siriusStartedQA = data?.sirius_started_q_a || false; + this.siriusQAChainDone = data?.sirius_q_a_chain_done || false; + this.siriusCompletedQA = data?.sirius_completed_q_a || false; + this.siriusClaimedDoubloon = data?.sirius_claimed_doubloon || false; + this.bughunterStep = data?.bughunter_step || 0; + } +} + +export default SkyBlockMemberRiftWyldWoods; diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.test.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.test.ts new file mode 100644 index 000000000..5e29dc6c6 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.test.ts @@ -0,0 +1,29 @@ +import SkyBlockMemberRiftVillagePlaza from './SkyBlockMemberRiftVillagePlaza.js'; +import SkyBlockMemberRiftVillagePlazaBarry from './SkyBlockMemberRiftVillagePlazaBarry.js'; +import SkyBlockMemberRiftVillagePlazaCowboy from './SkyBlockMemberRiftVillagePlazaCowboy.js'; +import SkyBlockMemberRiftVillagePlazaMurder from './SkyBlockMemberRiftVillagePlazaMurder.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftVillagePlaza', () => { + const data = new SkyBlockMemberRiftVillagePlaza({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftVillagePlaza); + expectTypeOf(data).toEqualTypeOf(); + expect(data.murder).toBeDefined(); + expect(data.murder).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaMurder); + expectTypeOf(data.murder).toEqualTypeOf(); + expect(data.barry).toBeDefined(); + expect(data.barry).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaBarry); + expectTypeOf(data.barry).toEqualTypeOf(); + expect(data.cowboy).toBeDefined(); + expect(data.cowboy).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaCowboy); + expectTypeOf(data.cowboy).toEqualTypeOf(); + expect(data.barterBank).toBeDefined(); + expectTypeOf(data.barterBank).toEqualTypeOf>(); + expect(data.lonely).toBeDefined(); + expectTypeOf(data.lonely).toEqualTypeOf>(); + expect(data.seraphine).toBeDefined(); + expectTypeOf(data.seraphine).toEqualTypeOf>(); + expect(data.gotScammed).toBeDefined(); + expectTypeOf(data.gotScammed).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.ts new file mode 100644 index 000000000..d9d35abdf --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.ts @@ -0,0 +1,24 @@ +import SkyBlockMemberRiftVillagePlazaBarry from './SkyBlockMemberRiftVillagePlazaBarry.js'; +import SkyBlockMemberRiftVillagePlazaCowboy from './SkyBlockMemberRiftVillagePlazaCowboy.js'; +import SkyBlockMemberRiftVillagePlazaMurder from './SkyBlockMemberRiftVillagePlazaMurder.js'; + +class SkyBlockMemberRiftVillagePlaza { + murder: SkyBlockMemberRiftVillagePlazaMurder; + barry: SkyBlockMemberRiftVillagePlazaBarry; + cowboy: SkyBlockMemberRiftVillagePlazaCowboy; + barterBank: Record; + lonely: Record; + seraphine: Record; + gotScammed: boolean; + constructor(data: Record) { + this.murder = new SkyBlockMemberRiftVillagePlazaMurder(data?.murder || {}); + this.barry = new SkyBlockMemberRiftVillagePlazaBarry(data?.barry_center || {}); + this.cowboy = new SkyBlockMemberRiftVillagePlazaCowboy(data?.cowboy || {}); + this.barterBank = data?.barter_bank || {}; + this.lonely = data?.lonely || {}; + this.seraphine = data?.seraphine || {}; + this.gotScammed = data?.got_scammed || false; + } +} + +export default SkyBlockMemberRiftVillagePlaza; diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.test.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.test.ts new file mode 100644 index 000000000..c36c168e7 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.test.ts @@ -0,0 +1,15 @@ +import SkyBlockMemberRiftVillagePlazaBarry from './SkyBlockMemberRiftVillagePlazaBarry.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftVillagePlazaBarry', () => { + const data = new SkyBlockMemberRiftVillagePlazaBarry({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaBarry); + expectTypeOf(data).toEqualTypeOf(); + expect(data.firstTalkToBarry).toBeDefined(); + expectTypeOf(data.firstTalkToBarry).toEqualTypeOf(); + expect(data.convinced).toBeDefined(); + expectTypeOf(data.convinced).toEqualTypeOf(); + expect(data.receivedReward).toBeDefined(); + expectTypeOf(data.receivedReward).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.ts new file mode 100644 index 000000000..c71fd0e04 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberRiftVillagePlazaBarry { + firstTalkToBarry: boolean; + convinced: boolean; + receivedReward: boolean; + constructor(data: Record) { + this.firstTalkToBarry = data?.first_talk_to_barry || false; + this.convinced = data?.convinced || []; + this.receivedReward = data?.received_reward || false; + } +} + +export default SkyBlockMemberRiftVillagePlazaBarry; diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.test.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.test.ts new file mode 100644 index 000000000..f8679e75f --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberRiftVillagePlazaCowboy from './SkyBlockMemberRiftVillagePlazaCowboy.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { RiftVillagePlazaCowboyRabbit } from '../../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberRiftVillagePlazaCowboy', () => { + const data = new SkyBlockMemberRiftVillagePlazaCowboy({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaCowboy); + expectTypeOf(data).toEqualTypeOf(); + expect(data.stage).toBeDefined(); + expect(data.stage).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stage).toEqualTypeOf(); + expect(data.hayEaten).toBeDefined(); + expect(data.hayEaten).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hayEaten).toEqualTypeOf(); + expect(data.rabbitName).toBeDefined(); + expectTypeOf(data.rabbitName).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.ts new file mode 100644 index 000000000..ad3c83308 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.ts @@ -0,0 +1,14 @@ +import type { RiftVillagePlazaCowboyRabbit } from '../../../../../Types/SkyBlock.js'; + +class SkyBlockMemberRiftVillagePlazaCowboy { + stage: number; + hayEaten: number; + rabbitName: RiftVillagePlazaCowboyRabbit | 'UNKNOWN'; + constructor(data: Record) { + this.stage = data?.stage || 0; + this.hayEaten = data?.hay_eaten || 0; + this.rabbitName = data?.rabbit_name || 'UNKNOWN'; + } +} + +export default SkyBlockMemberRiftVillagePlazaCowboy; diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.test.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.test.ts new file mode 100644 index 000000000..b86c20922 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.test.ts @@ -0,0 +1,20 @@ +import SkyBlockMemberRiftVillagePlazaMurder from './SkyBlockMemberRiftVillagePlazaMurder.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftVillagePlazaMurder', () => { + const data = new SkyBlockMemberRiftVillagePlazaMurder({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftVillagePlazaMurder); + expectTypeOf(data).toEqualTypeOf(); + expect(data.stepIndex).toBeDefined(); + expect(data.stepIndex).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stepIndex).toEqualTypeOf(); + expect(data.roomClues).toBeDefined(); + expectTypeOf(data.roomClues).toEqualTypeOf(); + expect(data.stepIndexPt2).toBeDefined(); + expect(data.stepIndexPt2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stepIndexPt2).toEqualTypeOf(); + expect(data.stepIndexPt3).toBeDefined(); + expect(data.stepIndexPt3).toBeGreaterThanOrEqual(0); + expectTypeOf(data.stepIndexPt3).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.ts b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.ts new file mode 100644 index 000000000..9a1857a97 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.ts @@ -0,0 +1,14 @@ +class SkyBlockMemberRiftVillagePlazaMurder { + stepIndex: number; + roomClues: number[]; + stepIndexPt2: number; + stepIndexPt3: number; + constructor(data: Record) { + this.stepIndex = data?.step_index || 0; + this.roomClues = data?.room_clues || []; + this.stepIndexPt2 = data?.step_index_pt2 || 0; + this.stepIndexPt3 = data?.step_index_pt3 || 0; + } +} + +export default SkyBlockMemberRiftVillagePlazaMurder; diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.test.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.test.ts new file mode 100644 index 000000000..f4529a7fb --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.test.ts @@ -0,0 +1,25 @@ +import SkyBlockMemberRiftWestVillage from './SkyBlockMemberRiftWestVillage.js'; +import SkyBlockMemberRiftWestVillageCrazyKloon from './SkyBlockMemberRiftWestVillageCrazyKloon.js'; +import SkyBlockMemberRiftWestVillageGlyphs from './SkyBlockMemberRiftWestVillageGlyphs.js'; +import SkyBlockMemberRiftWestVillageKatHouse from './SkyBlockMemberRiftWestVillageKatHouse.js'; +import SkyBlockMemberRiftWestVillageMirrorverse from './SkyBlockMemberRiftWestVillageMirrorverse.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWestVillage', () => { + const data = new SkyBlockMemberRiftWestVillage({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWestVillage); + expectTypeOf(data).toEqualTypeOf(); + expect(data.crazyKloon).toBeDefined(); + expect(data.crazyKloon).toBeInstanceOf(SkyBlockMemberRiftWestVillageCrazyKloon); + expectTypeOf(data.crazyKloon).toEqualTypeOf(); + expect(data.mirrorverse).toBeDefined(); + expect(data.mirrorverse).toBeInstanceOf(SkyBlockMemberRiftWestVillageMirrorverse); + expectTypeOf(data.mirrorverse).toEqualTypeOf(); + expect(data.katHouse).toBeDefined(); + expect(data.katHouse).toBeInstanceOf(SkyBlockMemberRiftWestVillageKatHouse); + expectTypeOf(data.katHouse).toEqualTypeOf(); + expect(data.glyphs).toBeDefined(); + expect(data.glyphs).toBeInstanceOf(SkyBlockMemberRiftWestVillageGlyphs); + expectTypeOf(data.glyphs).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.ts new file mode 100644 index 000000000..da6f29a33 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.ts @@ -0,0 +1,19 @@ +import SkyBlockMemberRiftWestVillageCrazyKloon from './SkyBlockMemberRiftWestVillageCrazyKloon.js'; +import SkyBlockMemberRiftWestVillageGlyphs from './SkyBlockMemberRiftWestVillageGlyphs.js'; +import SkyBlockMemberRiftWestVillageKatHouse from './SkyBlockMemberRiftWestVillageKatHouse.js'; +import SkyBlockMemberRiftWestVillageMirrorverse from './SkyBlockMemberRiftWestVillageMirrorverse.js'; + +class SkyBlockMemberRiftWestVillage { + crazyKloon: SkyBlockMemberRiftWestVillageCrazyKloon; + mirrorverse: SkyBlockMemberRiftWestVillageMirrorverse; + katHouse: SkyBlockMemberRiftWestVillageKatHouse; + glyphs: SkyBlockMemberRiftWestVillageGlyphs; + constructor(data: Record) { + this.crazyKloon = new SkyBlockMemberRiftWestVillageCrazyKloon(data?.crazy_kloon || {}); + this.mirrorverse = new SkyBlockMemberRiftWestVillageMirrorverse(data?.mirrorverse || {}); + this.katHouse = new SkyBlockMemberRiftWestVillageKatHouse(data?.kat_house || {}); + this.glyphs = new SkyBlockMemberRiftWestVillageGlyphs(data?.glyphs || {}); + } +} + +export default SkyBlockMemberRiftWestVillage; diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.test.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.test.ts new file mode 100644 index 000000000..ff1ce1669 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.test.ts @@ -0,0 +1,17 @@ +import SkyBlockMemberRiftWestVillageCrazyKloon from './SkyBlockMemberRiftWestVillageCrazyKloon.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWestVillageCrazyKloon', () => { + const data = new SkyBlockMemberRiftWestVillageCrazyKloon({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWestVillageCrazyKloon); + expectTypeOf(data).toEqualTypeOf(); + expect(data.selectedColors).toBeDefined(); + expectTypeOf(data.selectedColors).toEqualTypeOf>(); + expect(data.talked).toBeDefined(); + expectTypeOf(data.talked).toEqualTypeOf(); + expect(data.hackedTerminals).toBeDefined(); + expectTypeOf(data.hackedTerminals).toEqualTypeOf(); + expect(data.questComplete).toBeDefined(); + expectTypeOf(data.questComplete).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.ts new file mode 100644 index 000000000..1dec8f1e2 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.ts @@ -0,0 +1,14 @@ +class SkyBlockMemberRiftWestVillageCrazyKloon { + selectedColors: Record; + talked: boolean; + hackedTerminals: string[]; + questComplete: boolean; + constructor(data: Record) { + this.selectedColors = data?.selected_colors || {}; + this.talked = data?.talked || false; + this.hackedTerminals = data?.hacked_terminals || []; + this.questComplete = data?.quest_complete || false; + } +} + +export default SkyBlockMemberRiftWestVillageCrazyKloon; diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.test.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.test.ts new file mode 100644 index 000000000..eb1f65f68 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.test.ts @@ -0,0 +1,22 @@ +import SkyBlockMemberRiftWestVillageGlyphs from './SkyBlockMemberRiftWestVillageGlyphs.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWestVillageGlyphs', () => { + const data = new SkyBlockMemberRiftWestVillageGlyphs({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWestVillageGlyphs); + expectTypeOf(data).toEqualTypeOf(); + expect(data.claimedWand).toBeDefined(); + expectTypeOf(data.claimedWand).toEqualTypeOf(); + expect(data.currentGlyphDelivered).toBeDefined(); + expectTypeOf(data.currentGlyphDelivered).toEqualTypeOf(); + expect(data.currentGlyphCompleted).toBeDefined(); + expectTypeOf(data.currentGlyphCompleted).toEqualTypeOf(); + expect(data.currentGlyph).toBeDefined(); + expect(data.currentGlyph).toBeGreaterThanOrEqual(0); + expectTypeOf(data.currentGlyph).toEqualTypeOf(); + expect(data.completed).toBeDefined(); + expectTypeOf(data.completed).toEqualTypeOf(); + expect(data.claimedBracelet).toBeDefined(); + expectTypeOf(data.claimedBracelet).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.ts new file mode 100644 index 000000000..8101c11fe --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.ts @@ -0,0 +1,18 @@ +class SkyBlockMemberRiftWestVillageGlyphs { + claimedWand: boolean; + currentGlyphDelivered: boolean; + currentGlyphCompleted: boolean; + currentGlyph: number; + completed: boolean; + claimedBracelet: boolean; + constructor(data: Record) { + this.claimedWand = data?.claimed_wand || false; + this.currentGlyphDelivered = data?.current_glyph_delivered || false; + this.currentGlyphCompleted = data?.current_glyph_completed || false; + this.currentGlyph = data?.current_glyph || 0; + this.completed = data?.completed || false; + this.claimedBracelet = data?.claimed_bracelet || false; + } +} + +export default SkyBlockMemberRiftWestVillageGlyphs; diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.test.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.test.ts new file mode 100644 index 000000000..0be255015 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberRiftWestVillageKatHouse from './SkyBlockMemberRiftWestVillageKatHouse.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberRiftWestVillageKatHouse', () => { + const data = new SkyBlockMemberRiftWestVillageKatHouse({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWestVillageKatHouse); + expectTypeOf(data).toEqualTypeOf(); + expect(data.binCollectedSilverfish).toBeDefined(); + expect(data.binCollectedSilverfish).toBeGreaterThanOrEqual(0); + expectTypeOf(data.binCollectedSilverfish).toEqualTypeOf(); + expect(data.binCollectedSpider).toBeDefined(); + expect(data.binCollectedSpider).toBeGreaterThanOrEqual(0); + expectTypeOf(data.binCollectedSpider).toEqualTypeOf(); + expect(data.binCollectedMosquito).toBeDefined(); + expect(data.binCollectedMosquito).toBeGreaterThanOrEqual(0); + expectTypeOf(data.binCollectedMosquito).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.ts new file mode 100644 index 000000000..8958c9626 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.ts @@ -0,0 +1,12 @@ +class SkyBlockMemberRiftWestVillageKatHouse { + binCollectedSilverfish: number; + binCollectedSpider: number; + binCollectedMosquito: number; + constructor(data: Record) { + this.binCollectedSilverfish = data?.bin_collected_silverfish || 0; + this.binCollectedSpider = data?.bin_collected_spider || 0; + this.binCollectedMosquito = data?.bin_collected_mosquito || 0; + } +} + +export default SkyBlockMemberRiftWestVillageKatHouse; diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.test.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.test.ts new file mode 100644 index 000000000..9bd55163c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.test.ts @@ -0,0 +1,18 @@ +import SkyBlockMemberRiftWestVillageMirrorverse from './SkyBlockMemberRiftWestVillageMirrorverse.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { MirrorverseChestItem, MirrorverseRoom } from '../../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberRiftWestVillageMirrorverse', () => { + const data = new SkyBlockMemberRiftWestVillageMirrorverse({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberRiftWestVillageMirrorverse); + expectTypeOf(data).toEqualTypeOf(); + expect(data.visitedRooms).toBeDefined(); + expectTypeOf(data.visitedRooms).toEqualTypeOf(); + expect(data.upsideDownHard).toBeDefined(); + expectTypeOf(data.upsideDownHard).toEqualTypeOf(); + expect(data.claimedChestItems).toBeDefined(); + expectTypeOf(data.claimedChestItems).toEqualTypeOf(); + expect(data.claimedReward).toBeDefined(); + expectTypeOf(data.claimedReward).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.ts b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.ts new file mode 100644 index 000000000..316adb8cd --- /dev/null +++ b/src/Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.ts @@ -0,0 +1,16 @@ +import type { MirrorverseChestItem, MirrorverseRoom } from '../../../../../Types/SkyBlock.js'; + +class SkyBlockMemberRiftWestVillageMirrorverse { + visitedRooms: MirrorverseRoom[]; + upsideDownHard: boolean; + claimedChestItems: MirrorverseChestItem[]; + claimedReward: boolean; + constructor(data: Record) { + this.visitedRooms = data?.visited_rooms || []; + this.upsideDownHard = data?.upside_down_hard || false; + this.claimedChestItems = data?.claimed_chest_items || []; + this.claimedReward = data?.claimed_reward || false; + } +} + +export default SkyBlockMemberRiftWestVillageMirrorverse; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMember.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMember.test.ts new file mode 100644 index 000000000..34f621bf7 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMember.test.ts @@ -0,0 +1,101 @@ +import SkyBlockMember from './SkyBlockMember.js'; +import SkyBlockMemberAccessoryBag from './AccessoryBag/SkyBlockMemberAccessoryBag.js'; +import SkyBlockMemberBestiary from './Bestiary/SkyBlockMemberBestiary.js'; +import SkyBlockMemberChocolateFactory from './ChocolateFactory/SkyBlockMemberChocolateFactory.js'; +import SkyBlockMemberCrimsonIsle from './CrimsonIsle/SkyBlockMemberCrimsonIsle.js'; +import SkyBlockMemberCurrencies from './SkyBlockMemberCurrencies.js'; +import SkyBlockMemberDungeons from './Dungeons/SkyBlockMemberDungeons.js'; +import SkyBlockMemberFairySouls from './SkyBlockMemberFairySouls.js'; +import SkyBlockMemberInventories from './Inventories/SkyBlockMemberInventories.js'; +import SkyBlockMemberJacobContests from './JacobContests/SkyBlockMemberJacobContests.js'; +import SkyBlockMemberLeveling from './SkyBlockMemberLeveling.js'; +import SkyBlockMemberMining from './Mining/SkyBlockMemberMining.js'; +import SkyBlockMemberObjectives from './SkyBlockMemberObjectives.js'; +import SkyBlockMemberPets from './Pets/SkyBlockMemberPets.js'; +import SkyBlockMemberPlayerData from './PlayerData/SkyBlockMemberPlayerData.js'; +import SkyBlockMemberPlayerStats from './PlayerStats/SkyBlockMemberPlayerStats.js'; +import SkyBlockMemberProfile from './SkyBlockMemberProfile.js'; +import SkyBlockMemberQuests from './Quests/SkyBlockMemberQuests.js'; +import SkyBlockMemberRift from './Rift/SkyBlockMemberRift.js'; +import SkyBlockMemberSlayers from './Slayers/SkyBlockMemberSlayers.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockArrow } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +test('SkyBlockMember', () => { + const data = new SkyBlockMember('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMember); + expectTypeOf(data).toEqualTypeOf(); + expect(data.uuid).toBeDefined(); + expectTypeOf(data.uuid).toEqualTypeOf(); + expect(data.accessoryBag).toBeDefined(); + expect(data.accessoryBag).toBeInstanceOf(SkyBlockMemberAccessoryBag); + expectTypeOf(data.accessoryBag).toEqualTypeOf(); + expect(data.bestiary).toBeDefined(); + expect(data.bestiary).toBeInstanceOf(SkyBlockMemberBestiary); + expectTypeOf(data.bestiary).toEqualTypeOf(); + expect(data.collections).toBeDefined(); + expectTypeOf(data.collections).toEqualTypeOf>(); + expect(data.currencies).toBeDefined(); + expect(data.currencies).toBeInstanceOf(SkyBlockMemberCurrencies); + expectTypeOf(data.currencies).toEqualTypeOf(); + expect(data.dungeons).toBeDefined(); + expect(data.dungeons).toBeInstanceOf(SkyBlockMemberDungeons); + expectTypeOf(data.dungeons).toEqualTypeOf(); + expect(data.chocolateFactory).toBeDefined(); + expect(data.chocolateFactory).toBeInstanceOf(SkyBlockMemberChocolateFactory); + expectTypeOf(data.chocolateFactory).toEqualTypeOf(); + expect(data.fairySouls).toBeDefined(); + expect(data.fairySouls).toBeInstanceOf(SkyBlockMemberFairySouls); + expectTypeOf(data.fairySouls).toEqualTypeOf(); + expect(data.soulflow).toBeDefined(); + expect(data.soulflow).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soulflow).toEqualTypeOf(); + expect(data.favoriteArrow).toBeDefined(); + expectTypeOf(data.favoriteArrow).toEqualTypeOf(); + expect(data.jacobContests).toBeDefined(); + expect(data.jacobContests).toBeInstanceOf(SkyBlockMemberJacobContests); + expectTypeOf(data.jacobContests).toEqualTypeOf(); + expect(data.leveling).toBeDefined(); + expect(data.leveling).toBeInstanceOf(SkyBlockMemberLeveling); + expectTypeOf(data.leveling).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expect(data.mining).toBeInstanceOf(SkyBlockMemberMining); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.crimsonIsle).toBeDefined(); + expect(data.crimsonIsle).toBeInstanceOf(SkyBlockMemberCrimsonIsle); + expectTypeOf(data.crimsonIsle).toEqualTypeOf(); + expect(data.objectives).toBeDefined(); + expect(data.objectives).toBeInstanceOf(SkyBlockMemberObjectives); + expectTypeOf(data.objectives).toEqualTypeOf(); + expect(data.pets).toBeDefined(); + expect(data.pets).toBeInstanceOf(SkyBlockMemberPets); + expectTypeOf(data.pets).toEqualTypeOf(); + expect(data.playerData).toBeDefined(); + expect(data.playerData).toBeInstanceOf(SkyBlockMemberPlayerData); + expectTypeOf(data.playerData).toEqualTypeOf(); + expect(data.playerStats).toBeDefined(); + expect(data.playerStats).toBeInstanceOf(SkyBlockMemberPlayerStats); + expectTypeOf(data.playerStats).toEqualTypeOf(); + expect(data.profileStats).toBeDefined(); + expect(data.profileStats).toBeInstanceOf(SkyBlockMemberProfile); + expectTypeOf(data.profileStats).toEqualTypeOf(); + expect(data.quests).toBeDefined(); + expect(data.quests).toBeInstanceOf(SkyBlockMemberQuests); + expectTypeOf(data.quests).toEqualTypeOf(); + expect(data.slayers).toBeDefined(); + expect(data.slayers).toBeInstanceOf(SkyBlockMemberSlayers); + expectTypeOf(data.slayers).toEqualTypeOf(); + expect(data.rift).toBeDefined(); + expect(data.rift).toBeInstanceOf(SkyBlockMemberRift); + expectTypeOf(data.rift).toEqualTypeOf(); + expect(data.inventory).toBeDefined(); + expect(data.inventory).toBeInstanceOf(SkyBlockMemberInventories); + expectTypeOf(data.inventory).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => UUID>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.uuid); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMember.ts b/src/Structures/SkyBlock/Member/SkyBlockMember.ts new file mode 100644 index 000000000..f30fded54 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMember.ts @@ -0,0 +1,81 @@ +import SkyBlockMemberAccessoryBag from './AccessoryBag/SkyBlockMemberAccessoryBag.js'; +import SkyBlockMemberBestiary from './Bestiary/SkyBlockMemberBestiary.js'; +import SkyBlockMemberChocolateFactory from './ChocolateFactory/SkyBlockMemberChocolateFactory.js'; +import SkyBlockMemberCrimsonIsle from './CrimsonIsle/SkyBlockMemberCrimsonIsle.js'; +import SkyBlockMemberCurrencies from './SkyBlockMemberCurrencies.js'; +import SkyBlockMemberDungeons from './Dungeons/SkyBlockMemberDungeons.js'; +import SkyBlockMemberFairySouls from './SkyBlockMemberFairySouls.js'; +import SkyBlockMemberInventories from './Inventories/SkyBlockMemberInventories.js'; +import SkyBlockMemberJacobContests from './JacobContests/SkyBlockMemberJacobContests.js'; +import SkyBlockMemberLeveling from './SkyBlockMemberLeveling.js'; +import SkyBlockMemberMining from './Mining/SkyBlockMemberMining.js'; +import SkyBlockMemberObjectives from './SkyBlockMemberObjectives.js'; +import SkyBlockMemberPets from './Pets/SkyBlockMemberPets.js'; +import SkyBlockMemberPlayerData from './PlayerData/SkyBlockMemberPlayerData.js'; +import SkyBlockMemberPlayerStats from './PlayerStats/SkyBlockMemberPlayerStats.js'; +import SkyBlockMemberProfile from './SkyBlockMemberProfile.js'; +import SkyBlockMemberQuests from './Quests/SkyBlockMemberQuests.js'; +import SkyBlockMemberRift from './Rift/SkyBlockMemberRift.js'; +import SkyBlockMemberSlayers from './Slayers/SkyBlockMemberSlayers.js'; +import type { SkyBlockArrow } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockMember { + uuid: UUID; + accessoryBag: SkyBlockMemberAccessoryBag; + bestiary: SkyBlockMemberBestiary; + collections: Record; + currencies: SkyBlockMemberCurrencies; + dungeons: SkyBlockMemberDungeons; + chocolateFactory: SkyBlockMemberChocolateFactory; + fairySouls: SkyBlockMemberFairySouls; + soulflow: number; + favoriteArrow: SkyBlockArrow; + jacobContests: SkyBlockMemberJacobContests; + leveling: SkyBlockMemberLeveling; + mining: SkyBlockMemberMining; + crimsonIsle: SkyBlockMemberCrimsonIsle; + objectives: SkyBlockMemberObjectives; + pets: SkyBlockMemberPets; + playerData: SkyBlockMemberPlayerData; + playerStats: SkyBlockMemberPlayerStats; + profileStats: SkyBlockMemberProfile; + quests: SkyBlockMemberQuests; + slayers: SkyBlockMemberSlayers; + rift: SkyBlockMemberRift; + inventory: SkyBlockMemberInventories; + constructor(uuid: string, data: Record) { + this.uuid = uuid; + this.accessoryBag = new SkyBlockMemberAccessoryBag(data?.accessory_bag_storage || {}); + this.bestiary = new SkyBlockMemberBestiary(data?.bestiary || {}); + this.collections = data?.collection || {}; + this.currencies = new SkyBlockMemberCurrencies(data?.currencies || {}); + this.dungeons = new SkyBlockMemberDungeons(data?.dungeons || {}); + this.chocolateFactory = new SkyBlockMemberChocolateFactory(data?.events?.easter || {}); + this.fairySouls = new SkyBlockMemberFairySouls(data?.fairy_soul || {}); + this.soulflow = data?.item_data?.soulflow || 0; + this.favoriteArrow = data?.item_data?.favorite_arrow || 'ARROW'; + this.jacobContests = new SkyBlockMemberJacobContests(data?.jacobs_contest || {}); + this.leveling = new SkyBlockMemberLeveling(data?.leveling || {}); + this.mining = new SkyBlockMemberMining({ ...(data?.mining_core || {}), ...(data?.forge || {}) }); + this.crimsonIsle = new SkyBlockMemberCrimsonIsle(data?.nether_island_player_data || {}, data?.trophy_fish || {}); + this.objectives = new SkyBlockMemberObjectives(data?.objectives || {}); + this.pets = new SkyBlockMemberPets({ ...(data?.pets_data || {}), ...(data?.player_stats?.pets || {}) }); + this.playerData = new SkyBlockMemberPlayerData(data?.player_data || {}, { + farmingCap: this.jacobContests.perks.farmingLevelCap || 0, + tamingCap: this.pets.petCare.petsSacrificed.length || 0 + }); + this.playerStats = new SkyBlockMemberPlayerStats(data?.player_stats || {}); + this.profileStats = new SkyBlockMemberProfile(data?.profile || {}); + this.quests = new SkyBlockMemberQuests(data?.quests || {}); + this.slayers = new SkyBlockMemberSlayers(data?.slayer || {}); + this.rift = new SkyBlockMemberRift(data?.rift || {}); + this.inventory = new SkyBlockMemberInventories(data?.inventory || {}, data?.shared_inventory || {}); + } + + toString(): UUID { + return this.uuid; + } +} + +export default SkyBlockMember; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.test.ts new file mode 100644 index 000000000..fadff8e82 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.test.ts @@ -0,0 +1,39 @@ +import SkyBlockMemberCurrencies from './SkyBlockMemberCurrencies.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberCurrencies', () => { + const data = new SkyBlockMemberCurrencies({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberCurrencies); + expectTypeOf(data).toEqualTypeOf(); + expect(data.purse).toBeDefined(); + expect(data.purse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.purse).toEqualTypeOf(); + expect(data.motesPurse).toBeDefined(); + expect(data.motesPurse).toBeGreaterThanOrEqual(0); + expectTypeOf(data.motesPurse).toEqualTypeOf(); + expect(data.witherEssence).toBeDefined(); + expect(data.witherEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.witherEssence).toEqualTypeOf(); + expect(data.dragonEssence).toBeDefined(); + expect(data.dragonEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dragonEssence).toEqualTypeOf(); + expect(data.spiderEssence).toBeDefined(); + expect(data.spiderEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spiderEssence).toEqualTypeOf(); + expect(data.undeadEssence).toBeDefined(); + expect(data.undeadEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.undeadEssence).toEqualTypeOf(); + expect(data.diamondEssence).toBeDefined(); + expect(data.diamondEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.diamondEssence).toEqualTypeOf(); + expect(data.goldEssence).toBeDefined(); + expect(data.goldEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.goldEssence).toEqualTypeOf(); + expect(data.iceEssence).toBeDefined(); + expect(data.iceEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.iceEssence).toEqualTypeOf(); + expect(data.crimsonEssence).toBeDefined(); + expect(data.crimsonEssence).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crimsonEssence).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.ts new file mode 100644 index 000000000..52ef173d0 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberCurrencies.ts @@ -0,0 +1,26 @@ +class SkyBlockMemberCurrencies { + purse: number; + motesPurse: number; + witherEssence: number; + dragonEssence: number; + spiderEssence: number; + undeadEssence: number; + diamondEssence: number; + goldEssence: number; + iceEssence: number; + crimsonEssence: number; + constructor(data: Record) { + this.purse = data?.coin_purse || 0; + this.motesPurse = data?.motes_purse || 0; + this.witherEssence = data.essence?.WITHER?.current || 0; + this.dragonEssence = data.essence?.DRAGON?.current || 0; + this.spiderEssence = data.essence?.SPIDER?.current || 0; + this.undeadEssence = data.essence?.UNDEAD?.current || 0; + this.diamondEssence = data.essence?.DIAMOND?.current || 0; + this.goldEssence = data.essence?.GOLD?.current || 0; + this.iceEssence = data.essence?.ICE?.current || 0; + this.crimsonEssence = data.essence?.CRIMSON?.current || 0; + } +} + +export default SkyBlockMemberCurrencies; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.test.ts new file mode 100644 index 000000000..6122e7098 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberFairySouls from './SkyBlockMemberFairySouls.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberFairySouls', () => { + const data = new SkyBlockMemberFairySouls({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberFairySouls); + expectTypeOf(data).toEqualTypeOf(); + expect(data.exchanges).toBeDefined(); + expect(data.exchanges).toBeGreaterThanOrEqual(0); + expectTypeOf(data.exchanges).toEqualTypeOf(); + expect(data.collected).toBeDefined(); + expect(data.collected).toBeGreaterThanOrEqual(0); + expectTypeOf(data.collected).toEqualTypeOf(); + expect(data.unspent).toBeDefined(); + expect(data.unspent).toBeGreaterThanOrEqual(0); + expectTypeOf(data.unspent).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.collected); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.ts new file mode 100644 index 000000000..be785a019 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberFairySouls.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberFairySouls { + exchanges: number; + collected: number; + unspent: number; + constructor(data: Record) { + this.exchanges = data?.fairy_exchanges || 0; + this.collected = data?.total_collected || 0; + this.unspent = data?.unspent_souls || 0; + } + + toString(): number { + return this.collected; + } +} + +export default SkyBlockMemberFairySouls; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.test.ts new file mode 100644 index 000000000..cf62ccf0e --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.test.ts @@ -0,0 +1,44 @@ +import SkyBlockMemberLeveling from './SkyBlockMemberLeveling.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { TaskLevelingSort } from '../../../Types/SkyBlock.js'; + +test('SkyBlockMemberLeveling', () => { + const data = new SkyBlockMemberLeveling({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberLeveling); + expectTypeOf(data).toEqualTypeOf(); + expect(data.experience).toBeDefined(); + expect(data.experience).toBeGreaterThanOrEqual(0); + expectTypeOf(data.experience).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.completions).toBeDefined(); + expectTypeOf(data.completions).toEqualTypeOf>(); + expect(data.completed).toBeDefined(); + expectTypeOf(data.completed).toEqualTypeOf(); + expect(data.completedTasks).toBeDefined(); + expectTypeOf(data.completedTasks).toEqualTypeOf(); + expect(data.lastViewedTasks).toBeDefined(); + expectTypeOf(data.lastViewedTasks).toEqualTypeOf(); + expect(data.highestPetScore).toBeDefined(); + expect(data.highestPetScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.highestPetScore).toEqualTypeOf(); + expect(data.miningFiestaOresMined).toBeDefined(); + expect(data.miningFiestaOresMined).toBeGreaterThanOrEqual(0); + expectTypeOf(data.miningFiestaOresMined).toEqualTypeOf(); + expect(data.fishingFestivalSharksKilled).toBeDefined(); + expect(data.fishingFestivalSharksKilled).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fishingFestivalSharksKilled).toEqualTypeOf(); + expect(data.taskSort).toBeDefined(); + expectTypeOf(data.taskSort).toEqualTypeOf(); + expect(data.claimedTalisman).toBeDefined(); + expectTypeOf(data.claimedTalisman).toEqualTypeOf(); + expect(data.emblemUnlocks).toBeDefined(); + expectTypeOf(data.emblemUnlocks).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.ts new file mode 100644 index 000000000..ca12d87ee --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberLeveling.ts @@ -0,0 +1,36 @@ +import type { TaskLevelingSort } from '../../../Types/SkyBlock.js'; + +class SkyBlockMemberLeveling { + experience: number; + level: number; + completions: Record; + completed: string[]; + completedTasks: string[]; + lastViewedTasks: string[]; + highestPetScore: number; + miningFiestaOresMined: number; + fishingFestivalSharksKilled: number; + taskSort: TaskLevelingSort | 'UNKNOWN'; + claimedTalisman: boolean; + emblemUnlocks: string[]; + constructor(data: Record) { + this.experience = data?.experience || 0; + this.level = this.experience / 100; + this.completions = data?.completions || {}; + this.completed = data?.completed || []; + this.completedTasks = data?.completed_tasks || []; + this.lastViewedTasks = data?.last_viewed_tasks || []; + this.highestPetScore = data?.highest_pet_score || 0; + this.miningFiestaOresMined = data?.mining_fiesta_ores_mined || 0; + this.fishingFestivalSharksKilled = data?.fishing_festival_sharks_killed || 0; + this.taskSort = data?.task_sort || 'UNKNOWN'; + this.claimedTalisman = data?.claimed_talisman || false; + this.emblemUnlocks = data?.emblem_unlocks || []; + } + + toString(): number { + return this.level; + } +} + +export default SkyBlockMemberLeveling; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.test.ts new file mode 100644 index 000000000..7a762fd8f --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.test.ts @@ -0,0 +1,14 @@ +import SkyBlockMemberObjectives from './SkyBlockMemberObjectives.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { RawSkyBlockObjective } from '../../../Types/SkyBlock.js'; + +test('SkyBlockMemberObjectives', () => { + const data = new SkyBlockMemberObjectives({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberObjectives); + expectTypeOf(data).toEqualTypeOf(); + expect(data.objectives).toBeDefined(); + expectTypeOf(data.objectives).toEqualTypeOf>(); + expect(data.tutorial).toBeDefined(); + expectTypeOf(data.tutorial).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.ts new file mode 100644 index 000000000..00ef89c43 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberObjectives.ts @@ -0,0 +1,17 @@ +import type { RawSkyBlockObjective } from '../../../Types/SkyBlock.js'; + +class SkyBlockMemberObjectives { + objectives: Record; + tutorial: string[]; + constructor(data: Record) { + this.objectives = Object.keys(data) + .filter((key) => key !== 'tutorial') + .reduce((obj: Record, key: string) => { + obj[key] = data[key]; + return obj; + }, {}); + this.tutorial = data?.tutorial || []; + } +} + +export default SkyBlockMemberObjectives; diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.test.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.test.ts new file mode 100644 index 000000000..3bdef9e50 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.test.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberProfile from './SkyBlockMemberProfile.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberProfile', () => { + const data = new SkyBlockMemberProfile({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberProfile); + expectTypeOf(data).toEqualTypeOf(); + expect(data.firstJoin).toBeDefined(); + expect(data.firstJoin).toBeGreaterThanOrEqual(0); + expectTypeOf(data.firstJoin).toEqualTypeOf(); + expect(data.firstJoinDate).toBeDefined(); + expect(data.firstJoinDate).toBeInstanceOf(Date); + expectTypeOf(data.firstJoinDate).toEqualTypeOf(); + expect(data.personalBankUpgrade).toBeDefined(); + expect(data.personalBankUpgrade).toBeGreaterThanOrEqual(0); + expectTypeOf(data.personalBankUpgrade).toEqualTypeOf(); + expect(data.bankAccount).toBeDefined(); + expect(data.bankAccount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bankAccount).toEqualTypeOf(); + expect(data.hasCookie).toBeDefined(); + expectTypeOf(data.hasCookie).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.ts b/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.ts new file mode 100644 index 000000000..c636ae749 --- /dev/null +++ b/src/Structures/SkyBlock/Member/SkyBlockMemberProfile.ts @@ -0,0 +1,16 @@ +class SkyBlockMemberProfile { + firstJoin: number; + firstJoinDate: Date; + personalBankUpgrade: number; + bankAccount: number; + hasCookie: boolean; + constructor(data: Record) { + this.firstJoin = data?.first_join || 0; + this.firstJoinDate = new Date(this.firstJoin); + this.personalBankUpgrade = data?.personal_bank_upgrade || 0; + this.bankAccount = data?.bank_account || 0; + this.hasCookie = data?.cookie_buff_active || false; + } +} + +export default SkyBlockMemberProfile; diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.test.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.test.ts new file mode 100644 index 000000000..0878b601c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.test.ts @@ -0,0 +1,36 @@ +import SkyBlockMemberSlayer from './SkyBlockMemberSlayer.js'; +import SkyBlockMemberSlayerClaimedLevels from './SkyBlockMemberSlayerClaimedLevels.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { LevelData } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberSlayer', () => { + const data = new SkyBlockMemberSlayer({ stats: 'meow' }, 'blaze'); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data).toEqualTypeOf(); + expect(data.claimedLevels).toBeDefined(); + expect(data.claimedLevels).toBeInstanceOf(SkyBlockMemberSlayerClaimedLevels); + expectTypeOf(data.claimedLevels).toEqualTypeOf(); + expect(data.tier1Kills).toBeDefined(); + expect(data.tier1Kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier1Kills).toEqualTypeOf(); + expect(data.tier2Kills).toBeDefined(); + expect(data.tier2Kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier2Kills).toEqualTypeOf(); + expect(data.tier3Kills).toBeDefined(); + expect(data.tier3Kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier3Kills).toEqualTypeOf(); + expect(data.tier4Kills).toBeDefined(); + expect(data.tier4Kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier4Kills).toEqualTypeOf(); + expect(data.tier5Kills).toBeDefined(); + expect(data.tier5Kills).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier5Kills).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.ts new file mode 100644 index 000000000..f70aded69 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.ts @@ -0,0 +1,28 @@ +import SkyBlockMemberSlayerClaimedLevels from './SkyBlockMemberSlayerClaimedLevels.js'; +import { getSlayerLevel } from '../../../../Utils/SkyBlockUtils.js'; +import type { LevelData, SkyBlockSlayer } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberSlayer { + claimedLevels: SkyBlockMemberSlayerClaimedLevels; + tier1Kills: number; + tier2Kills: number; + tier3Kills: number; + tier4Kills: number; + tier5Kills: number; + level: LevelData; + constructor(data: Record, slayer: SkyBlockSlayer) { + this.claimedLevels = new SkyBlockMemberSlayerClaimedLevels(data?.claimed_levels || {}); + this.tier1Kills = data?.boss_kills_tier_0 || 0; + this.tier2Kills = data?.boss_kills_tier_1 || 0; + this.tier3Kills = data?.boss_kills_tier_2 || 0; + this.tier4Kills = data?.boss_kills_tier_3 || 0; + this.tier5Kills = data?.boss_kills_tier_4 || 0; + this.level = getSlayerLevel(slayer, data?.xp); + } + + toString(): number { + return this.level.level; + } +} + +export default SkyBlockMemberSlayer; diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.test.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.test.ts new file mode 100644 index 000000000..649861c3c --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.test.ts @@ -0,0 +1,27 @@ +import SkyBlockMemberSlayerClaimedLevels from './SkyBlockMemberSlayerClaimedLevels.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberSlayerClaimedLevels', () => { + const data = new SkyBlockMemberSlayerClaimedLevels({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberSlayerClaimedLevels); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level1).toBeDefined(); + expectTypeOf(data.level1).toEqualTypeOf(); + expect(data.level2).toBeDefined(); + expectTypeOf(data.level2).toEqualTypeOf(); + expect(data.level3).toBeDefined(); + expectTypeOf(data.level3).toEqualTypeOf(); + expect(data.level4).toBeDefined(); + expectTypeOf(data.level4).toEqualTypeOf(); + expect(data.level5).toBeDefined(); + expectTypeOf(data.level5).toEqualTypeOf(); + expect(data.level6).toBeDefined(); + expectTypeOf(data.level6).toEqualTypeOf(); + expect(data.level7).toBeDefined(); + expectTypeOf(data.level7).toEqualTypeOf(); + expect(data.level8).toBeDefined(); + expectTypeOf(data.level8).toEqualTypeOf(); + expect(data.level9).toBeDefined(); + expectTypeOf(data.level9).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.ts new file mode 100644 index 000000000..fe48c284a --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.ts @@ -0,0 +1,24 @@ +class SkyBlockMemberSlayerClaimedLevels { + level1: boolean; + level2: boolean; + level3: boolean; + level4: boolean; + level5: boolean; + level6: boolean; + level7: boolean; + level8: boolean; + level9: boolean; + constructor(data: Record) { + this.level1 = data?.level_1 ?? data?.level_1_special ?? false; + this.level2 = data?.level_2 ?? data?.level_2_special ?? false; + this.level3 = data?.level_3 ?? data?.level_3_special ?? false; + this.level4 = data?.level_4 ?? data?.level_4_special ?? false; + this.level5 = data?.level_5 ?? data?.level_5_special ?? false; + this.level6 = data?.level_6 ?? data?.level_6_special ?? false; + this.level7 = data?.level_7 ?? data?.level_7_special ?? false; + this.level8 = data?.level_8 ?? data?.level_8_special ?? false; + this.level9 = data?.level_9 ?? data?.level_9_special ?? false; + } +} + +export default SkyBlockMemberSlayerClaimedLevels; diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.test.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.test.ts new file mode 100644 index 000000000..336825f55 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.test.ts @@ -0,0 +1,31 @@ +import SkyBlockMemberSlayer from './SkyBlockMemberSlayer.js'; +import SkyBlockMemberSlayers from './SkyBlockMemberSlayers.js'; +import SkyBlockMemberSlayersQuest from './SkyBlockMemberSlayersQuest.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMemberSlayers', () => { + const data = new SkyBlockMemberSlayers({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberSlayers); + expectTypeOf(data).toEqualTypeOf(); + expect(data.activeSlayer).toBeDefined(); + expectTypeOf(data.activeSlayer).toEqualTypeOf(); + expect(data.zombie).toBeDefined(); + expect(data.zombie).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.zombie).toEqualTypeOf(); + expect(data.spider).toBeDefined(); + expect(data.spider).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.spider).toEqualTypeOf(); + expect(data.wolf).toBeDefined(); + expect(data.wolf).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.wolf).toEqualTypeOf(); + expect(data.enderman).toBeDefined(); + expect(data.enderman).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.enderman).toEqualTypeOf(); + expect(data.blaze).toBeDefined(); + expect(data.blaze).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.blaze).toEqualTypeOf(); + expect(data.vampire).toBeDefined(); + expect(data.vampire).toBeInstanceOf(SkyBlockMemberSlayer); + expectTypeOf(data.vampire).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.ts new file mode 100644 index 000000000..bf8005f5e --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.ts @@ -0,0 +1,23 @@ +import SkyBlockMemberSlayer from './SkyBlockMemberSlayer.js'; +import SkyBlockMemberSlayersQuest from './SkyBlockMemberSlayersQuest.js'; + +class SkyBlockMemberSlayers { + activeSlayer: SkyBlockMemberSlayersQuest | null; + zombie: SkyBlockMemberSlayer; + spider: SkyBlockMemberSlayer; + wolf: SkyBlockMemberSlayer; + enderman: SkyBlockMemberSlayer; + blaze: SkyBlockMemberSlayer; + vampire: SkyBlockMemberSlayer; + constructor(data: Record) { + this.activeSlayer = data?.slayer_quest ? new SkyBlockMemberSlayersQuest(data?.slayer_quest || {}) : null; + this.zombie = new SkyBlockMemberSlayer(data?.slayer_bosses?.zombie || {}, 'zombie'); + this.spider = new SkyBlockMemberSlayer(data?.slayer_bosses?.spider || {}, 'spider'); + this.wolf = new SkyBlockMemberSlayer(data?.slayer_bosses?.wolf || {}, 'wolf'); + this.enderman = new SkyBlockMemberSlayer(data?.slayer_bosses?.enderman || {}, 'enderman'); + this.blaze = new SkyBlockMemberSlayer(data?.slayer_bosses?.blaze || {}, 'blaze'); + this.vampire = new SkyBlockMemberSlayer(data?.slayer_bosses?.vampire || {}, 'vampire'); + } +} + +export default SkyBlockMemberSlayers; diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.test.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.test.ts new file mode 100644 index 000000000..ee5c6caf2 --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.test.ts @@ -0,0 +1,44 @@ +import SkyBlockMemberSlayersQuest from './SkyBlockMemberSlayersQuest.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockArea, SkyBlockSlayer } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockMemberSlayerQuest', () => { + const data = new SkyBlockMemberSlayersQuest({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMemberSlayersQuest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.startTimestamp).toBeDefined(); + expect(data.startTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startTimestamp).toEqualTypeOf(); + expect(data.startAt).toBeDefined(); + expect(data.startAt).toBeInstanceOf(Date); + expectTypeOf(data.startAt).toEqualTypeOf(); + expect(data.completionState).toBeDefined(); + expect(data.completionState).toBeGreaterThanOrEqual(0); + expectTypeOf(data.completionState).toEqualTypeOf(); + expect(data.usedArmor).toBeDefined(); + expectTypeOf(data.usedArmor).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.combatXp).toBeDefined(); + expect(data.combatXp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.combatXp).toEqualTypeOf(); + expect(data.recentMobKills).toBeDefined(); + expectTypeOf(data.recentMobKills).toEqualTypeOf<{ xp: number; timestamp: number; timestampAt: Date }[]>(); + expect(data.lastKilledMobIsland).toBeDefined(); + expectTypeOf(data.lastKilledMobIsland).toEqualTypeOf(); + expect(data.xpOnLastFollowerSpawn).toBeDefined(); + expect(data.xpOnLastFollowerSpawn).toBeGreaterThanOrEqual(0); + expectTypeOf(data.xpOnLastFollowerSpawn).toEqualTypeOf(); + expect(data.spawnTimestamp).toBeDefined(); + expect(data.spawnTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spawnTimestamp).toEqualTypeOf(); + expect(data.spawnAt).toBeDefined(); + expect(data.spawnAt).toBeInstanceOf(Date); + expectTypeOf(data.spawnAt).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.ts b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.ts new file mode 100644 index 000000000..77a90bc5b --- /dev/null +++ b/src/Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.ts @@ -0,0 +1,36 @@ +import type { SkyBlockArea, SkyBlockSlayer } from '../../../../Types/SkyBlock.js'; + +class SkyBlockMemberSlayersQuest { + type: SkyBlockSlayer | 'UNKNOWN'; + tier: number; + startTimestamp: number; + startAt: Date; + completionState: number; + usedArmor: boolean; + solo: boolean; + combatXp: number; + recentMobKills: { xp: number; timestamp: number; timestampAt: Date }[]; + lastKilledMobIsland: SkyBlockArea | 'UNKNOWN'; + xpOnLastFollowerSpawn: number; + spawnTimestamp: number; + spawnAt: Date; + constructor(data: Record) { + this.type = data?.type || 'UNKNOWN'; + this.tier = data?.tier || 0; + this.startTimestamp = data?.start_timestamp || 0; + this.startAt = new Date(this.startTimestamp); + this.completionState = data?.completion_state || 0; + this.usedArmor = data?.used_armor || 0; + this.solo = data?.solo || 0; + this.combatXp = data?.combat_xp || 0; + this.recentMobKills = (data?.recent_mob_kills || []).map((mob: { xp: number; timestamp: number }) => { + return { ...mob, timestampAt: new Date(mob.timestamp) }; + }); + this.lastKilledMobIsland = data?.last_killed_mob_island || 'UNKNOWN'; + this.xpOnLastFollowerSpawn = data?.xp_on_last_follower_spawn || 0; + this.spawnTimestamp = data?.spawn_timestamp || 0; + this.spawnAt = new Date(this.spawnTimestamp); + } +} + +export default SkyBlockMemberSlayersQuest; diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseum.test.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseum.test.ts new file mode 100644 index 000000000..3c7c852c5 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseum.test.ts @@ -0,0 +1,13 @@ +import SkyBlockMuseum from './SkyBlockMuseum.js'; +import SkyBlockMuseumMember from './SkyBlockMuseumMember.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { UUID } from '../../../Types/Global.js'; + +test('SkyBlockMuseum', () => { + const data = new SkyBlockMuseum({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMuseum); + expectTypeOf(data).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf>(); +}); diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseum.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseum.ts new file mode 100644 index 000000000..72a48fb64 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseum.ts @@ -0,0 +1,20 @@ +import SkyBlockMuseumMember from './SkyBlockMuseumMember.js'; +import type RequestData from '../../../Private/RequestData.js'; +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockMuseum { + members: Record; + constructor(data: Record) { + const members = data?.members || {}; + this.members = Object.keys(members).reduce((obj: Record, key: UUID) => { + obj[key] = new SkyBlockMuseumMember(members?.[key] || {}); + return obj; + }, {}); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockMuseum; diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.test.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.test.ts new file mode 100644 index 000000000..c1bc9fe45 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.test.ts @@ -0,0 +1,29 @@ +import SkyBlockInventoryItem from '../Inventory/SkyBlockInventoryItem.js'; +import SkyBlockMuseumItem from './SkyBlockMuseumItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMuseumItem', () => { + const data = new SkyBlockMuseumItem('mrrp', { stats: 'meow' }, []); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMuseumItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.donated).toBeDefined(); + expect(data.donated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.donated).toEqualTypeOf(); + expect(data.donatedAt).toBeDefined(); + expect(data.donatedAt).toBeInstanceOf(Date); + expectTypeOf(data.donatedAt).toEqualTypeOf(); + expect(data.featuredSlot).toBeDefined(); + expectTypeOf(data.featuredSlot).toEqualTypeOf(); + expect(data.borrowing).toBeDefined(); + expectTypeOf(data.borrowing).toEqualTypeOf(); + expect(data.items).toBeDefined(); + expectTypeOf(data.items).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.ts new file mode 100644 index 000000000..e788f8625 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseumItem.ts @@ -0,0 +1,28 @@ +import SkyBlockInventoryItem from '../Inventory/SkyBlockInventoryItem.js'; + +class SkyBlockMuseumItem { + name: string; + donated: number; + donatedAt: Date; + featuredSlot: string | null; + borrowing: boolean; + items: SkyBlockInventoryItem[]; + constructor(name: string, data: Record, decoded: any[]) { + this.name = name; + this.donated = data?.donated_time || 0; + this.donatedAt = new Date(this.donated); + this.featuredSlot = data?.featured_slot || null; + this.borrowing = data?.borrowing || false; + this.items = []; + decoded.forEach((item) => { + if (!item.tag) return; + this.items.push(new SkyBlockInventoryItem(item)); + }); + } + + toString(): string { + return this.name; + } +} + +export default SkyBlockMuseumItem; diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.test.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.test.ts new file mode 100644 index 000000000..dd576dc61 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.test.ts @@ -0,0 +1,19 @@ +import SkyBlockMuseumItem from './SkyBlockMuseumItem.js'; +import SkyBlockMuseumMember from './SkyBlockMuseumMember.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockMuseumMember', () => { + const data = new SkyBlockMuseumMember({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockMuseumMember); + expectTypeOf(data).toEqualTypeOf(); + expect(data.value).toBeDefined(); + expect(data.value).toBeGreaterThanOrEqual(0); + expectTypeOf(data.value).toEqualTypeOf(); + expect(data.appraisal).toBeDefined(); + expectTypeOf(data.appraisal).toEqualTypeOf(); + expect(data.rawItems).toBeDefined(); + expectTypeOf(data.rawItems).toEqualTypeOf>(); + expect(data.getItems).toBeDefined(); + expectTypeOf(data.getItems).toEqualTypeOf<() => Promise>(); +}); diff --git a/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.ts b/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.ts new file mode 100644 index 000000000..d650c3178 --- /dev/null +++ b/src/Structures/SkyBlock/Museum/SkyBlockMuseumMember.ts @@ -0,0 +1,25 @@ +import SkyBlockMuseumItem from './SkyBlockMuseumItem.js'; +import { decode } from '../../../Utils/SkyBlockUtils.js'; + +class SkyBlockMuseumMember { + value: number; + appraisal: boolean; + rawItems: Record; + getItems: () => Promise; + constructor(data: Record) { + this.value = data?.value || 0; + this.appraisal = data?.appraisal || false; + this.rawItems = data?.items || {}; + this.getItems = async (): Promise => { + const items: SkyBlockMuseumItem[] = []; + for (const item of Object.keys(data?.items || {})) { + items.push( + new SkyBlockMuseumItem(item, data?.items?.[item] || {}, await decode((data?.items?.[item] || {})?.data)) + ); + } + return items; + }; + } +} + +export default SkyBlockMuseumMember; diff --git a/src/Structures/SkyBlock/News/SkyBlockNews.test.ts b/src/Structures/SkyBlock/News/SkyBlockNews.test.ts new file mode 100644 index 000000000..79e99273c --- /dev/null +++ b/src/Structures/SkyBlock/News/SkyBlockNews.test.ts @@ -0,0 +1,22 @@ +import SkyBlockNews from './SkyBlockNews.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockNews', () => { + const data = new SkyBlockNews({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockNews); + expectTypeOf(data).toEqualTypeOf(); + expect(data.title).toBeDefined(); + expectTypeOf(data.title).toEqualTypeOf(); + expect(data.link).toBeDefined(); + expectTypeOf(data.link).toEqualTypeOf(); + expect(data.date).toBeDefined(); + expectTypeOf(data.date).toEqualTypeOf(); + expect(data.version).toBeDefined(); + expectTypeOf(data.version).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.title); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/News/SkyBlockNews.ts b/src/Structures/SkyBlock/News/SkyBlockNews.ts new file mode 100644 index 000000000..6f209889f --- /dev/null +++ b/src/Structures/SkyBlock/News/SkyBlockNews.ts @@ -0,0 +1,39 @@ +import type RequestData from '../../../Private/RequestData.js'; + +const dateRegExp = /(\d{1,2})(?:st|nd|rd|th|) ([A-Za-z]+) (\d+)/; +const versionRegExp = /v\d+(\.\d+){1,}/; + +function parseDate(stringDate: string): Date | null { + const matched = stringDate.match(dateRegExp); + if (!matched) return null; + return new Date(matched.slice(1).join(' ')); +} + +function parseVer(stringVer: string): string | null { + const matches = versionRegExp.exec(stringVer); + if (!matches?.length) return null; + return matches[0]; +} + +class SkyBlockNews { + title: string; + link: string; + date: Date | null; + version: string | null; + constructor(data: Record) { + this.title = data?.title || 'UNKNOWN'; + this.link = data?.link || 'UNKNOWN'; + this.date = parseDate(data?.text || 'UNKNOWN'); + this.version = parseVer(this.title); + } + + toString(): string { + return this.title; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockNews; diff --git a/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.test.ts b/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.test.ts new file mode 100644 index 000000000..d978de0a3 --- /dev/null +++ b/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.test.ts @@ -0,0 +1,30 @@ +import SkyBlockPotionEffect from './SkyBlockPotionEffect.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockPotionEffectName } from '../../../Types/SkyBlock.js'; + +test('SkyBlockPotionEffect', () => { + const data = new SkyBlockPotionEffect({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockPotionEffect); + expectTypeOf(data).toEqualTypeOf(); + expect(data.effect).toBeDefined(); + expectTypeOf(data.effect).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.modifiers).toBeDefined(); + expectTypeOf(data.modifiers).toEqualTypeOf<{ key: string; amp: number }[]>(); + expect(data.durationTicks).toBeDefined(); + expect(data.durationTicks).toBeGreaterThanOrEqual(0); + expectTypeOf(data.durationTicks).toEqualTypeOf(); + expect(data.duration).toBeDefined(); + expect(data.duration).toBeGreaterThanOrEqual(0); + expectTypeOf(data.duration).toEqualTypeOf(); + expect(data.infinite).toBeDefined(); + expectTypeOf(data.infinite).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockPotionEffectName | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.effect); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.ts b/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.ts new file mode 100644 index 000000000..7c56a653c --- /dev/null +++ b/src/Structures/SkyBlock/Potion/SkyBlockPotionEffect.ts @@ -0,0 +1,25 @@ +import TicksToMilliseconds from '../../../Utils/TicksToMilliseconds.js'; +import type { SkyBlockPotionEffectName } from '../../../Types/SkyBlock.js'; + +class SkyBlockPotionEffect { + effect: SkyBlockPotionEffectName | 'UNKNOWN'; + level: number; + modifiers: { key: string; amp: number }[]; + durationTicks: number; + duration: number; + infinite: boolean; + constructor(data: Record) { + this.effect = data?.effect || 'UNKNOWN'; + this.level = data?.level || 0; + this.modifiers = data?.modifiers || []; + this.durationTicks = data?.duration_ticks || 0; + this.duration = TicksToMilliseconds(this.durationTicks); + this.infinite = data?.infinite || false; + } + + toString(): SkyBlockPotionEffectName | 'UNKNOWN' { + return this.effect; + } +} + +export default SkyBlockPotionEffect; diff --git a/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.test.ts b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.test.ts new file mode 100644 index 000000000..634284cea --- /dev/null +++ b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.test.ts @@ -0,0 +1,20 @@ +import SkyBlockProfileBanking from './SkyBlockProfileBanking.js'; +import SkyBlockProfilesBankingTransaction from './SkyBlockProfilesBankingTransaction.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockProfileBanking', () => { + const data = new SkyBlockProfileBanking({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfileBanking); + expectTypeOf(data).toEqualTypeOf(); + expect(data.balance).toBeDefined(); + expect(data.balance).toBeGreaterThanOrEqual(0); + expectTypeOf(data.balance).toEqualTypeOf(); + expect(data.transactions).toBeDefined(); + expectTypeOf(data.transactions).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.balance); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.ts b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.ts new file mode 100644 index 000000000..7bcc73d44 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.ts @@ -0,0 +1,18 @@ +import SkyBlockProfilesBankingTransaction from './SkyBlockProfilesBankingTransaction.js'; + +class SkyBlockProfileBanking { + balance: number; + transactions: SkyBlockProfilesBankingTransaction[]; + constructor(data: Record) { + this.balance = data.balance || 0; + this.transactions = (data.transactions || []).map( + (transaction: Record) => new SkyBlockProfilesBankingTransaction(transaction) + ); + } + + toString(): number { + return this.balance; + } +} + +export default SkyBlockProfileBanking; diff --git a/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.test.ts b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.test.ts new file mode 100644 index 000000000..3bdaf08e1 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.test.ts @@ -0,0 +1,25 @@ +import SkyBlockProfilesBankingTransaction from './SkyBlockProfilesBankingTransaction.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { BankingTransactionAction } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockProfilesBankingTransaction', () => { + const data = new SkyBlockProfilesBankingTransaction({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfilesBankingTransaction); + expectTypeOf(data).toEqualTypeOf(); + expect(data.amount).toBeDefined(); + expect(data.amount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amount).toEqualTypeOf(); + expect(data.timestamp).toBeDefined(); + expect(data.timestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.timestamp).toEqualTypeOf(); + expect(data.action).toBeDefined(); + expectTypeOf(data.action).toEqualTypeOf(); + expect(data.user).toBeDefined(); + expectTypeOf(data.user).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.amount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.ts b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.ts new file mode 100644 index 000000000..136465bdb --- /dev/null +++ b/src/Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.ts @@ -0,0 +1,20 @@ +import type { BankingTransactionAction } from '../../../../Types/SkyBlock.js'; + +class SkyBlockProfilesBankingTransaction { + amount: number; + timestamp: number; + action: BankingTransactionAction | 'UNKNOWN'; + user: string | 'Bank Interest' | 'UNKNOWN'; + constructor(data: Record) { + this.amount = data?.amount || 0; + this.timestamp = data?.timestamp || 0; + this.action = data?.action || 'UNKNOWN'; + this.user = data?.initiator_name || 'UNKNOWN'; + } + + toString(): number { + return this.amount; + } +} + +export default SkyBlockProfilesBankingTransaction; diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.test.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.test.ts new file mode 100644 index 000000000..d6e8d7516 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.test.ts @@ -0,0 +1,20 @@ +import SkyBlockProfileCommunityUpgrades from './SkyBlockProfileCommunityUpgrades.js'; +import SkyBlockProfileCommunityUpgradesUpgraded from './SkyBlockProfileCommunityUpgradesUpgraded.js'; +import SkyBlockProfileCommunityUpgradesUpgrading from './SkyBlockProfileCommunityUpgradesUpgrading.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockProfileCommunityUpgrades', () => { + const data = new SkyBlockProfileCommunityUpgrades({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfileCommunityUpgrades); + expectTypeOf(data).toEqualTypeOf(); + expect(data.currentlyUpgrading).toBeDefined(); + expectTypeOf(data.currentlyUpgrading).toEqualTypeOf(); + expect(data.upgrades).toBeDefined(); + expectTypeOf(data.upgrades).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockProfileCommunityUpgradesUpgrading | null>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.currentlyUpgrading); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.ts new file mode 100644 index 000000000..cbb4c2f89 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.ts @@ -0,0 +1,22 @@ +import SkyBlockProfileCommunityUpgradesUpgraded from './SkyBlockProfileCommunityUpgradesUpgraded.js'; +import SkyBlockProfileCommunityUpgradesUpgrading from './SkyBlockProfileCommunityUpgradesUpgrading.js'; + +class SkyBlockProfileCommunityUpgrades { + currentlyUpgrading: SkyBlockProfileCommunityUpgradesUpgrading | null; + upgrades: SkyBlockProfileCommunityUpgradesUpgraded[]; + constructor(data: Record) { + this.currentlyUpgrading = data.currently_upgrading + ? new SkyBlockProfileCommunityUpgradesUpgrading(data.currently_upgrading) + : null; + this.upgrades = []; + (data.upgrade_states || []).forEach((upgrade: Record) => { + this.upgrades.push(new SkyBlockProfileCommunityUpgradesUpgraded(upgrade)); + }); + } + + toString(): SkyBlockProfileCommunityUpgradesUpgrading | null { + return this.currentlyUpgrading; + } +} + +export default SkyBlockProfileCommunityUpgrades; diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.test.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.test.ts new file mode 100644 index 000000000..d42542f25 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.test.ts @@ -0,0 +1,23 @@ +import SkyBlockProfileCommunityUpgradesUpgrade from './SkyBlockProfileCommunityUpgradesUpgrade.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { CommunityUpgradesUpgrades } from '../../../../Types/SkyBlock.js'; + +test('SkyBlockProfileCommunityUpgradesUpgrade', () => { + const data = new SkyBlockProfileCommunityUpgradesUpgrade({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfileCommunityUpgradesUpgrade); + expectTypeOf(data).toEqualTypeOf(); + expect(data.upgrade).toBeDefined(); + expectTypeOf(data.upgrade).toEqualTypeOf(); + expect(data.startedTimestamp).toBeDefined(); + expect(data.startedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startedTimestamp).toEqualTypeOf(); + expect(data.startedAt).toBeDefined(); + expect(data.startedAt).toBeInstanceOf(Date); + expectTypeOf(data.startedAt).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => CommunityUpgradesUpgrades | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.upgrade); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.ts new file mode 100644 index 000000000..b2a89b35b --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.ts @@ -0,0 +1,18 @@ +import type { CommunityUpgradesUpgrades } from '../../../../Types/SkyBlock.js'; + +class SkyBlockProfileCommunityUpgradesUpgrade { + upgrade: CommunityUpgradesUpgrades | 'UNKNOWN'; + startedTimestamp: number; + startedAt: Date; + constructor(data: Record) { + this.upgrade = data.upgrade || 'UNKNOWN'; + this.startedTimestamp = data.started_ms || 0; + this.startedAt = new Date(this.startedTimestamp); + } + + toString(): CommunityUpgradesUpgrades | 'UNKNOWN' { + return this.upgrade; + } +} + +export default SkyBlockProfileCommunityUpgradesUpgrade; diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.test.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.test.ts new file mode 100644 index 000000000..d615a4092 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.test.ts @@ -0,0 +1,26 @@ +import SkyBlockProfileCommunityUpgradesUpgraded from './SkyBlockProfileCommunityUpgradesUpgraded.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockProfileCommunityUpgradesUpgraded', () => { + const data = new SkyBlockProfileCommunityUpgradesUpgraded({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfileCommunityUpgradesUpgraded); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.startedBy).toBeDefined(); + expect(data.startedBy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startedBy).toEqualTypeOf(); + expect(data.claimedTimestamp).toBeDefined(); + expect(data.claimedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.claimedTimestamp).toEqualTypeOf(); + expect(data.claimedAt).toBeDefined(); + expect(data.claimedAt).toBeInstanceOf(Date); + expectTypeOf(data.claimedAt).toEqualTypeOf(); + expect(data.claimedBy).toBeDefined(); + expect(data.claimedBy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.claimedBy).toEqualTypeOf(); + expect(data.fasttracked).toBeDefined(); + expectTypeOf(data.fasttracked).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.ts new file mode 100644 index 000000000..bf2cbb09a --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.ts @@ -0,0 +1,21 @@ +import SkyBlockProfileCommunityUpgradesUpgrade from './SkyBlockProfileCommunityUpgradesUpgrade.js'; + +class SkyBlockProfileCommunityUpgradesUpgraded extends SkyBlockProfileCommunityUpgradesUpgrade { + tier: number; + startedBy: number; + claimedTimestamp: number; + claimedAt: Date; + claimedBy: number; + fasttracked: boolean; + constructor(data: Record) { + super(data); + this.tier = data.tier || 0; + this.startedBy = data.started_by || 0; + this.claimedTimestamp = data.claimed_ms || 0; + this.claimedAt = new Date(this.claimedTimestamp); + this.claimedBy = data.claimed_by || 0; + this.fasttracked = data.fasttracked || false; + } +} + +export default SkyBlockProfileCommunityUpgradesUpgraded; diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.test.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.test.ts new file mode 100644 index 000000000..4724f2ba1 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.test.ts @@ -0,0 +1,15 @@ +import SkyBlockProfileCommunityUpgradesUpgrading from './SkyBlockProfileCommunityUpgradesUpgrading.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockProfileCommunityUpgradesUpgrading', () => { + const data = new SkyBlockProfileCommunityUpgradesUpgrading({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfileCommunityUpgradesUpgrading); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expect(data.tier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.startedBy).toBeDefined(); + expect(data.startedBy).toBeGreaterThanOrEqual(0); + expectTypeOf(data.startedBy).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.ts b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.ts new file mode 100644 index 000000000..49801e7e3 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.ts @@ -0,0 +1,13 @@ +import SkyBlockProfileCommunityUpgradesUpgrade from './SkyBlockProfileCommunityUpgradesUpgrade.js'; + +class SkyBlockProfileCommunityUpgradesUpgrading extends SkyBlockProfileCommunityUpgradesUpgrade { + tier: number; + startedBy: number; + constructor(data: Record) { + super(data); + this.tier = data.new_tier || 0; + this.startedBy = data.who_started || 0; + } +} + +export default SkyBlockProfileCommunityUpgradesUpgrading; diff --git a/src/Structures/SkyBlock/Profile/SkyBlockProfile.test.ts b/src/Structures/SkyBlock/Profile/SkyBlockProfile.test.ts new file mode 100644 index 000000000..87338d0de --- /dev/null +++ b/src/Structures/SkyBlock/Profile/SkyBlockProfile.test.ts @@ -0,0 +1,46 @@ +import SkyBlockGarden from '../Garden/SkyBlockGarden.js'; +import SkyBlockMember from '../Member/SkyBlockMember.js'; +import SkyBlockMuseum from '../Museum/SkyBlockMuseum.js'; +import SkyBlockProfile from './SkyBlockProfile.js'; +import SkyBlockProfileBanking from './Banking/SkyBlockProfileBanking.js'; +import SkyBlockProfileCommunityUpgrades from './CommunityUpgrades/SkyBlockProfileCommunityUpgrades.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { SkyBlockProfileName, SkyBlockProfileType } from '../../../Types/SkyBlock.js'; + +test('SkyBlockProfile', () => { + const data = new SkyBlockProfile({ stats: 'meow' }, { uuid: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockProfile); + expectTypeOf(data).toEqualTypeOf(); + expect(data.profileId).toBeDefined(); + expectTypeOf(data.profileId).toEqualTypeOf(); + expect(data.communityUpgrades).toBeDefined(); + expect(data.communityUpgrades).toBeInstanceOf(SkyBlockProfileCommunityUpgrades); + expectTypeOf(data.communityUpgrades).toEqualTypeOf(); + expect(data.createdTimestamp).toBeDefined(); + expectTypeOf(data.createdTimestamp).toEqualTypeOf(); + expect(data.createdAt).toBeDefined(); + expectTypeOf(data.createdAt).toEqualTypeOf(); + expect(data.members).toBeDefined(); + expectTypeOf(data.members).toEqualTypeOf(); + expect(data.me).toBeDefined(); + expectTypeOf(data.me).toEqualTypeOf(); + expect(data.gameMode).toBeDefined(); + expectTypeOf(data.gameMode).toEqualTypeOf(); + expect(data.banking).toBeDefined(); + expect(data.banking).toBeInstanceOf(SkyBlockProfileBanking); + expectTypeOf(data.banking).toEqualTypeOf(); + expect(data.profileName).toBeDefined(); + expectTypeOf(data.profileName).toEqualTypeOf(); + expect(data.selected).toBeDefined(); + expectTypeOf(data.selected).toEqualTypeOf(); + expect(data.garden).toBeDefined(); + expectTypeOf(data.garden).toEqualTypeOf(); + expect(data.museum).toBeDefined(); + expectTypeOf(data.museum).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => SkyBlockProfileName | 'UNKNOWN'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.profileName); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Profile/SkyBlockProfile.ts b/src/Structures/SkyBlock/Profile/SkyBlockProfile.ts new file mode 100644 index 000000000..a1133f7c7 --- /dev/null +++ b/src/Structures/SkyBlock/Profile/SkyBlockProfile.ts @@ -0,0 +1,51 @@ +import SkyBlockMember from '../Member/SkyBlockMember.js'; +import SkyBlockProfileBanking from './Banking/SkyBlockProfileBanking.js'; +import SkyBlockProfileCommunityUpgrades from './CommunityUpgrades/SkyBlockProfileCommunityUpgrades.js'; +import type RequestData from '../../../Private/RequestData.js'; +import type SkyBlockGarden from '../Garden/SkyBlockGarden.js'; +import type SkyBlockMuseum from '../Museum/SkyBlockMuseum.js'; +import type { SkyBlockProfileName, SkyBlockProfileType } from '../../../Types/SkyBlock.js'; +import type { UUID } from '../../../Types/Global.js'; + +class SkyBlockProfile { + profileId: string; + communityUpgrades: SkyBlockProfileCommunityUpgrades; + createdTimestamp: number | null; + createdAt: Date | null; + members: SkyBlockMember[]; + me: SkyBlockMember | null; + gameMode: SkyBlockProfileType | null; + banking: SkyBlockProfileBanking; + profileName: SkyBlockProfileName | 'UNKNOWN'; + selected: boolean; + garden: SkyBlockGarden | null; + museum: SkyBlockMuseum | null; + constructor( + data: Record, + extra: { uuid: UUID | null; garden?: SkyBlockGarden; museum?: SkyBlockMuseum } + ) { + this.profileId = data?.profile_id || 'UNKNOWN'; + this.communityUpgrades = new SkyBlockProfileCommunityUpgrades(data.communityUpgrades || {}); + this.createdTimestamp = data.created_at ? data.created_at : null; + this.createdAt = this.createdTimestamp ? new Date(this.createdTimestamp) : null; + const members = data?.members || {}; + this.members = Object.keys(members).map((uuid) => new SkyBlockMember(uuid, members?.[uuid] || {})); + this.me = extra.uuid !== null ? this.members.find((x) => x.uuid === extra.uuid) || null : null; + this.gameMode = data?.game_mode || null; + this.banking = new SkyBlockProfileBanking(data?.banking || {}); + this.profileName = data?.cute_name || 'UNKNOWN'; + this.selected = data?.selected || false; + this.garden = extra.garden || null; + this.museum = extra.museum || null; + } + + toString(): SkyBlockProfileName | 'UNKNOWN' { + return this.profileName; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockProfile; diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkill.test.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkill.test.ts new file mode 100644 index 000000000..a90f4ee9e --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkill.test.ts @@ -0,0 +1,24 @@ +import SkyBlockSkill from './SkyBlockSkill.js'; +import SkyBlockSkillLevel from './SkyBlockSkillLevel.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockSkill', () => { + const data = new SkyBlockSkill({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.maxLevel).toBeDefined(); + expect(data.maxLevel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.maxLevel).toEqualTypeOf(); + expect(data.levels).toBeDefined(); + expectTypeOf(data.levels).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkill.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkill.ts new file mode 100644 index 000000000..e8ce8add7 --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkill.ts @@ -0,0 +1,20 @@ +import SkyBlockSkillLevel from './SkyBlockSkillLevel.js'; + +class SkyBlockSkill { + name: string; + description: string; + maxLevel: number; + levels: SkyBlockSkillLevel[]; + constructor(data: Record) { + this.name = data?.name || 'UNKNOWN'; + this.description = data?.description || 'UNKNOWN'; + this.maxLevel = data?.maxLevel || 0; + this.levels = (data?.levels || []).map((level: Record) => new SkyBlockSkillLevel(level)); + } + + toString(): string { + return this.name; + } +} + +export default SkyBlockSkill; diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.test.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.test.ts new file mode 100644 index 000000000..fbcad663e --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.test.ts @@ -0,0 +1,22 @@ +import SkyBlockSkillLevel from './SkyBlockSkillLevel.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockSkillLevel', () => { + const data = new SkyBlockSkillLevel({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockSkillLevel); + expectTypeOf(data).toEqualTypeOf(); + expect(data.level).toBeDefined(); + expect(data.level).toBeGreaterThanOrEqual(0); + expectTypeOf(data.level).toEqualTypeOf(); + expect(data.totalExpRequired).toBeDefined(); + expect(data.totalExpRequired).toBeGreaterThanOrEqual(0); + expectTypeOf(data.totalExpRequired).toEqualTypeOf(); + expect(data.unlocks).toBeDefined(); + expectTypeOf(data.unlocks).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.level); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.ts new file mode 100644 index 000000000..a06e97d41 --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkillLevel.ts @@ -0,0 +1,16 @@ +class SkyBlockSkillLevel { + level: number; + totalExpRequired: number; + unlocks: string[]; + constructor(data: Record) { + this.level = data?.level || 0; + this.totalExpRequired = data?.totalExpRequired || 0; + this.unlocks = data?.unlocks || []; + } + + toString(): number { + return this.level; + } +} + +export default SkyBlockSkillLevel; diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkills.test.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkills.test.ts new file mode 100644 index 000000000..06a442349 --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkills.test.ts @@ -0,0 +1,51 @@ +import SkyBlockSkill from './SkyBlockSkill.js'; +import SkyBlockSkills from './SkyBlockSkills.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockSkills', () => { + const data = new SkyBlockSkills({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockSkills); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdated).toBeDefined(); + expect(data.lastUpdated).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdated).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.version).toBeDefined(); + expectTypeOf(data.version).toEqualTypeOf(); + expect(data.farming).toBeDefined(); + expect(data.farming).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.farming).toEqualTypeOf(); + expect(data.mining).toBeDefined(); + expect(data.mining).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.mining).toEqualTypeOf(); + expect(data.combat).toBeDefined(); + expect(data.combat).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.combat).toEqualTypeOf(); + expect(data.foraging).toBeDefined(); + expect(data.foraging).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.foraging).toEqualTypeOf(); + expect(data.fishing).toBeDefined(); + expect(data.fishing).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.fishing).toEqualTypeOf(); + expect(data.enchanting).toBeDefined(); + expect(data.enchanting).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.enchanting).toEqualTypeOf(); + expect(data.alchemy).toBeDefined(); + expect(data.alchemy).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.alchemy).toEqualTypeOf(); + expect(data.carpentry).toBeDefined(); + expect(data.carpentry).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.carpentry).toEqualTypeOf(); + expect(data.runecrafting).toBeDefined(); + expect(data.runecrafting).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.runecrafting).toEqualTypeOf(); + expect(data.social).toBeDefined(); + expect(data.social).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.social).toEqualTypeOf(); + expect(data.taming).toBeDefined(); + expect(data.taming).toBeInstanceOf(SkyBlockSkill); + expectTypeOf(data.taming).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/Skills/SkyBlockSkills.ts b/src/Structures/SkyBlock/Skills/SkyBlockSkills.ts new file mode 100644 index 000000000..2c52d9cb7 --- /dev/null +++ b/src/Structures/SkyBlock/Skills/SkyBlockSkills.ts @@ -0,0 +1,41 @@ +import SkyBlockSkill from './SkyBlockSkill.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class SkyBlockSkills { + lastUpdated: number; + lastUpdatedAt: Date; + version: string; + farming: SkyBlockSkill; + mining: SkyBlockSkill; + combat: SkyBlockSkill; + foraging: SkyBlockSkill; + fishing: SkyBlockSkill; + enchanting: SkyBlockSkill; + alchemy: SkyBlockSkill; + carpentry: SkyBlockSkill; + runecrafting: SkyBlockSkill; + social: SkyBlockSkill; + taming: SkyBlockSkill; + constructor(data: Record) { + this.lastUpdated = data?.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdated); + this.version = data?.version || 'UNKNOWN'; + this.farming = new SkyBlockSkill(data?.skills?.FARMING || {}); + this.mining = new SkyBlockSkill(data?.skills?.MINING || {}); + this.combat = new SkyBlockSkill(data?.skills?.COMBAT || {}); + this.foraging = new SkyBlockSkill(data?.skills?.FORAGING || {}); + this.fishing = new SkyBlockSkill(data?.skills?.FISHING || {}); + this.enchanting = new SkyBlockSkill(data?.skills?.ENCHANTING || {}); + this.alchemy = new SkyBlockSkill(data?.skills?.ALCHEMY || {}); + this.carpentry = new SkyBlockSkill(data?.skills?.CARPENTRY || {}); + this.runecrafting = new SkyBlockSkill(data?.skills?.RUNECRAFTING || {}); + this.social = new SkyBlockSkill(data?.skills?.SOCIAL || {}); + this.taming = new SkyBlockSkill(data?.skills?.TAMING || {}); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockSkills; diff --git a/src/Structures/SkyBlock/SkyBlockItem.test.ts b/src/Structures/SkyBlock/SkyBlockItem.test.ts new file mode 100644 index 000000000..2a6d4c7da --- /dev/null +++ b/src/Structures/SkyBlock/SkyBlockItem.test.ts @@ -0,0 +1,139 @@ +import SkyBlockItem from './SkyBlockItem.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('SkyBlockItem', () => { + const data = new SkyBlockItem({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(SkyBlockItem); + expectTypeOf(data).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.material).toBeDefined(); + expectTypeOf(data.material).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.durability).toBeDefined(); + expect(data.durability).toBeGreaterThanOrEqual(0); + expectTypeOf(data.durability).toEqualTypeOf(); + expect(data.skin).toBeDefined(); + expectTypeOf(data.skin).toEqualTypeOf>(); + expect(data.category).toBeDefined(); + expectTypeOf(data.category).toEqualTypeOf(); + expect(data.tier).toBeDefined(); + expectTypeOf(data.tier).toEqualTypeOf(); + expect(data.npcSellPrice).toBeDefined(); + expect(data.npcSellPrice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.npcSellPrice).toEqualTypeOf(); + expect(data.salvages).toBeDefined(); + expectTypeOf(data.salvages).toEqualTypeOf[]>(); + expect(data.raritySalvageable).toBeDefined(); + expectTypeOf(data.raritySalvageable).toEqualTypeOf(); + expect(data.stats).toBeDefined(); + expectTypeOf(data.stats).toEqualTypeOf>(); + expect(data.unstackable).toBeDefined(); + expectTypeOf(data.unstackable).toEqualTypeOf(); + expect(data.museumData).toBeDefined(); + expectTypeOf(data.museumData).toEqualTypeOf>(); + expect(data.color).toBeDefined(); + expectTypeOf(data.color).toEqualTypeOf(); + expect(data.soulbound).toBeDefined(); + expectTypeOf(data.soulbound).toEqualTypeOf(); + expect(data.hasUuid).toBeDefined(); + expectTypeOf(data.hasUuid).toEqualTypeOf(); + expect(data.gemstoneSlots).toBeDefined(); + expectTypeOf(data.gemstoneSlots).toEqualTypeOf[]>(); + expect(data.glowing).toBeDefined(); + expectTypeOf(data.glowing).toEqualTypeOf(); + expect(data.canAuction).toBeDefined(); + expectTypeOf(data.canAuction).toEqualTypeOf(); + expect(data.canTrade).toBeDefined(); + expectTypeOf(data.canTrade).toEqualTypeOf(); + expect(data.requirements).toBeDefined(); + expectTypeOf(data.requirements).toEqualTypeOf[]>(); + expect(data.canPlace).toBeDefined(); + expectTypeOf(data.canPlace).toEqualTypeOf(); + expect(data.museum).toBeDefined(); + expectTypeOf(data.museum).toEqualTypeOf(); + expect(data.generator).toBeDefined(); + expectTypeOf(data.generator).toEqualTypeOf(); + expect(data.generatorTier).toBeDefined(); + expect(data.generatorTier).toBeGreaterThanOrEqual(0); + expectTypeOf(data.generatorTier).toEqualTypeOf(); + expect(data.furniture).toBeDefined(); + expectTypeOf(data.furniture).toEqualTypeOf(); + expect(data.itemSpecific).toBeDefined(); + expectTypeOf(data.itemSpecific).toEqualTypeOf>(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.upgradeCosts).toBeDefined(); + expectTypeOf(data.upgradeCosts).toEqualTypeOf>>>(); + expect(data.gearScore).toBeDefined(); + expect(data.gearScore).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gearScore).toEqualTypeOf(); + expect(data.dungeonItem).toBeDefined(); + expectTypeOf(data.dungeonItem).toEqualTypeOf(); + expect(data.dungeonItemConversionCost).toBeDefined(); + expectTypeOf(data.dungeonItemConversionCost).toEqualTypeOf>(); + expect(data.catacombsRequirements).toBeDefined(); + expectTypeOf(data.catacombsRequirements).toEqualTypeOf[]>(); + expect(data.canHaveAttributes).toBeDefined(); + expectTypeOf(data.canHaveAttributes).toEqualTypeOf(); + expect(data.salvageableFromRecipe).toBeDefined(); + expectTypeOf(data.salvageableFromRecipe).toEqualTypeOf(); + expect(data.canRecombobulate).toBeDefined(); + expectTypeOf(data.canRecombobulate).toEqualTypeOf(); + expect(data.enchantments).toBeDefined(); + expectTypeOf(data.enchantments).toEqualTypeOf>(); + expect(data.riftTransferrable).toBeDefined(); + expectTypeOf(data.riftTransferrable).toEqualTypeOf(); + expect(data.origin).toBeDefined(); + expectTypeOf(data.origin).toEqualTypeOf(); + expect(data.doubleTapToDrop).toBeDefined(); + expectTypeOf(data.doubleTapToDrop).toEqualTypeOf(); + expect(data.hideFromViewRecipeCommand).toBeDefined(); + expectTypeOf(data.hideFromViewRecipeCommand).toEqualTypeOf(); + expect(data.swordType).toBeDefined(); + expectTypeOf(data.swordType).toEqualTypeOf(); + expect(data.abilityDamageScaling).toBeDefined(); + expect(data.abilityDamageScaling).toBeGreaterThanOrEqual(0); + expectTypeOf(data.abilityDamageScaling).toEqualTypeOf(); + expect(data.tieredStats).toBeDefined(); + expectTypeOf(data.tieredStats).toEqualTypeOf>(); + expect(data.motesSellPrice).toBeDefined(); + expect(data.motesSellPrice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.motesSellPrice).toEqualTypeOf(); + expect(data.crystal).toBeDefined(); + expectTypeOf(data.crystal).toEqualTypeOf(); + expect(data.canBurnInFurnace).toBeDefined(); + expectTypeOf(data.canBurnInFurnace).toEqualTypeOf(); + expect(data.salvage).toBeDefined(); + expectTypeOf(data.salvage).toEqualTypeOf>(); + expect(data.serializable).toBeDefined(); + expectTypeOf(data.serializable).toEqualTypeOf(); + expect(data.canInteract).toBeDefined(); + expectTypeOf(data.canInteract).toEqualTypeOf(); + expect(data.canInteractRightClick).toBeDefined(); + expectTypeOf(data.canInteractRightClick).toEqualTypeOf(); + expect(data.privateIsland).toBeDefined(); + expectTypeOf(data.privateIsland).toEqualTypeOf(); + expect(data.canHavePowerScroll).toBeDefined(); + expectTypeOf(data.canHavePowerScroll).toEqualTypeOf(); + expect(data.canInteractEntity).toBeDefined(); + expectTypeOf(data.canInteractEntity).toEqualTypeOf(); + expect(data.miningFortune).toBeDefined(); + expect(data.miningFortune).toBeGreaterThanOrEqual(0); + expectTypeOf(data.miningFortune).toEqualTypeOf(); + expect(data.recipes).toBeDefined(); + expectTypeOf(data.recipes).toEqualTypeOf[]>(); + expect(data.cannotReforge).toBeDefined(); + expectTypeOf(data.cannotReforge).toEqualTypeOf(); + expect(data.loseMotesValueOnTransfer).toBeDefined(); + expectTypeOf(data.loseMotesValueOnTransfer).toEqualTypeOf(); + expect(data.prestige).toBeDefined(); + expectTypeOf(data.prestige).toEqualTypeOf>(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/SkyBlock/SkyBlockItem.ts b/src/Structures/SkyBlock/SkyBlockItem.ts new file mode 100644 index 000000000..6fb93c69d --- /dev/null +++ b/src/Structures/SkyBlock/SkyBlockItem.ts @@ -0,0 +1,134 @@ +import type RequestData from '../../Private/RequestData.js'; + +class SkyBlockItem { + name: string; + material: string; + id: string; + durability: number; + skin: Record; + category: string; + tier: string; + npcSellPrice: number; + salvages: Record[]; + raritySalvageable: boolean; + stats: Record; + unstackable: boolean; + museumData: Record; + color: string; + soulbound: string; + hasUuid: boolean | string; + gemstoneSlots: Record[]; + glowing: boolean; + canAuction: boolean; + canTrade: boolean; + requirements: Record[]; + canPlace: boolean; + museum: boolean; + generator: string; + generatorTier: number; + furniture: string; + itemSpecific: Record; + description: string; + upgradeCosts: Array>>; + gearScore: number; + dungeonItem: boolean; + dungeonItemConversionCost: Record; + catacombsRequirements: Record[]; + canHaveAttributes: boolean; + salvageableFromRecipe: boolean; + canRecombobulate: boolean; + enchantments: Record; + riftTransferrable: boolean; + origin: string; + doubleTapToDrop: boolean; + hideFromViewRecipeCommand: boolean; + swordType: string; + abilityDamageScaling: number; + tieredStats: Record; + motesSellPrice: number; + crystal: string; + canBurnInFurnace: boolean; + salvage: Record; + serializable: boolean; + canInteract: boolean; + canInteractRightClick: boolean; + privateIsland: string; + canHavePowerScroll: boolean; + canInteractEntity: boolean; + miningFortune: number; + recipes: Record[]; + cannotReforge: boolean; + loseMotesValueOnTransfer: boolean; + prestige: Record; + constructor(data: Record) { + this.name = data?.name || 'UNKNOWN'; + this.material = data?.material || 'UNKNOWN'; + this.id = data?.id || 'UNKNOWN'; + this.durability = data?.durability || 0; + this.skin = data?.skin || {}; + this.category = data?.category || 'UNKNOWN'; + this.tier = data?.tier || 'UNKNOWN'; + this.npcSellPrice = data?.npc_sell_price || 0; + this.salvages = data?.salvages || []; + this.raritySalvageable = data?.rarity_salvageable || false; + this.stats = data?.stats || {}; + this.unstackable = data?.unstackable || false; + this.museumData = data?.museum_data || {}; + this.color = data?.color || 'UNKNOWN'; + this.soulbound = data?.soulbound || 'UNKNOWN'; + this.hasUuid = data?.has_uuid || false; + this.gemstoneSlots = data?.gemstone_slots || []; + this.glowing = data?.glowing || false; + this.canAuction = data?.can_auction || false; + this.canTrade = data?.can_trade || false; + this.requirements = data?.requirements || []; + this.canPlace = data?.can_place || false; + this.museum = data?.museum || false; + this.generator = data?.generator || 'UNKNOWN'; + this.generatorTier = data?.generator_tier || 0; + this.furniture = data?.furniture || 'UNKNOWN'; + this.itemSpecific = data?.item_specific || {}; + this.description = data?.description || 'UNKNOWN'; + this.upgradeCosts = data?.upgrade_costs || []; + this.gearScore = data?.gear_score || 0; + this.dungeonItem = data?.dungeon_item || false; + this.dungeonItemConversionCost = data?.dungeon_item_conversion_cost || {}; + this.catacombsRequirements = data?.catacombs_requirements || []; + this.canHaveAttributes = data?.can_have_attributes || false; + this.salvageableFromRecipe = data?.salvageable_from_recipe || false; + this.canRecombobulate = data?.can_recombobulate || false; + this.enchantments = data?.enchantments || {}; + this.riftTransferrable = data?.rift_transferrable || false; + this.origin = data?.origin || 'UNKNOWN'; + this.doubleTapToDrop = data?.double_tap_to_drop || false; + this.hideFromViewRecipeCommand = data?.hide_from_viewrecipe_command || false; + this.swordType = data?.sword_type || 'UNKNOWN'; + this.abilityDamageScaling = data?.ability_damage_scaling || 0; + this.tieredStats = data?.tiered_stats || {}; + this.motesSellPrice = data?.motes_sell_price || 0; + this.crystal = data?.crystal || 'UNKNOWN'; + this.canBurnInFurnace = data?.can_burn_in_furnace || false; + this.salvage = data?.salvage || {}; + this.serializable = data?.serializable || false; + this.canInteract = data?.can_interact || false; + this.canInteractRightClick = data?.can_interact_right_click || false; + this.privateIsland = data?.private_island || 'UNKNOWN'; + this.canHavePowerScroll = data?.can_have_power_scroll || false; + this.canInteractEntity = data?.can_interact_entity || false; + this.miningFortune = data?.MINING_FORTUNE || 0; + this.recipes = data?.recipes || []; + this.cannotReforge = data?.cannot_reforge || false; + this.loseMotesValueOnTransfer = data?.lose_motes_value_on_transfer || false; + this.prestige = data?.prestige || {}; + } + + toString(): string { + return this.name; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default SkyBlockItem; diff --git a/src/Structures/Static/Achievements/Achievements.test.ts b/src/Structures/Static/Achievements/Achievements.test.ts new file mode 100644 index 000000000..996ddd285 --- /dev/null +++ b/src/Structures/Static/Achievements/Achievements.test.ts @@ -0,0 +1,18 @@ +import Achievements from './Achievements.js'; +import GameAchievements from './GameAchievements.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Achievements', () => { + const data = new Achievements({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Achievements); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.achievementsPerGame).toBeDefined(); + expectTypeOf(data.achievementsPerGame).toEqualTypeOf>(); +}); diff --git a/src/Structures/Static/Achievements/Achievements.ts b/src/Structures/Static/Achievements/Achievements.ts new file mode 100644 index 000000000..5ca1fbb0d --- /dev/null +++ b/src/Structures/Static/Achievements/Achievements.ts @@ -0,0 +1,22 @@ +import GameAchievements from './GameAchievements.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class Achievements { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + achievementsPerGame: Record; + constructor(data: Record) { + this.lastUpdatedTimestamp = data.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.achievementsPerGame = {}; + Object.keys(data.achievements || {}).forEach((game) => { + this.achievementsPerGame.game = new GameAchievements(game, data.achievements[game]); + }); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Achievements; diff --git a/src/Structures/Static/Achievements/BaseAchievement.test.ts b/src/Structures/Static/Achievements/BaseAchievement.test.ts new file mode 100644 index 000000000..944d5d424 --- /dev/null +++ b/src/Structures/Static/Achievements/BaseAchievement.test.ts @@ -0,0 +1,24 @@ +import BaseAchievement from './BaseAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('BaseAchievement', () => { + const data = new BaseAchievement('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(BaseAchievement); + expectTypeOf(data).toEqualTypeOf(); + expect(data.codeName).toBeDefined(); + expectTypeOf(data.codeName).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.secret).toBeDefined(); + expectTypeOf(data.secret).toEqualTypeOf(); + expect(data.legacy).toBeDefined(); + expectTypeOf(data.legacy).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.codeName); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Achievements/BaseAchievement.ts b/src/Structures/Static/Achievements/BaseAchievement.ts new file mode 100644 index 000000000..8a7dd24fa --- /dev/null +++ b/src/Structures/Static/Achievements/BaseAchievement.ts @@ -0,0 +1,20 @@ +class BaseAchievement { + codeName: string; + name: string; + description: string; + secret: boolean; + legacy: boolean; + constructor(achievementName: string, data: Record) { + this.codeName = achievementName; + this.name = data.name || 'UNKNOWN'; + this.description = data.description || 'UNKNOWN'; + this.secret = data.secret || false; + this.legacy = data.legacy || false; + } + + toString(): string { + return this.codeName; + } +} + +export default BaseAchievement; diff --git a/src/Structures/Static/Achievements/GameAchievements.test.ts b/src/Structures/Static/Achievements/GameAchievements.test.ts new file mode 100644 index 000000000..dedbd9f0e --- /dev/null +++ b/src/Structures/Static/Achievements/GameAchievements.test.ts @@ -0,0 +1,23 @@ +import GameAchievements from './GameAchievements.js'; +import OneTimeAchievement from './OneTimeAchievement.js'; +import TieredAchievement from './TieredAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameAchievements', () => { + const data = new GameAchievements('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameAchievements); + expectTypeOf(data).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.points).toBeDefined(); + expect(data.points).toBeGreaterThanOrEqual(0); + expectTypeOf(data.points).toEqualTypeOf(); + expect(data.legacyPoints).toBeDefined(); + expect(data.legacyPoints).toBeGreaterThanOrEqual(0); + expectTypeOf(data.legacyPoints).toEqualTypeOf(); + expect(data.oneTimeAchievements).toBeDefined(); + expectTypeOf(data.oneTimeAchievements).toEqualTypeOf(); + expect(data.tieredAchievements).toBeDefined(); + expectTypeOf(data.tieredAchievements).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Achievements/GameAchievements.ts b/src/Structures/Static/Achievements/GameAchievements.ts new file mode 100644 index 000000000..a3e225a83 --- /dev/null +++ b/src/Structures/Static/Achievements/GameAchievements.ts @@ -0,0 +1,23 @@ +import OneTimeAchievement from './OneTimeAchievement.js'; +import TieredAchievement from './TieredAchievement.js'; + +class GameAchievements { + game: string; + points: number; + legacyPoints: number; + oneTimeAchievements: OneTimeAchievement[]; + tieredAchievements: TieredAchievement[]; + constructor(game: string, data: Record) { + this.game = game; + this.points = data.total_points || 0; + this.legacyPoints = data.total_legacy_points || 0; + this.oneTimeAchievements = Object.keys(data.one_time || {}).map( + (achievementKey) => new OneTimeAchievement(achievementKey, data.one_time[achievementKey]) + ); + this.tieredAchievements = Object.keys(data.tiered || {}).map( + (achievementKey) => new TieredAchievement(achievementKey, data.tiered[achievementKey]) + ); + } +} + +export default GameAchievements; diff --git a/src/Structures/Static/Achievements/GuildAchievements.test.ts b/src/Structures/Static/Achievements/GuildAchievements.test.ts new file mode 100644 index 000000000..f07d76ee3 --- /dev/null +++ b/src/Structures/Static/Achievements/GuildAchievements.test.ts @@ -0,0 +1,21 @@ +import GuildAchievements from './GuildAchievements.js'; +import OneTimeAchievement from './OneTimeAchievement.js'; +import TieredAchievement from './TieredAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GuildAchievements', () => { + const data = new GuildAchievements({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GuildAchievements); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.oneTimeAchievements).toBeDefined(); + expectTypeOf(data.oneTimeAchievements).toEqualTypeOf(); + expect(data.tieredAchievements).toBeDefined(); + expectTypeOf(data.tieredAchievements).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Achievements/GuildAchievements.ts b/src/Structures/Static/Achievements/GuildAchievements.ts new file mode 100644 index 000000000..b90bcd587 --- /dev/null +++ b/src/Structures/Static/Achievements/GuildAchievements.ts @@ -0,0 +1,26 @@ +import OneTimeAchievement from './OneTimeAchievement.js'; +import TieredAchievement from './TieredAchievement.js'; +import type RequestData from '../../../Private/RequestData.js'; + +class GuildAchievements { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + oneTimeAchievements: OneTimeAchievement[]; + tieredAchievements: TieredAchievement[]; + constructor(data: Record) { + this.lastUpdatedTimestamp = data.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.oneTimeAchievements = Object.keys(data.one_time || {}).map( + (achievementKey) => new OneTimeAchievement(achievementKey, data.one_time[achievementKey]) + ); + this.tieredAchievements = Object.keys(data.tiered || {}).map( + (achievementKey) => new TieredAchievement(achievementKey, data.tiered[achievementKey]) + ); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default GuildAchievements; diff --git a/src/Structures/Static/Achievements/OneTimeAchievement.test.ts b/src/Structures/Static/Achievements/OneTimeAchievement.test.ts new file mode 100644 index 000000000..18c73d473 --- /dev/null +++ b/src/Structures/Static/Achievements/OneTimeAchievement.test.ts @@ -0,0 +1,18 @@ +import OneTimeAchievement from './OneTimeAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('OneTimeAchievement', () => { + const data = new OneTimeAchievement('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(OneTimeAchievement); + expectTypeOf(data).toEqualTypeOf(); + expect(data.points).toBeDefined(); + expect(data.points).toBeGreaterThanOrEqual(0); + expectTypeOf(data.points).toEqualTypeOf(); + expect(data.gamePercentUnlocked).toBeDefined(); + expect(data.gamePercentUnlocked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gamePercentUnlocked).toEqualTypeOf(); + expect(data.globalPercentUnlocked).toBeDefined(); + expect(data.globalPercentUnlocked).toBeGreaterThanOrEqual(0); + expectTypeOf(data.globalPercentUnlocked).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Achievements/OneTimeAchievement.ts b/src/Structures/Static/Achievements/OneTimeAchievement.ts new file mode 100644 index 000000000..044c7a3f8 --- /dev/null +++ b/src/Structures/Static/Achievements/OneTimeAchievement.ts @@ -0,0 +1,15 @@ +import BaseAchievement from './BaseAchievement.js'; + +class OneTimeAchievement extends BaseAchievement { + points: number; + gamePercentUnlocked: number; + globalPercentUnlocked: number; + constructor(achievementName: string, data: Record) { + super(achievementName, data); + this.points = data.points || 0; + this.gamePercentUnlocked = data.gamePercentUnlocked || 0; + this.globalPercentUnlocked = data.globalPercentUnlocked || 0; + } +} + +export default OneTimeAchievement; diff --git a/src/Structures/Static/Achievements/TieredAchievement.test.ts b/src/Structures/Static/Achievements/TieredAchievement.test.ts new file mode 100644 index 000000000..f68b7e31b --- /dev/null +++ b/src/Structures/Static/Achievements/TieredAchievement.test.ts @@ -0,0 +1,12 @@ +import TieredAchievement from './TieredAchievement.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { AchievementTier } from '../../../Types/Static.js'; + +test('TieredAchievement', () => { + const data = new TieredAchievement('mrrp', { stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(TieredAchievement); + expectTypeOf(data).toEqualTypeOf(); + expect(data.tiers).toBeDefined(); + expectTypeOf(data.tiers).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Achievements/TieredAchievement.ts b/src/Structures/Static/Achievements/TieredAchievement.ts new file mode 100644 index 000000000..ea999e413 --- /dev/null +++ b/src/Structures/Static/Achievements/TieredAchievement.ts @@ -0,0 +1,12 @@ +import BaseAchievement from './BaseAchievement.js'; +import type { AchievementTier } from '../../../Types/Static.js'; + +class TieredAchievement extends BaseAchievement { + tiers: AchievementTier[]; + constructor(achievementName: string, data: Record) { + super(achievementName, data); + this.tiers = data.tiers || []; + } +} + +export default TieredAchievement; diff --git a/src/Structures/Static/Challenge.test.ts b/src/Structures/Static/Challenge.test.ts new file mode 100644 index 000000000..2936a6c37 --- /dev/null +++ b/src/Structures/Static/Challenge.test.ts @@ -0,0 +1,16 @@ +import Challenge from './Challenge.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { ChallengeReward } from '../../Types/Static.js'; + +test('Challenge', () => { + const data = new Challenge({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Challenge); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.rewards).toBeDefined(); + expectTypeOf(data.rewards).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Challenge.ts b/src/Structures/Static/Challenge.ts new file mode 100644 index 000000000..7c90a8bd7 --- /dev/null +++ b/src/Structures/Static/Challenge.ts @@ -0,0 +1,14 @@ +import type { ChallengeReward } from '../../Types/Static.js'; + +class Challenge { + id: string; + name: string; + rewards: ChallengeReward[]; + constructor(data: Record) { + this.id = data.id || 'UNKNOWN'; + this.name = data.name || 'UNKNOWN'; + this.rewards = data.rewards || []; + } +} + +export default Challenge; diff --git a/src/Structures/Static/Challenges.test.ts b/src/Structures/Static/Challenges.test.ts new file mode 100644 index 000000000..19c74a8b1 --- /dev/null +++ b/src/Structures/Static/Challenges.test.ts @@ -0,0 +1,18 @@ +import Challenges from './Challenges.js'; +import GameChallenges from './GameChallenges.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Challenges', () => { + const data = new Challenges({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Challenges); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.challengesPerGame).toBeDefined(); + expectTypeOf(data.challengesPerGame).toEqualTypeOf>(); +}); diff --git a/src/Structures/Static/Challenges.ts b/src/Structures/Static/Challenges.ts new file mode 100644 index 000000000..db143e222 --- /dev/null +++ b/src/Structures/Static/Challenges.ts @@ -0,0 +1,22 @@ +import GameChallenges from './GameChallenges.js'; +import type RequestData from '../../Private/RequestData.js'; + +class Challenges { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + challengesPerGame: Record; + constructor(data: Record) { + this.lastUpdatedTimestamp = data.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.challengesPerGame = {}; + Object.keys(data?.challenges || {}).forEach((game) => { + this.challengesPerGame[game] = new GameChallenges(game, data.challenges[game]); + }); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Challenges; diff --git a/src/Structures/Static/GameChallenges.test.ts b/src/Structures/Static/GameChallenges.test.ts new file mode 100644 index 000000000..784d219c0 --- /dev/null +++ b/src/Structures/Static/GameChallenges.test.ts @@ -0,0 +1,14 @@ +import Challenge from './Challenge.js'; +import GameChallenges from './GameChallenges.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameChallenges', () => { + const data = new GameChallenges('mrrp', [{ stats: 'meow' }]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameChallenges); + expectTypeOf(data).toEqualTypeOf(); + expect(data.category).toBeDefined(); + expectTypeOf(data.category).toEqualTypeOf(); + expect(data.challenges).toBeDefined(); + expectTypeOf(data.challenges).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameChallenges.ts b/src/Structures/Static/GameChallenges.ts new file mode 100644 index 000000000..f6dda8274 --- /dev/null +++ b/src/Structures/Static/GameChallenges.ts @@ -0,0 +1,12 @@ +import Challenge from './Challenge.js'; + +class GameChallenges { + category: string; + challenges: Challenge[]; + constructor(name: string, data: Record[]) { + this.category = name; + this.challenges = data.map((challenge) => new Challenge(challenge)); + } +} + +export default GameChallenges; diff --git a/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.test.ts b/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.test.ts new file mode 100644 index 000000000..f635ac3d9 --- /dev/null +++ b/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.test.ts @@ -0,0 +1,13 @@ +import GameCountsArcade from './GameCountsArcade.js'; +import GameCountsArcadeModes from './GameCountsArcadeModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsArcade', () => { + const data = new GameCountsArcade({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsArcade); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsArcadeModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.ts b/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.ts new file mode 100644 index 000000000..8a3303a3e --- /dev/null +++ b/src/Structures/Static/GameCounts/Arcade/GameCountsArcade.ts @@ -0,0 +1,12 @@ +import GameCountsArcadeModes from './GameCountsArcadeModes.ts'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsArcade extends GameCountsGeneric { + modes: GameCountsArcadeModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsArcadeModes(data?.modes); + } +} + +export default GameCountsArcade; diff --git a/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.test.ts b/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.test.ts new file mode 100644 index 000000000..943d855d3 --- /dev/null +++ b/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.test.ts @@ -0,0 +1,78 @@ +import GameCountsArcadeModes from './GameCountsArcadeModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsArcadeModes', () => { + const data = new GameCountsArcadeModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsArcadeModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.party).toBeDefined(); + expect(data.party).toBeGreaterThanOrEqual(0); + expectTypeOf(data.party).toEqualTypeOf(); + expect(data.holeInTheWall).toBeDefined(); + expect(data.holeInTheWall).toBeGreaterThanOrEqual(0); + expectTypeOf(data.holeInTheWall).toEqualTypeOf(); + expect(data.defender).toBeDefined(); + expect(data.defender).toBeGreaterThanOrEqual(0); + expectTypeOf(data.defender).toEqualTypeOf(); + expect(data.miniWalls).toBeDefined(); + expect(data.miniWalls).toBeGreaterThanOrEqual(0); + expectTypeOf(data.miniWalls).toEqualTypeOf(); + expect(data.simonSays).toBeDefined(); + expect(data.simonSays).toBeGreaterThanOrEqual(0); + expectTypeOf(data.simonSays).toEqualTypeOf(); + expect(data.zombiesBadBlood).toBeDefined(); + expect(data.zombiesBadBlood).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombiesBadBlood).toEqualTypeOf(); + expect(data.hideAndSeekPartyPooper).toBeDefined(); + expect(data.hideAndSeekPartyPooper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hideAndSeekPartyPooper).toEqualTypeOf(); + expect(data.dayOne).toBeDefined(); + expect(data.dayOne).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dayOne).toEqualTypeOf(); + expect(data.drawTheirThing).toBeDefined(); + expect(data.drawTheirThing).toBeGreaterThanOrEqual(0); + expectTypeOf(data.drawTheirThing).toEqualTypeOf(); + expect(data.zombiesAlianArcadium).toBeDefined(); + expect(data.zombiesAlianArcadium).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombiesAlianArcadium).toEqualTypeOf(); + expect(data.pixelParty).toBeDefined(); + expect(data.pixelParty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pixelParty).toEqualTypeOf(); + expect(data.oneInTheQuiver).toBeDefined(); + expect(data.oneInTheQuiver).toBeGreaterThanOrEqual(0); + expectTypeOf(data.oneInTheQuiver).toEqualTypeOf(); + expect(data.soccer).toBeDefined(); + expect(data.soccer).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soccer).toEqualTypeOf(); + expect(data.zombiesPrison).toBeDefined(); + expect(data.zombiesPrison).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombiesPrison).toEqualTypeOf(); + expect(data.ender).toBeDefined(); + expect(data.ender).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ender).toEqualTypeOf(); + expect(data.throwOut).toBeDefined(); + expect(data.throwOut).toBeGreaterThanOrEqual(0); + expectTypeOf(data.throwOut).toEqualTypeOf(); + expect(data.starWars).toBeDefined(); + expect(data.starWars).toBeGreaterThanOrEqual(0); + expectTypeOf(data.starWars).toEqualTypeOf(); + expect(data.dragonWars2).toBeDefined(); + expect(data.dragonWars2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dragonWars2).toEqualTypeOf(); + expect(data.dropper).toBeDefined(); + expect(data.dropper).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dropper).toEqualTypeOf(); + expect(data.zombiesDeadEnd).toBeDefined(); + expect(data.zombiesDeadEnd).toBeGreaterThanOrEqual(0); + expectTypeOf(data.zombiesDeadEnd).toEqualTypeOf(); + expect(data.disasters).toBeDefined(); + expect(data.disasters).toBeGreaterThanOrEqual(0); + expectTypeOf(data.disasters).toEqualTypeOf(); + expect(data.farmHunt).toBeDefined(); + expect(data.farmHunt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farmHunt).toEqualTypeOf(); + expect(data.hideAndSeekPropHunt).toBeDefined(); + expect(data.hideAndSeekPropHunt).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hideAndSeekPropHunt).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.ts b/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.ts new file mode 100644 index 000000000..f8f28fe44 --- /dev/null +++ b/src/Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.ts @@ -0,0 +1,52 @@ +class GameCountsArcadeModes { + party: number; + holeInTheWall: number; + defender: number; + miniWalls: number; + simonSays: number; + zombiesBadBlood: number; + hideAndSeekPartyPooper: number; + dayOne: number; + drawTheirThing: number; + zombiesAlianArcadium: number; + pixelParty: number; + oneInTheQuiver: number; + soccer: number; + zombiesPrison: number; + ender: number; + throwOut: number; + starWars: number; + dragonWars2: number; + dropper: number; + zombiesDeadEnd: number; + disasters: number; + farmHunt: number; + hideAndSeekPropHunt: number; + constructor(data: Record) { + this.party = data?.PARTY || 0; + this.holeInTheWall = data?.HOLE_IN_THE_WALL || 0; + this.defender = data?.DEFENDER || 0; + this.miniWalls = data?.MINI_WALLS || 0; + this.simonSays = data?.SIMON_SAYS || 0; + this.zombiesBadBlood = data?.ZOMBIES_BAD_BLOOD || 0; + this.hideAndSeekPartyPooper = data?.HIDE_AND_SEEK_PARTY_POOPER || 0; + this.dayOne = data?.DAYONE || 0; + this.drawTheirThing = data?.DRAW_THEIR_THING || 0; + this.zombiesAlianArcadium = data?.ZOMBIES_ALIEN_ARCADIUM || 0; + this.pixelParty = data?.PIXEL_PARTY || 0; + this.oneInTheQuiver = data?.ONEINTHEQUIVER || 0; + this.soccer = data?.SOCCER || 0; + this.zombiesPrison = data?.ZOMBIES_PRISON || 0; + this.ender = data?.ENDER || 0; + this.throwOut = data?.THROW_OUT || 0; + this.starWars = data?.STARWARS || 0; + this.dragonWars2 = data?.DRAGONWARS2 || 0; + this.dropper = data?.DROPPER || 0; + this.zombiesDeadEnd = data?.ZOMBIES_DEAD_END || 0; + this.disasters = data?.DISASTERS || 0; + this.farmHunt = data?.FARM_HUNT || 0; + this.hideAndSeekPropHunt = data?.HIDE_AND_SEEK_PROP_HUNT || 0; + } +} + +export default GameCountsArcadeModes; diff --git a/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.test.ts b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.test.ts new file mode 100644 index 000000000..42af9b0f7 --- /dev/null +++ b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.test.ts @@ -0,0 +1,13 @@ +import GameCountsBattleGround from './GameCountsBattleGround.js'; +import GameCountsBattleGroundModes from './GameCountsBattleGroundModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBattleGround', () => { + const data = new GameCountsBattleGround({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBattleGround); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsBattleGroundModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.ts b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.ts new file mode 100644 index 000000000..cd9bb9bde --- /dev/null +++ b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.ts @@ -0,0 +1,12 @@ +import GameCountsBattleGroundModes from './GameCountsBattleGroundModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsBattleGround extends GameCountsGeneric { + modes: GameCountsBattleGroundModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsBattleGroundModes(data?.modes); + } +} + +export default GameCountsBattleGround; diff --git a/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.test.ts b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.test.ts new file mode 100644 index 000000000..5aa21ff15 --- /dev/null +++ b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.test.ts @@ -0,0 +1,18 @@ +import GameCountsBattleGroundMods from './GameCountsBattleGroundModes.ts'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBattleGroundMods', () => { + const data = new GameCountsBattleGroundMods({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBattleGroundMods); + expectTypeOf(data).toEqualTypeOf(); + expect(data.ctfMini).toBeDefined(); + expect(data.ctfMini).toBeGreaterThanOrEqual(0); + expectTypeOf(data.ctfMini).toEqualTypeOf(); + expect(data.domination).toBeDefined(); + expect(data.domination).toBeGreaterThanOrEqual(0); + expectTypeOf(data.domination).toEqualTypeOf(); + expect(data.teamDeathmatch).toBeDefined(); + expect(data.teamDeathmatch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamDeathmatch).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.ts b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.ts new file mode 100644 index 000000000..eab4f4eda --- /dev/null +++ b/src/Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.ts @@ -0,0 +1,12 @@ +class GameCountsBattleGroundMods { + ctfMini: number; + domination: number; + teamDeathmatch: number; + constructor(data: Record) { + this.ctfMini = data?.ctf_mini || 0; + this.domination = data?.domination || 0; + this.teamDeathmatch = data?.team_deathmatch || 0; + } +} + +export default GameCountsBattleGroundMods; diff --git a/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.test.ts b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.test.ts new file mode 100644 index 000000000..813255180 --- /dev/null +++ b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.test.ts @@ -0,0 +1,13 @@ +import GameCountsBedWars from './GameCountsBedWars.js'; +import GameCountsGameCountsBedWarsModes from './GameCountsBedWarsModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBedWars', () => { + const data = new GameCountsBedWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBedWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsBedWarsModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.ts b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.ts new file mode 100644 index 000000000..521691a96 --- /dev/null +++ b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWars.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsBedWarsModes from './GameCountsBedWarsModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsBedWars extends GameCountsGeneric { + modes: GameCountsGameCountsBedWarsModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsBedWarsModes(data?.modes); + } +} + +export default GameCountsBedWars; diff --git a/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.test.ts b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.test.ts new file mode 100644 index 000000000..408d4c68f --- /dev/null +++ b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.test.ts @@ -0,0 +1,75 @@ +import GameCountsBedWarsModes from './GameCountsBedWarsModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBedWarsModes', () => { + const data = new GameCountsBedWarsModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBedWarsModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.twoFour).toBeDefined(); + expect(data.twoFour).toBeGreaterThanOrEqual(0); + expectTypeOf(data.twoFour).toEqualTypeOf(); + expect(data.fourFourRush).toBeDefined(); + expect(data.fourFourRush).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourRush).toEqualTypeOf(); + expect(data.eightOneOneBlock).toBeDefined(); + expect(data.eightOneOneBlock).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightOneOneBlock).toEqualTypeOf(); + expect(data.eightOne).toBeDefined(); + expect(data.eightOne).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightOne).toEqualTypeOf(); + expect(data.eightTwoRush).toBeDefined(); + expect(data.eightTwoRush).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoRush).toEqualTypeOf(); + expect(data.eightTwoVoidless).toBeDefined(); + expect(data.eightTwoVoidless).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoVoidless).toEqualTypeOf(); + expect(data.fourFourArmed).toBeDefined(); + expect(data.fourFourArmed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourArmed).toEqualTypeOf(); + expect(data.eightTwoArmed).toBeDefined(); + expect(data.eightTwoArmed).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoArmed).toEqualTypeOf(); + expect(data.eightTwoUnderworld).toBeDefined(); + expect(data.eightTwoUnderworld).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoUnderworld).toEqualTypeOf(); + expect(data.eightTwoSwap).toBeDefined(); + expect(data.eightTwoSwap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoSwap).toEqualTypeOf(); + expect(data.fourFourUnderworld).toBeDefined(); + expect(data.fourFourUnderworld).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourUnderworld).toEqualTypeOf(); + expect(data.eightTwo).toBeDefined(); + expect(data.eightTwo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwo).toEqualTypeOf(); + expect(data.fourFour).toBeDefined(); + expect(data.fourFour).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFour).toEqualTypeOf(); + expect(data.fourFourTultimate).toBeDefined(); + expect(data.fourFourTultimate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourTultimate).toEqualTypeOf(); + expect(data.practice).toBeDefined(); + expect(data.practice).toBeGreaterThanOrEqual(0); + expectTypeOf(data.practice).toEqualTypeOf(); + expect(data.eightTwoLuck).toBeDefined(); + expect(data.eightTwoLuck).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoLuck).toEqualTypeOf(); + expect(data.fourFourSwap).toBeDefined(); + expect(data.fourFourSwap).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourSwap).toEqualTypeOf(); + expect(data.fourFourVoidless).toBeDefined(); + expect(data.fourFourVoidless).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourVoidless).toEqualTypeOf(); + expect(data.fourThrww).toBeDefined(); + expect(data.fourThrww).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourThrww).toEqualTypeOf(); + expect(data.fourFourLucky).toBeDefined(); + expect(data.fourFourLucky).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fourFourLucky).toEqualTypeOf(); + expect(data.castle).toBeDefined(); + expect(data.castle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.castle).toEqualTypeOf(); + expect(data.eightTwoUltimate).toBeDefined(); + expect(data.eightTwoUltimate).toBeGreaterThanOrEqual(0); + expectTypeOf(data.eightTwoUltimate).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.ts b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.ts new file mode 100644 index 000000000..000a4aa8a --- /dev/null +++ b/src/Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.ts @@ -0,0 +1,50 @@ +class GameCountsBedWarsModes { + twoFour: number; + fourFourRush: number; + eightOneOneBlock: number; + eightOne: number; + eightTwoRush: number; + eightTwoVoidless: number; + fourFourArmed: number; + eightTwoArmed: number; + eightTwoUnderworld: number; + eightTwoSwap: number; + fourFourUnderworld: number; + eightTwo: number; + fourFour: number; + fourFourTultimate: number; + practice: number; + eightTwoLuck: number; + fourFourSwap: number; + fourFourVoidless: number; + fourThrww: number; + fourFourLucky: number; + castle: number; + eightTwoUltimate: number; + constructor(data: Record) { + this.twoFour = data?.BEDWARS_TWO_FOUR || 0; + this.fourFourRush = data?.BEDWARS_FOUR_FOUR_RUSH || 0; + this.eightOneOneBlock = data?.BEDWARS_EIGHT_ONE_ONEBLOCK || 0; + this.eightOne = data?.BEDWARS_EIGHT_ONE || 0; + this.eightTwoRush = data?.BEDWARS_EIGHT_TWO_RUSH || 0; + this.eightTwoVoidless = data?.BEDWARS_EIGHT_TWO_VOIDLESS || 0; + this.fourFourArmed = data?.BEDWARS_FOUR_FOUR_ARMED || 0; + this.eightTwoArmed = data?.BEDWARS_EIGHT_TWO_ARMED || 0; + this.eightTwoUnderworld = data?.BEDWARS_EIGHT_TWO_UNDERWORLD || 0; + this.eightTwoSwap = data?.BEDWARS_EIGHT_TWO_SWAP || 0; + this.fourFourUnderworld = data?.BEDWARS_FOUR_FOUR_UNDERWORLD || 0; + this.eightTwo = data?.BEDWARS_EIGHT_TWO || 0; + this.fourFour = data?.BEDWARS_FOUR_FOUR || 0; + this.fourFourTultimate = data?.BEDWARS_FOUR_FOUR_ULTIMATE || 0; + this.practice = data?.BEDWARS_PRACTICE || 0; + this.eightTwoLuck = data?.BEDWARS_EIGHT_TWO_LUCKY || 0; + this.fourFourSwap = data?.BEDWARS_FOUR_FOUR_SWAP || 0; + this.fourFourVoidless = data?.BEDWARS_FOUR_FOUR_VOIDLESS || 0; + this.fourThrww = data?.BEDWARS_FOUR_THREE || 0; + this.fourFourLucky = data?.BEDWARS_FOUR_FOUR_LUCKY || 0; + this.castle = data?.BEDWARS_CASTLE || 0; + this.eightTwoUltimate = data?.BEDWARS_EIGHT_TWO_ULTIMATE || 0; + } +} + +export default GameCountsBedWarsModes; diff --git a/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.test.ts b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.test.ts new file mode 100644 index 000000000..683f31b31 --- /dev/null +++ b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.test.ts @@ -0,0 +1,13 @@ +import GameCountsBuildBattle from './GameCountsBuildBattle.js'; +import GameCountsGameCountsBuildBattleModes from './GameCountsBuildBattleModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBuildBattle', () => { + const data = new GameCountsBuildBattle({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBuildBattle); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsBuildBattleModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.ts b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.ts new file mode 100644 index 000000000..ecda29ce7 --- /dev/null +++ b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsBuildBattleModes from './GameCountsBuildBattleModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsBuildBattle extends GameCountsGeneric { + modes: GameCountsGameCountsBuildBattleModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsBuildBattleModes(data?.modes); + } +} + +export default GameCountsBuildBattle; diff --git a/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.test.ts b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.test.ts new file mode 100644 index 000000000..2c78005e9 --- /dev/null +++ b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.test.ts @@ -0,0 +1,27 @@ +import GameCountsBuildBattleModes from './GameCountsBuildBattleModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBuildBattleModes', () => { + const data = new GameCountsBuildBattleModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBuildBattleModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.soloNormalLatest).toBeDefined(); + expect(data.soloNormalLatest).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloNormalLatest).toEqualTypeOf(); + expect(data.speedBuilders).toBeDefined(); + expect(data.speedBuilders).toBeGreaterThanOrEqual(0); + expectTypeOf(data.speedBuilders).toEqualTypeOf(); + expect(data.guessTheBuild).toBeDefined(); + expect(data.guessTheBuild).toBeGreaterThanOrEqual(0); + expectTypeOf(data.guessTheBuild).toEqualTypeOf(); + expect(data.teamsNormal).toBeDefined(); + expect(data.teamsNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsNormal).toEqualTypeOf(); + expect(data.soloPro).toBeDefined(); + expect(data.soloPro).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloPro).toEqualTypeOf(); + expect(data.soloNormal).toBeDefined(); + expect(data.soloNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloNormal).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.ts b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.ts new file mode 100644 index 000000000..c343afbe1 --- /dev/null +++ b/src/Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.ts @@ -0,0 +1,18 @@ +class GameCountsBuildBattleModes { + soloNormalLatest: number; + speedBuilders: number; + guessTheBuild: number; + teamsNormal: number; + soloPro: number; + soloNormal: number; + constructor(data: Record) { + this.soloNormalLatest = data?.BUILD_BATTLE_SOLO_NORMAL_LATEST || 0; + this.speedBuilders = data?.BUILD_BATTLE_SPEED_BUILDERS || 0; + this.guessTheBuild = data?.BUILD_BATTLE_GUESS_THE_BUILD || 0; + this.teamsNormal = data?.BUILD_BATTLE_TEAMS_NORMAL || 0; + this.soloPro = data?.BUILD_BATTLE_SOLO_PRO || 0; + this.soloNormal = data?.BUILD_BATTLE_SOLO_NORMAL || 0; + } +} + +export default GameCountsBuildBattleModes; diff --git a/src/Structures/Static/GameCounts/Duels/GameCountsDuels.test.ts b/src/Structures/Static/GameCounts/Duels/GameCountsDuels.test.ts new file mode 100644 index 000000000..d197bc7fd --- /dev/null +++ b/src/Structures/Static/GameCounts/Duels/GameCountsDuels.test.ts @@ -0,0 +1,13 @@ +import GaemCountsDuels from './GameCountsDuels.ts'; +import GameCountsGameCountsDuelsModes from './GameCountsDuelsModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GaemCountsDuels', () => { + const data = new GaemCountsDuels({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GaemCountsDuels); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsDuelsModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Duels/GameCountsDuels.ts b/src/Structures/Static/GameCounts/Duels/GameCountsDuels.ts new file mode 100644 index 000000000..db11f662a --- /dev/null +++ b/src/Structures/Static/GameCounts/Duels/GameCountsDuels.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsDuelsModes from './GameCountsDuelsModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GaemCountsDuels extends GameCountsGeneric { + modes: GameCountsGameCountsDuelsModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsDuelsModes(data?.modes); + } +} + +export default GaemCountsDuels; diff --git a/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.test.ts b/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.test.ts new file mode 100644 index 000000000..5d2e37647 --- /dev/null +++ b/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.test.ts @@ -0,0 +1,93 @@ +import GameCountsDuelsModes from './GameCountsDuelsModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsDuelsModes', () => { + const data = new GameCountsDuelsModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsDuelsModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.bowSpleefDuel).toBeDefined(); + expect(data.bowSpleefDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowSpleefDuel).toEqualTypeOf(); + expect(data.bowDuel).toBeDefined(); + expect(data.bowDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowDuel).toEqualTypeOf(); + expect(data.megaWallsDuel).toBeDefined(); + expect(data.megaWallsDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.megaWallsDuel).toEqualTypeOf(); + expect(data.UHCFour).toBeDefined(); + expect(data.UHCFour).toBeGreaterThanOrEqual(0); + expectTypeOf(data.UHCFour).toEqualTypeOf(); + expect(data.UHCMeetup).toBeDefined(); + expect(data.UHCMeetup).toBeGreaterThanOrEqual(0); + expectTypeOf(data.UHCMeetup).toEqualTypeOf(); + expect(data.quakeDuel).toBeDefined(); + expect(data.quakeDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quakeDuel).toEqualTypeOf(); + expect(data.skyWarsDoubles).toBeDefined(); + expect(data.skyWarsDoubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skyWarsDoubles).toEqualTypeOf(); + expect(data.UHCDoubles).toBeDefined(); + expect(data.UHCDoubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.UHCDoubles).toEqualTypeOf(); + expect(data.bridgeFour).toBeDefined(); + expect(data.bridgeFour).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bridgeFour).toEqualTypeOf(); + expect(data.duelsSumoDuel).toBeDefined(); + expect(data.duelsSumoDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.duelsSumoDuel).toEqualTypeOf(); + expect(data.bridgeThrees).toBeDefined(); + expect(data.bridgeThrees).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bridgeThrees).toEqualTypeOf(); + expect(data.twoOneDuels).toBeDefined(); + expect(data.twoOneDuels).toBeGreaterThanOrEqual(0); + expectTypeOf(data.twoOneDuels).toEqualTypeOf(); + expect(data.opDuel).toBeDefined(); + expect(data.opDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.opDuel).toEqualTypeOf(); + expect(data.duelsArena).toBeDefined(); + expect(data.duelsArena).toBeGreaterThanOrEqual(0); + expectTypeOf(data.duelsArena).toEqualTypeOf(); + expect(data.twoOneRust).toBeDefined(); + expect(data.twoOneRust).toBeGreaterThanOrEqual(0); + expectTypeOf(data.twoOneRust).toEqualTypeOf(); + expect(data.comboDuel).toBeDefined(); + expect(data.comboDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.comboDuel).toEqualTypeOf(); + expect(data.bridgeDoubles).toBeDefined(); + expect(data.bridgeDoubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bridgeDoubles).toEqualTypeOf(); + expect(data.boxingDuel).toBeDefined(); + expect(data.boxingDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.boxingDuel).toEqualTypeOf(); + expect(data.UHCDuel).toBeDefined(); + expect(data.UHCDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.UHCDuel).toEqualTypeOf(); + expect(data.classicDoubles).toBeDefined(); + expect(data.classicDoubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.classicDoubles).toEqualTypeOf(); + expect(data.spleefDuel).toBeDefined(); + expect(data.spleefDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.spleefDuel).toEqualTypeOf(); + expect(data.opDuels).toBeDefined(); + expect(data.opDuels).toBeGreaterThanOrEqual(0); + expectTypeOf(data.opDuels).toEqualTypeOf(); + expect(data.parkourEight).toBeDefined(); + expect(data.parkourEight).toBeGreaterThanOrEqual(0); + expectTypeOf(data.parkourEight).toEqualTypeOf(); + expect(data.blitzDuel).toBeDefined(); + expect(data.blitzDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.blitzDuel).toEqualTypeOf(); + expect(data.classicDuel).toBeDefined(); + expect(data.classicDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.classicDuel).toEqualTypeOf(); + expect(data.pottionDuel).toBeDefined(); + expect(data.pottionDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.pottionDuel).toEqualTypeOf(); + expect(data.bridgeDuel).toBeDefined(); + expect(data.bridgeDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bridgeDuel).toEqualTypeOf(); + expect(data.skyWarsDuel).toBeDefined(); + expect(data.skyWarsDuel).toBeGreaterThanOrEqual(0); + expectTypeOf(data.skyWarsDuel).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.ts b/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.ts new file mode 100644 index 000000000..bc59d3acb --- /dev/null +++ b/src/Structures/Static/GameCounts/Duels/GameCountsDuelsModes.ts @@ -0,0 +1,62 @@ +class GameCountsDuelsModes { + bowSpleefDuel: number; + bowDuel: number; + megaWallsDuel: number; + UHCFour: number; + UHCMeetup: number; + quakeDuel: number; + skyWarsDoubles: number; + UHCDoubles: number; + bridgeFour: number; + duelsSumoDuel: number; + bridgeThrees: number; + twoOneDuels: number; + opDuel: number; + duelsArena: number; + twoOneRust: number; + comboDuel: number; + bridgeDoubles: number; + boxingDuel: number; + UHCDuel: number; + classicDoubles: number; + spleefDuel: number; + opDuels: number; + parkourEight: number; + blitzDuel: number; + classicDuel: number; + pottionDuel: number; + bridgeDuel: number; + skyWarsDuel: number; + constructor(data: Record) { + this.bowSpleefDuel = data?.DUELS_BOWSPLEEF_DUEL || 0; + this.bowDuel = data?.DUELS_BOW_DUEL || 0; + this.megaWallsDuel = data?.DUELS_MW_DUEL || 0; + this.UHCFour = data?.DUELS_UHC_FOUR || 0; + this.UHCMeetup = data?.DUELS_UHC_MEETUP || 0; + this.quakeDuel = data?.DUELS_QUAKE_DUEL || 0; + this.skyWarsDoubles = data?.DUELS_SW_DOUBLES || 0; + this.UHCDoubles = data?.DUELS_UHC_DOUBLES || 0; + this.bridgeFour = data?.DUELS_BRIDGE_FOUR || 0; + this.duelsSumoDuel = data?.DUELS_SUMO_DUEL || 0; + this.bridgeThrees = data?.DUELS_BRIDGE_THREES || 0; + this.twoOneDuels = data?.BEDWARS_TWO_ONE_DUELS || 0; + this.opDuel = data?.DUELS_OP_DUEL || 0; + this.duelsArena = data?.DUELS_DUEL_ARENA || 0; + this.twoOneRust = data?.BEDWARS_TWO_ONE_DUELS_RUSH || 0; + this.comboDuel = data?.DUELS_COMBO_DUEL || 0; + this.bridgeDoubles = data?.DUELS_BRIDGE_DOUBLES || 0; + this.boxingDuel = data?.DUELS_BOXING_DUEL || 0; + this.UHCDuel = data?.DUELS_UHC_DUEL || 0; + this.classicDoubles = data?.DUELS_CLASSIC_DOUBLES || 0; + this.spleefDuel = data?.DUELS_SPLEEF_DUEL || 0; + this.opDuels = data?.DUELS_OP_DOUBLES || 0; + this.parkourEight = data?.DUELS_PARKOUR_EIGHT || 0; + this.blitzDuel = data?.DUELS_BLITZ_DUEL || 0; + this.classicDuel = data?.DUELS_CLASSIC_DUEL || 0; + this.pottionDuel = data?.DUELS_POTION_DUEL || 0; + this.bridgeDuel = data?.DUELS_BRIDGE_DUEL || 0; + this.skyWarsDuel = data?.DUELS_SW_DUEL || 0; + } +} + +export default GameCountsDuelsModes; diff --git a/src/Structures/Static/GameCounts/GameCounts.test.ts b/src/Structures/Static/GameCounts/GameCounts.test.ts new file mode 100644 index 000000000..c8e010098 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCounts.test.ts @@ -0,0 +1,21 @@ +import GameCountGames from './GameCountsGames.js'; +import GameCounts from './GameCounts.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCounts', () => { + const data = new GameCounts({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCounts); + expectTypeOf(data).toEqualTypeOf(); + expect(data.playerCount).toBeDefined(); + expect(data.playerCount).toBeGreaterThanOrEqual(0); + expectTypeOf(data.playerCount).toEqualTypeOf(); + expect(data.games).toBeDefined(); + expect(data.games).toBeInstanceOf(GameCountGames); + expectTypeOf(data.games).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => number>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.playerCount); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/GameCounts.ts b/src/Structures/Static/GameCounts/GameCounts.ts new file mode 100644 index 000000000..926e70804 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCounts.ts @@ -0,0 +1,21 @@ +import GameCountGames from './GameCountsGames.ts'; +import type RequestData from '../../../Private/RequestData.ts'; + +class GameCounts { + playerCount: number; + games: GameCountGames; + constructor(data: Record) { + this.playerCount = data?.playerCount || 0; + this.games = new GameCountGames(data.games); + } + + toString(): number { + return this.playerCount; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default GameCounts; diff --git a/src/Structures/Static/GameCounts/GameCountsBasicModes.test.ts b/src/Structures/Static/GameCounts/GameCountsBasicModes.test.ts new file mode 100644 index 000000000..5ac0b5e16 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsBasicModes.test.ts @@ -0,0 +1,15 @@ +import GameCountsBasicModes from './GameCountsBasicModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsBasicModes', () => { + const data = new GameCountsBasicModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsBasicModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.soloNormal).toBeDefined(); + expect(data.soloNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloNormal).toEqualTypeOf(); + expect(data.teamNormal).toBeDefined(); + expect(data.teamNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamNormal).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/GameCountsBasicModes.ts b/src/Structures/Static/GameCounts/GameCountsBasicModes.ts new file mode 100644 index 000000000..4724edeed --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsBasicModes.ts @@ -0,0 +1,10 @@ +class GameCountsBasicModes { + soloNormal: number; + teamNormal: number; + constructor(data: Record) { + this.soloNormal = data?.solo_normal || 0; + this.teamNormal = data?.team_normal || 0; + } +} + +export default GameCountsBasicModes; diff --git a/src/Structures/Static/GameCounts/GameCountsGames.test.ts b/src/Structures/Static/GameCounts/GameCountsGames.test.ts new file mode 100644 index 000000000..42aa97786 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsGames.test.ts @@ -0,0 +1,110 @@ +import GaemCountsDuels from './Duels/GameCountsDuels.js'; +import GameCountGames from './GameCountsGames.ts'; +import GameCountsArcade from './Arcade/GameCountsArcade.js'; +import GameCountsBattleGround from './BattleGround/GameCountsBattleGround.js'; +import GameCountsBedWars from './BedWars/GameCountsBedWars.js'; +import GameCountsBuildBattle from './BuildBattle/GameCountsBuildBattle.js'; +import GameCountsGeneric from './GameCountsGeneric.js'; +import GameCountsLegacy from './Legacy/GameCountsLegacy.js'; +import GameCountsMCGO from './MCGO/GameCountsMCGO.js'; +import GameCountsMurderMystery from './MurderMystery/GameCountsMurderMystery.js'; +import GameCountsPit from './Pit/GameCountsPit.js'; +import GameCountsReplay from './Replay/GameCountsReplay.js'; +import GameCountsSkyBlock from './SkyBlock/GameCountsSkyBlock.js'; +import GameCountsSkyWars from './SkyWars/GameCountsSkyWars.js'; +import GameCountsSpeedUHC from './SpeedUHC/GameCountsSpeedUHC.js'; +import GameCountsSuperSmash from './SuperSmash/GameCountsSuperSmash.js'; +import GameCountsSurvivalGames from './SurvivalGames/GameCountsSurvivalGames.js'; +import GameCountsTNTGames from './TNTGames/GameCountsTNTGames.js'; +import GameCountsWoolGames from './WoolGames/GameCountsWoolGames.js'; +import UHC from './UHC/GameCountsUHC.js'; +import Walls3 from './Walls3/GameCountsWalls3.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountGames', () => { + const data = new GameCountGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.mainLobby).toBeDefined(); + expect(data.mainLobby).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.mainLobby).toEqualTypeOf(); + expect(data.tournamentLobby).toBeDefined(); + expect(data.tournamentLobby).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.tournamentLobby).toEqualTypeOf(); + expect(data.smp).toBeDefined(); + expect(data.smp).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.smp).toEqualTypeOf(); + expect(data.legacy).toBeDefined(); + expect(data.legacy).toBeInstanceOf(GameCountsLegacy); + expectTypeOf(data.legacy).toEqualTypeOf(); + expect(data.SkyBlock).toBeDefined(); + expect(data.SkyBlock).toBeInstanceOf(GameCountsSkyBlock); + expectTypeOf(data.SkyBlock).toEqualTypeOf(); + expect(data.UHC).toBeDefined(); + expect(data.UHC).toBeInstanceOf(UHC); + expectTypeOf(data.UHC).toEqualTypeOf(); + expect(data.skywars).toBeDefined(); + expect(data.skywars).toBeInstanceOf(GameCountsSkyWars); + expectTypeOf(data.skywars).toEqualTypeOf(); + expect(data.replay).toBeDefined(); + expect(data.replay).toBeInstanceOf(GameCountsReplay); + expectTypeOf(data.replay).toEqualTypeOf(); + expect(data.speedUHC).toBeDefined(); + expect(data.speedUHC).toBeInstanceOf(GameCountsSpeedUHC); + expectTypeOf(data.speedUHC).toEqualTypeOf(); + expect(data.arcade).toBeDefined(); + expect(data.arcade).toBeInstanceOf(GameCountsArcade); + expectTypeOf(data.arcade).toEqualTypeOf(); + expect(data.housing).toBeDefined(); + expect(data.housing).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.housing).toEqualTypeOf(); + expect(data.battleGround).toBeDefined(); + expect(data.battleGround).toBeInstanceOf(GameCountsBattleGround); + expectTypeOf(data.battleGround).toEqualTypeOf(); + expect(data.superSmash).toBeDefined(); + expect(data.superSmash).toBeInstanceOf(GameCountsSuperSmash); + expectTypeOf(data.superSmash).toEqualTypeOf(); + expect(data.bedwars).toBeDefined(); + expect(data.bedwars).toBeInstanceOf(GameCountsBedWars); + expectTypeOf(data.bedwars).toEqualTypeOf(); + expect(data.duels).toBeDefined(); + expect(data.duels).toBeInstanceOf(GaemCountsDuels); + expectTypeOf(data.duels).toEqualTypeOf(); + expect(data.walls3).toBeDefined(); + expect(data.walls3).toBeInstanceOf(Walls3); + expectTypeOf(data.walls3).toEqualTypeOf(); + expect(data.murderMystery).toBeDefined(); + expect(data.murderMystery).toBeInstanceOf(GameCountsMurderMystery); + expectTypeOf(data.murderMystery).toEqualTypeOf(); + expect(data.survivalGames).toBeDefined(); + expect(data.survivalGames).toBeInstanceOf(GameCountsSurvivalGames); + expectTypeOf(data.survivalGames).toEqualTypeOf(); + expect(data.buildBattle).toBeDefined(); + expect(data.buildBattle).toBeInstanceOf(GameCountsBuildBattle); + expectTypeOf(data.buildBattle).toEqualTypeOf(); + expect(data.pit).toBeDefined(); + expect(data.pit).toBeInstanceOf(GameCountsPit); + expectTypeOf(data.pit).toEqualTypeOf(); + expect(data.woolGames).toBeDefined(); + expect(data.woolGames).toBeInstanceOf(GameCountsWoolGames); + expectTypeOf(data.woolGames).toEqualTypeOf(); + expect(data.tntGames).toBeDefined(); + expect(data.tntGames).toBeInstanceOf(GameCountsTNTGames); + expectTypeOf(data.tntGames).toEqualTypeOf(); + expect(data.MCGO).toBeDefined(); + expect(data.MCGO).toBeInstanceOf(GameCountsMCGO); + expectTypeOf(data.MCGO).toEqualTypeOf(); + expect(data.prototype).toBeDefined(); + expect(data.prototype).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.prototype).toEqualTypeOf(); + expect(data.limbo).toBeDefined(); + expect(data.limbo).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.limbo).toEqualTypeOf(); + expect(data.idle).toBeDefined(); + expect(data.idle).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.idle).toEqualTypeOf(); + expect(data.queue).toBeDefined(); + expect(data.queue).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data.queue).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/GameCountsGames.ts b/src/Structures/Static/GameCounts/GameCountsGames.ts new file mode 100644 index 000000000..b0707c396 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsGames.ts @@ -0,0 +1,81 @@ +import GaemCountsDuels from './Duels/GameCountsDuels.js'; +import GameCountsArcade from './Arcade/GameCountsArcade.js'; +import GameCountsBattleGround from './BattleGround/GameCountsBattleGround.js'; +import GameCountsBedWars from './BedWars/GameCountsBedWars.js'; +import GameCountsBuildBattle from './BuildBattle/GameCountsBuildBattle.js'; +import GameCountsGeneric from './GameCountsGeneric.ts'; +import GameCountsLegacy from './Legacy/GameCountsLegacy.js'; +import GameCountsMCGO from './MCGO/GameCountsMCGO.js'; +import GameCountsMurderMystery from './MurderMystery/GameCountsMurderMystery.js'; +import GameCountsPit from './Pit/GameCountsPit.js'; +import GameCountsReplay from './Replay/GameCountsReplay.js'; +import GameCountsSkyBlock from './SkyBlock/GameCountsSkyBlock.js'; +import GameCountsSkyWars from './SkyWars/GameCountsSkyWars.js'; +import GameCountsSpeedUHC from './SpeedUHC/GameCountsSpeedUHC.js'; +import GameCountsSuperSmash from './SuperSmash/GameCountsSuperSmash.js'; +import GameCountsSurvivalGames from './SurvivalGames/GameCountsSurvivalGames.js'; +import GameCountsTNTGames from './TNTGames/GameCountsTNTGames.js'; +import GameCountsWoolGames from './WoolGames/GameCountsWoolGames.js'; +import UHC from './UHC/GameCountsUHC.js'; +import Walls3 from './Walls3/GameCountsWalls3.js'; + +class GameCountGames { + mainLobby: GameCountsGeneric; + tournamentLobby: GameCountsGeneric; + smp: GameCountsGeneric; + legacy: GameCountsLegacy; + SkyBlock: GameCountsSkyBlock; + UHC: UHC; + skywars: GameCountsSkyWars; + replay: GameCountsReplay; + speedUHC: GameCountsSpeedUHC; + arcade: GameCountsArcade; + housing: GameCountsGeneric; + battleGround: GameCountsBattleGround; + superSmash: GameCountsSuperSmash; + bedwars: GameCountsBedWars; + duels: GaemCountsDuels; + walls3: Walls3; + murderMystery: GameCountsMurderMystery; + survivalGames: GameCountsSurvivalGames; + buildBattle: GameCountsBuildBattle; + pit: GameCountsPit; + woolGames: GameCountsWoolGames; + tntGames: GameCountsTNTGames; + MCGO: GameCountsMCGO; + prototype: GameCountsGeneric; + limbo: GameCountsGeneric; + idle: GameCountsGeneric; + queue: GameCountsGeneric; + constructor(data: Record) { + this.mainLobby = new GameCountsGeneric(data?.MAIN_LOBBY); + this.tournamentLobby = new GameCountsGeneric(data?.TOURNAMENT_LOBBY); + this.smp = new GameCountsGeneric(data?.SMP); + this.legacy = new GameCountsLegacy(data?.LEGACY); + this.SkyBlock = new GameCountsSkyBlock(data?.SKYBLOCK); + this.UHC = new UHC(data?.UHC); + this.skywars = new GameCountsSkyWars(data?.SKYWARS); + this.replay = new GameCountsReplay(data?.REPLAY); + this.speedUHC = new GameCountsSpeedUHC(data?.SPEED_UHC); + this.arcade = new GameCountsArcade(data?.ARCADE); + this.housing = new GameCountsGeneric(data?.HOUSING); + this.battleGround = new GameCountsBattleGround(data?.BATTLEGROUND); + this.superSmash = new GameCountsSuperSmash(data?.SUPER_SMASH); + this.bedwars = new GameCountsBedWars(data?.BEDWARS); + this.duels = new GaemCountsDuels(data?.DUELS); + this.walls3 = new Walls3(data?.WALLS3); + this.murderMystery = new GameCountsMurderMystery(data?.MURDER_MYSTERY); + this.survivalGames = new GameCountsSurvivalGames(data?.SURVIVAL_GAMES); + this.buildBattle = new GameCountsBuildBattle(data?.BUILD_BATTLE); + this.pit = new GameCountsPit(data?.PIT); + this.woolGames = new GameCountsWoolGames(data?.WOOL_GAMES); + this.tntGames = new GameCountsTNTGames(data?.TNTGAMES); + this.MCGO = new GameCountsMCGO(data?.MCGO); + this.prototype = new GameCountsGeneric(data?.PROTOTYPE); + this.limbo = new GameCountsGeneric(data?.LIMBO); + this.idle = new GameCountsGeneric(data?.IDLE); + this.queue = new GameCountsGeneric(data?.QUEUE); + } +} + +export default GameCountGames; diff --git a/src/Structures/Static/GameCounts/GameCountsGeneric.test.ts b/src/Structures/Static/GameCounts/GameCountsGeneric.test.ts new file mode 100644 index 000000000..a9e9a12c8 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsGeneric.test.ts @@ -0,0 +1,12 @@ +import GameCountsGeneric from './GameCountsGeneric.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsGeneric', () => { + const data = new GameCountsGeneric({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsGeneric); + expectTypeOf(data).toEqualTypeOf(); + expect(data.players).toBeDefined(); + expect(data.players).toBeGreaterThanOrEqual(0); + expectTypeOf(data.players).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/GameCountsGeneric.ts b/src/Structures/Static/GameCounts/GameCountsGeneric.ts new file mode 100644 index 000000000..d82f6b8b6 --- /dev/null +++ b/src/Structures/Static/GameCounts/GameCountsGeneric.ts @@ -0,0 +1,8 @@ +class GameCountsGeneric { + players: number; + constructor(data: Record) { + this.players = data?.players || 0; + } +} + +export default GameCountsGeneric; diff --git a/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.test.ts b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.test.ts new file mode 100644 index 000000000..395041100 --- /dev/null +++ b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsLegacyModes from './GameCountsLegacyModes.js'; +import GameCountsLegacy from './GameCountsLegacy.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsLegacy', () => { + const data = new GameCountsLegacy({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsLegacy); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsLegacyModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.ts b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.ts new file mode 100644 index 000000000..39c2e220e --- /dev/null +++ b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacy.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsLegacyModes from './GameCountsLegacyModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsLegacy extends GameCountsGeneric { + modes: GameCountsGameCountsLegacyModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsLegacyModes(data?.modes); + } +} + +export default GameCountsLegacy; diff --git a/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.test.ts b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.test.ts new file mode 100644 index 000000000..58c504db4 --- /dev/null +++ b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.test.ts @@ -0,0 +1,27 @@ +import GameCountsLegacyModes from './GameCountsLegacyModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsLegacyModes', () => { + const data = new GameCountsLegacyModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsLegacyModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.vampireZ).toBeDefined(); + expect(data.vampireZ).toBeGreaterThanOrEqual(0); + expectTypeOf(data.vampireZ).toEqualTypeOf(); + expect(data.walls).toBeDefined(); + expect(data.walls).toBeGreaterThanOrEqual(0); + expectTypeOf(data.walls).toEqualTypeOf(); + expect(data.quakecraft).toBeDefined(); + expect(data.quakecraft).toBeGreaterThanOrEqual(0); + expectTypeOf(data.quakecraft).toEqualTypeOf(); + expect(data.gingerbread).toBeDefined(); + expect(data.gingerbread).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gingerbread).toEqualTypeOf(); + expect(data.paintball).toBeDefined(); + expect(data.paintball).toBeGreaterThanOrEqual(0); + expectTypeOf(data.paintball).toEqualTypeOf(); + expect(data.arena).toBeDefined(); + expect(data.arena).toBeGreaterThanOrEqual(0); + expectTypeOf(data.arena).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.ts b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.ts new file mode 100644 index 000000000..3c1f36982 --- /dev/null +++ b/src/Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.ts @@ -0,0 +1,18 @@ +class GameCountsLegacyModes { + vampireZ: number; + walls: number; + quakecraft: number; + gingerbread: number; + paintball: number; + arena: number; + constructor(data: Record) { + this.vampireZ = data?.VAMPIREZ || 0; + this.walls = data?.WALLS || 0; + this.quakecraft = data?.QUAKECRAFT || 0; + this.gingerbread = data?.GINGERBREAD || 0; + this.paintball = data?.PAINTBALL || 0; + this.arena = data?.ARENA || 0; + } +} + +export default GameCountsLegacyModes; diff --git a/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.test.ts b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.test.ts new file mode 100644 index 000000000..aed4fff51 --- /dev/null +++ b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsMCGOModes from './GameCountsMCGOModes.js'; +import GameCountsMCGO from './GameCountsMCGO.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsMCGO', () => { + const data = new GameCountsMCGO({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsMCGO); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsMCGOModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.ts b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.ts new file mode 100644 index 000000000..955efbb05 --- /dev/null +++ b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGO.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsMCGOModes from './GameCountsMCGOModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsMCGO extends GameCountsGeneric { + modes: GameCountsGameCountsMCGOModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsMCGOModes(data?.modes); + } +} + +export default GameCountsMCGO; diff --git a/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.test.ts b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.test.ts new file mode 100644 index 000000000..9e073c8b8 --- /dev/null +++ b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.test.ts @@ -0,0 +1,18 @@ +import GameCountsMCGOModes from './GameCountsMCGOModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsMCGOModes', () => { + const data = new GameCountsMCGOModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsMCGOModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.normal).toBeDefined(); + expect(data.normal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.normal).toEqualTypeOf(); + expect(data.gungame).toBeDefined(); + expect(data.gungame).toBeGreaterThanOrEqual(0); + expectTypeOf(data.gungame).toEqualTypeOf(); + expect(data.deathmatch).toBeDefined(); + expect(data.deathmatch).toBeGreaterThanOrEqual(0); + expectTypeOf(data.deathmatch).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.ts b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.ts new file mode 100644 index 000000000..4e5c96d77 --- /dev/null +++ b/src/Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.ts @@ -0,0 +1,12 @@ +class GameCountsMCGOModes { + normal: number; + gungame: number; + deathmatch: number; + constructor(data: Record) { + this.normal = data?.normal || 0; + this.gungame = data?.gungame || 0; + this.deathmatch = data?.deathmatch || 0; + } +} + +export default GameCountsMCGOModes; diff --git a/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.test.ts b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.test.ts new file mode 100644 index 000000000..97f0493df --- /dev/null +++ b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsMurderMysteryModes from './GameCountsMurderMysteryModes.js'; +import GameCountsMurderMystery from './GameCountsMurderMystery.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsMurderMystery', () => { + const data = new GameCountsMurderMystery({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsMurderMystery); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsMurderMysteryModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.ts b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.ts new file mode 100644 index 000000000..402d0e737 --- /dev/null +++ b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsMurderMysteryModes from './GameCountsMurderMysteryModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsMurderMystery extends GameCountsGeneric { + modes: GameCountsGameCountsMurderMysteryModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsMurderMysteryModes(data?.modes); + } +} + +export default GameCountsMurderMystery; diff --git a/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.test.ts b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.test.ts new file mode 100644 index 000000000..38e247902 --- /dev/null +++ b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.test.ts @@ -0,0 +1,21 @@ +import GameCountsMurderMysteryModes from './GameCountsMurderMysteryModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsMurderMysteryModes', () => { + const data = new GameCountsMurderMysteryModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsMurderMysteryModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.doubleUp).toBeDefined(); + expect(data.doubleUp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.doubleUp).toEqualTypeOf(); + expect(data.infection).toBeDefined(); + expect(data.infection).toBeGreaterThanOrEqual(0); + expectTypeOf(data.infection).toEqualTypeOf(); + expect(data.assassins).toBeDefined(); + expect(data.assassins).toBeGreaterThanOrEqual(0); + expectTypeOf(data.assassins).toEqualTypeOf(); + expect(data.classic).toBeDefined(); + expect(data.classic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.classic).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.ts b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.ts new file mode 100644 index 000000000..520ab2ee2 --- /dev/null +++ b/src/Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.ts @@ -0,0 +1,14 @@ +class GameCountsMurderMysteryModes { + doubleUp: number; + infection: number; + assassins: number; + classic: number; + constructor(data: Record) { + this.doubleUp = data?.MURDER_DOUBLE_UP || 0; + this.infection = data?.MURDER_INFECTION || 0; + this.assassins = data?.MURDER_ASSASSINS || 0; + this.classic = data?.MURDER_CLASSIC || 0; + } +} + +export default GameCountsMurderMysteryModes; diff --git a/src/Structures/Static/GameCounts/Pit/GameCountsPit.test.ts b/src/Structures/Static/GameCounts/Pit/GameCountsPit.test.ts new file mode 100644 index 000000000..1d39b055a --- /dev/null +++ b/src/Structures/Static/GameCounts/Pit/GameCountsPit.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsPitModes from './GameCountsPitModes.js'; +import GameCountsPit from './GameCountsPit.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsPit', () => { + const data = new GameCountsPit({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsPit); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsPitModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Pit/GameCountsPit.ts b/src/Structures/Static/GameCounts/Pit/GameCountsPit.ts new file mode 100644 index 000000000..9e0ebbc24 --- /dev/null +++ b/src/Structures/Static/GameCounts/Pit/GameCountsPit.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsPitModes from './GameCountsPitModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsPit extends GameCountsGeneric { + modes: GameCountsGameCountsPitModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsPitModes(data?.modes); + } +} + +export default GameCountsPit; diff --git a/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.test.ts b/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.test.ts new file mode 100644 index 000000000..921e32221 --- /dev/null +++ b/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.test.ts @@ -0,0 +1,12 @@ +import GameCountsPitModes from './GameCountsPitModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsPitModes', () => { + const data = new GameCountsPitModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsPitModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.PIT).toBeDefined(); + expect(data.PIT).toBeGreaterThanOrEqual(0); + expectTypeOf(data.PIT).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.ts b/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.ts new file mode 100644 index 000000000..590f48ddd --- /dev/null +++ b/src/Structures/Static/GameCounts/Pit/GameCountsPitModes.ts @@ -0,0 +1,8 @@ +class GameCountsPitModes { + PIT: number; + constructor(data: Record) { + this.PIT = data?.PIT || 0; + } +} + +export default GameCountsPitModes; diff --git a/src/Structures/Static/GameCounts/Replay/GameCountsReplay.test.ts b/src/Structures/Static/GameCounts/Replay/GameCountsReplay.test.ts new file mode 100644 index 000000000..df1bdff12 --- /dev/null +++ b/src/Structures/Static/GameCounts/Replay/GameCountsReplay.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameContsReplayModes from './GameCountsReplayModes.js'; +import GameCountsReplay from './GameCountsReplay.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsReplay', () => { + const data = new GameCountsReplay({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsReplay); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameContsReplayModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Replay/GameCountsReplay.ts b/src/Structures/Static/GameCounts/Replay/GameCountsReplay.ts new file mode 100644 index 000000000..88378fb03 --- /dev/null +++ b/src/Structures/Static/GameCounts/Replay/GameCountsReplay.ts @@ -0,0 +1,12 @@ +import GameCountsGameContsReplayModes from './GameCountsReplayModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsReplay extends GameCountsGeneric { + modes: GameCountsGameContsReplayModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameContsReplayModes(data?.modes); + } +} + +export default GameCountsReplay; diff --git a/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.test.ts b/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.test.ts new file mode 100644 index 000000000..e7b0aab6f --- /dev/null +++ b/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.test.ts @@ -0,0 +1,12 @@ +import GameContsReplayModes from './GameCountsReplayModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameContsReplayModes', () => { + const data = new GameContsReplayModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameContsReplayModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.base).toBeDefined(); + expect(data.base).toBeGreaterThanOrEqual(0); + expectTypeOf(data.base).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.ts b/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.ts new file mode 100644 index 000000000..bbfdb6d84 --- /dev/null +++ b/src/Structures/Static/GameCounts/Replay/GameCountsReplayModes.ts @@ -0,0 +1,8 @@ +class GameContsReplayModes { + base: number; + constructor(data: Record) { + this.base = data?.BASE || 0; + } +} + +export default GameContsReplayModes; diff --git a/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.test.ts b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.test.ts new file mode 100644 index 000000000..20086fe05 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsSkyBlockModes from './GameCountsSkyBlockModes.js'; +import GameCountsSkyBlock from './GameCountsSkyBlock.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSkyBlock', () => { + const data = new GameCountsSkyBlock({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSkyBlock); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsSkyBlockModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.ts b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.ts new file mode 100644 index 000000000..55b979e9c --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsSkyBlockModes from './GameCountsSkyBlockModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsSkyBlock extends GameCountsGeneric { + modes: GameCountsGameCountsSkyBlockModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsSkyBlockModes(data?.modes); + } +} + +export default GameCountsSkyBlock; diff --git a/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.test.ts b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.test.ts new file mode 100644 index 000000000..a3c046174 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.test.ts @@ -0,0 +1,72 @@ +import GameCountsSkyBlockModes from './GameCountsSkyBlockModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSkyBlockModes', () => { + const data = new GameCountsSkyBlockModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSkyBlockModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.instanced).toBeDefined(); + expect(data.instanced).toBeGreaterThanOrEqual(0); + expectTypeOf(data.instanced).toEqualTypeOf(); + expect(data.foraging2).toBeDefined(); + expect(data.foraging2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.foraging2).toEqualTypeOf(); + expect(data.garden).toBeDefined(); + expect(data.garden).toBeGreaterThanOrEqual(0); + expectTypeOf(data.garden).toEqualTypeOf(); + expect(data.dungeonHub).toBeDefined(); + expect(data.dungeonHub).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dungeonHub).toEqualTypeOf(); + expect(data.fishing1).toBeDefined(); + expect(data.fishing1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.fishing1).toEqualTypeOf(); + expect(data.farming1).toBeDefined(); + expect(data.farming1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.farming1).toEqualTypeOf(); + expect(data.mining2).toBeDefined(); + expect(data.mining2).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mining2).toEqualTypeOf(); + expect(data.darkAuction).toBeDefined(); + expect(data.darkAuction).toBeGreaterThanOrEqual(0); + expectTypeOf(data.darkAuction).toEqualTypeOf(); + expect(data.kuudra).toBeDefined(); + expect(data.kuudra).toBeGreaterThanOrEqual(0); + expectTypeOf(data.kuudra).toEqualTypeOf(); + expect(data.crimsonIsle).toBeDefined(); + expect(data.crimsonIsle).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crimsonIsle).toEqualTypeOf(); + expect(data.mining3).toBeDefined(); + expect(data.mining3).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mining3).toEqualTypeOf(); + expect(data.crystalHollows).toBeDefined(); + expect(data.crystalHollows).toBeGreaterThanOrEqual(0); + expectTypeOf(data.crystalHollows).toEqualTypeOf(); + expect(data.dynamic).toBeDefined(); + expect(data.dynamic).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dynamic).toEqualTypeOf(); + expect(data.combat3).toBeDefined(); + expect(data.combat3).toBeGreaterThanOrEqual(0); + expectTypeOf(data.combat3).toEqualTypeOf(); + expect(data.combat1).toBeDefined(); + expect(data.combat1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.combat1).toEqualTypeOf(); + expect(data.foraging1).toBeDefined(); + expect(data.foraging1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.foraging1).toEqualTypeOf(); + expect(data.hub).toBeDefined(); + expect(data.hub).toBeGreaterThanOrEqual(0); + expectTypeOf(data.hub).toEqualTypeOf(); + expect(data.dungeon).toBeDefined(); + expect(data.dungeon).toBeGreaterThanOrEqual(0); + expectTypeOf(data.dungeon).toEqualTypeOf(); + expect(data.mining1).toBeDefined(); + expect(data.mining1).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mining1).toEqualTypeOf(); + expect(data.rift).toBeDefined(); + expect(data.rift).toBeGreaterThanOrEqual(0); + expectTypeOf(data.rift).toEqualTypeOf(); + expect(data.mineshaft).toBeDefined(); + expect(data.mineshaft).toBeGreaterThanOrEqual(0); + expectTypeOf(data.mineshaft).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.ts b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.ts new file mode 100644 index 000000000..e8443f9c5 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.ts @@ -0,0 +1,48 @@ +class GameCountsSkyBlockModes { + instanced: number; + foraging2: number; + garden: number; + dungeonHub: number; + fishing1: number; + farming1: number; + mining2: number; + darkAuction: number; + kuudra: number; + crimsonIsle: number; + mining3: number; + crystalHollows: number; + dynamic: number; + combat3: number; + combat1: number; + foraging1: number; + hub: number; + dungeon: number; + mining1: number; + rift: number; + mineshaft: number; + constructor(data: Record) { + this.instanced = data?.instanced || 0; + this.foraging2 = data?.foraging_2 || 0; + this.garden = data?.garden || 0; + this.dungeonHub = data?.dungeon_hub || 0; + this.fishing1 = data?.fishing_1 || 0; + this.farming1 = data?.farming_1 || 0; + this.mining2 = data?.mining_2 || 0; + this.darkAuction = data?.dark_auction || 0; + this.kuudra = data?.kuudra || 0; + this.crimsonIsle = data?.crimson_isle || 0; + this.mining3 = data?.mining_3 || 0; + this.crystalHollows = data?.crystal_hollows || 0; + this.dynamic = data?.dynamic || 0; + this.combat3 = data?.combat_3 || 0; + this.combat1 = data?.combat_1 || 0; + this.foraging1 = data?.foraging_1 || 0; + this.hub = data?.hub || 0; + this.dungeon = data?.dungeon || 0; + this.mining1 = data?.mining_1 || 0; + this.rift = data?.rift || 0; + this.mineshaft = data?.mineshaft || 0; + } +} + +export default GameCountsSkyBlockModes; diff --git a/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.test.ts b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.test.ts new file mode 100644 index 000000000..5581d9833 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.test.ts @@ -0,0 +1,13 @@ +import GameCountsMCGOModes from './GameCountsSkyWarsModes.js'; +import GameCountsSkyWars from './GameCountsSkyWars.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSkyWars', () => { + const data = new GameCountsSkyWars({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSkyWars); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsMCGOModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.ts b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.ts new file mode 100644 index 000000000..ca08c5af5 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.ts @@ -0,0 +1,12 @@ +import GameCountsGeneric from '../GameCountsGeneric.ts'; +import GameCountsMCGOModes from './GameCountsSkyWarsModes.js'; + +class GameCountsSkyWars extends GameCountsGeneric { + modes: GameCountsMCGOModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsMCGOModes(data?.modes); + } +} + +export default GameCountsSkyWars; diff --git a/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.test.ts b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.test.ts new file mode 100644 index 000000000..ee5501220 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.test.ts @@ -0,0 +1,45 @@ +import GameCountsSkyWarsModes from './GameCountsSkyWarsModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSkyWarsModes', () => { + const data = new GameCountsSkyWarsModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSkyWarsModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.soloInsaneLucky).toBeDefined(); + expect(data.soloInsaneLucky).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsaneLucky).toEqualTypeOf(); + expect(data.soloInsaneSlime).toBeDefined(); + expect(data.soloInsaneSlime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsaneSlime).toEqualTypeOf(); + expect(data.teamsInsaneSlime).toBeDefined(); + expect(data.teamsInsaneSlime).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsInsaneSlime).toEqualTypeOf(); + expect(data.teamsInsaneRush).toBeDefined(); + expect(data.teamsInsaneRush).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsInsaneRush).toEqualTypeOf(); + expect(data.teamsInsaneLucky).toBeDefined(); + expect(data.teamsInsaneLucky).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsInsaneLucky).toEqualTypeOf(); + expect(data.soloInsaneHuntersVsBeasts).toBeDefined(); + expect(data.soloInsaneHuntersVsBeasts).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsaneHuntersVsBeasts).toEqualTypeOf(); + expect(data.soloInsaneTntMadness).toBeDefined(); + expect(data.soloInsaneTntMadness).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsaneTntMadness).toEqualTypeOf(); + expect(data.megaDoubles).toBeDefined(); + expect(data.megaDoubles).toBeGreaterThanOrEqual(0); + expectTypeOf(data.megaDoubles).toEqualTypeOf(); + expect(data.miniNormal).toBeDefined(); + expect(data.miniNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.miniNormal).toEqualTypeOf(); + expect(data.soloInsaneRush).toBeDefined(); + expect(data.soloInsaneRush).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsaneRush).toEqualTypeOf(); + expect(data.soloInsane).toBeDefined(); + expect(data.soloInsane).toBeGreaterThanOrEqual(0); + expectTypeOf(data.soloInsane).toEqualTypeOf(); + expect(data.teamsInsaneTntMadness).toBeDefined(); + expect(data.teamsInsaneTntMadness).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teamsInsaneTntMadness).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.ts b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.ts new file mode 100644 index 000000000..5ad1f6724 --- /dev/null +++ b/src/Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.ts @@ -0,0 +1,33 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.ts'; + +class GameCountsSkyWarsModes extends GameCountsBasicModes { + soloInsaneLucky: number; + soloInsaneSlime: number; + teamsInsaneSlime: number; + teamsInsaneRush: number; + teamsInsaneLucky: number; + soloInsaneHuntersVsBeasts: number; + soloInsaneTntMadness: number; + megaDoubles: number; + miniNormal: number; + soloInsaneRush: number; + soloInsane: number; + teamsInsaneTntMadness: number; + constructor(data: Record) { + super(data); + this.soloInsaneLucky = data?.solo_insane_lucky || 0; + this.soloInsaneSlime = data?.solo_insane_slime || 0; + this.teamsInsaneSlime = data?.teams_insane_slime || 0; + this.teamsInsaneRush = data?.teams_insane_rush || 0; + this.teamsInsaneLucky = data?.teams_insane_lucky || 0; + this.soloInsaneHuntersVsBeasts = data?.solo_insane_hunters_vs_beasts || 0; + this.soloInsaneTntMadness = data?.solo_insane_tnt_madness || 0; + this.megaDoubles = data?.mega_doubles || 0; + this.miniNormal = data?.mini_normal || 0; + this.soloInsaneRush = data?.solo_insane_rush || 0; + this.soloInsane = data?.solo_insane || 0; + this.teamsInsaneTntMadness = data?.teams_insane_tnt_madness || 0; + } +} + +export default GameCountsSkyWarsModes; diff --git a/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.test.ts b/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.test.ts new file mode 100644 index 000000000..84d91da9b --- /dev/null +++ b/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.test.ts @@ -0,0 +1,13 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.js'; +import GameCountsSpeedUHC from './GameCountsSpeedUHC.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSpeedUHC', () => { + const data = new GameCountsSpeedUHC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSpeedUHC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsBasicModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.ts b/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.ts new file mode 100644 index 000000000..6bdbb75c3 --- /dev/null +++ b/src/Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.ts @@ -0,0 +1,12 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.ts'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsSpeedUHC extends GameCountsGeneric { + modes: GameCountsBasicModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsBasicModes(data?.modes); + } +} + +export default GameCountsSpeedUHC; diff --git a/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.test.ts b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.test.ts new file mode 100644 index 000000000..cfc687f03 --- /dev/null +++ b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsSuperSmashModes from './GameCountsSuperSmashModes.js'; +import GameCountsSuperSmash from './GameCountsSuperSmash.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSuperSmash', () => { + const data = new GameCountsSuperSmash({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSuperSmash); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsSuperSmashModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.ts b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.ts new file mode 100644 index 000000000..d0d9b4501 --- /dev/null +++ b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsSuperSmashModes from './GameCountsSuperSmashModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsSuperSmash extends GameCountsGeneric { + modes: GameCountsGameCountsSuperSmashModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsSuperSmashModes(data?.modes); + } +} + +export default GameCountsSuperSmash; diff --git a/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.test.ts b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.test.ts new file mode 100644 index 000000000..d6d85a64f --- /dev/null +++ b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.test.ts @@ -0,0 +1,18 @@ +import GameCountsSuperSmashModes from './GameCountsSuperSmashModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSuperSmashModes', () => { + const data = new GameCountsSuperSmashModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSuperSmashModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data['1v1Normal']).toBeDefined(); + expect(data['1v1Normal']).toBeGreaterThanOrEqual(0); + expectTypeOf(data['1v1Normal']).toEqualTypeOf(); + expect(data.friendsNormal).toBeDefined(); + expect(data.friendsNormal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.friendsNormal).toEqualTypeOf(); + expect(data['2v2Normal']).toBeDefined(); + expect(data['2v2Normal']).toBeGreaterThanOrEqual(0); + expectTypeOf(data['2v2Normal']).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.ts b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.ts new file mode 100644 index 000000000..9cab04b12 --- /dev/null +++ b/src/Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.ts @@ -0,0 +1,15 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.ts'; + +class GameCountsSuperSmashModes extends GameCountsBasicModes { + '1v1Normal': number; + friendsNormal: number; + '2v2Normal': number; + constructor(data: Record) { + super(data); + this['1v1Normal'] = data?.['1v1_normal'] || 0; + this.friendsNormal = data?.friends_normal || 0; + this['2v2Normal'] = data?.['.2v2_normal'] || 0; + } +} + +export default GameCountsSuperSmashModes; diff --git a/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.test.ts b/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.test.ts new file mode 100644 index 000000000..363f03f9f --- /dev/null +++ b/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.test.ts @@ -0,0 +1,13 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.js'; +import GameCountsSurvivalGames from './GameCountsSurvivalGames.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsSurvivalGames', () => { + const data = new GameCountsSurvivalGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsSurvivalGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsBasicModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.ts b/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.ts new file mode 100644 index 000000000..f85cac829 --- /dev/null +++ b/src/Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.ts @@ -0,0 +1,12 @@ +import GameCountsBasicModes from '../GameCountsBasicModes.ts'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsSurvivalGames extends GameCountsGeneric { + modes: GameCountsBasicModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsBasicModes(data?.modes); + } +} + +export default GameCountsSurvivalGames; diff --git a/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.test.ts b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.test.ts new file mode 100644 index 000000000..e1d6554ae --- /dev/null +++ b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.test.ts @@ -0,0 +1,13 @@ +import GameCountsTNTGames from './GameCountsTNTGames.js'; +import GameCountsTNTGamesModes from './GameCountsTNTGamesModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsTNTGames', () => { + const data = new GameCountsTNTGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsTNTGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsTNTGamesModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.ts b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.ts new file mode 100644 index 000000000..adb4b1a0f --- /dev/null +++ b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.ts @@ -0,0 +1,12 @@ +import GameCountsGeneric from '../GameCountsGeneric.ts'; +import GameCountsTNTGamesModes from './GameCountsTNTGamesModes.js'; + +class GameCountsTNTGames extends GameCountsGeneric { + modes: GameCountsTNTGamesModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsTNTGamesModes(data?.modes); + } +} + +export default GameCountsTNTGames; diff --git a/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.test.ts b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.test.ts new file mode 100644 index 000000000..e54847c8d --- /dev/null +++ b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.test.ts @@ -0,0 +1,24 @@ +import GameCountsTNTGamesModes from './GameCountsTNTGamesModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsTNTGamesModes', () => { + const data = new GameCountsTNTGamesModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsTNTGamesModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.PVPRun).toBeDefined(); + expect(data.PVPRun).toBeGreaterThanOrEqual(0); + expectTypeOf(data.PVPRun).toEqualTypeOf(); + expect(data.TNTTag).toBeDefined(); + expect(data.TNTTag).toBeGreaterThanOrEqual(0); + expectTypeOf(data.TNTTag).toEqualTypeOf(); + expect(data.TNTRun).toBeDefined(); + expect(data.TNTRun).toBeGreaterThanOrEqual(0); + expectTypeOf(data.TNTRun).toEqualTypeOf(); + expect(data.bowSpleef).toBeDefined(); + expect(data.bowSpleef).toBeGreaterThanOrEqual(0); + expectTypeOf(data.bowSpleef).toEqualTypeOf(); + expect(data.capture).toBeDefined(); + expect(data.capture).toBeGreaterThanOrEqual(0); + expectTypeOf(data.capture).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.ts b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.ts new file mode 100644 index 000000000..8c69e61ea --- /dev/null +++ b/src/Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.ts @@ -0,0 +1,16 @@ +class GameCountsTNTGamesModes { + PVPRun: number; + TNTTag: number; + TNTRun: number; + bowSpleef: number; + capture: number; + constructor(data: Record) { + this.PVPRun = data?.PVPRUN || 0; + this.TNTTag = data?.TNTAG || 0; + this.TNTRun = data?.TNTRUN || 0; + this.bowSpleef = data?.BOWSPLEEF || 0; + this.capture = data?.CAPTURE || 0; + } +} + +export default GameCountsTNTGamesModes; diff --git a/src/Structures/Static/GameCounts/UHC/GameCountsUHC.test.ts b/src/Structures/Static/GameCounts/UHC/GameCountsUHC.test.ts new file mode 100644 index 000000000..f7be84b49 --- /dev/null +++ b/src/Structures/Static/GameCounts/UHC/GameCountsUHC.test.ts @@ -0,0 +1,13 @@ +import GameCountsUHC from './GameCountsUHC.js'; +import GameCountsUHCModes from './GameCountsUHCModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsUHC', () => { + const data = new GameCountsUHC({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsUHC); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsUHCModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/UHC/GameCountsUHC.ts b/src/Structures/Static/GameCounts/UHC/GameCountsUHC.ts new file mode 100644 index 000000000..b5571e0f1 --- /dev/null +++ b/src/Structures/Static/GameCounts/UHC/GameCountsUHC.ts @@ -0,0 +1,12 @@ +import GameCountsGeneric from '../GameCountsGeneric.ts'; +import GameCountsUHCModes from './GameCountsUHCModes.js'; + +class GameCountsUHC extends GameCountsGeneric { + modes: GameCountsUHCModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsUHCModes(data?.modes); + } +} + +export default GameCountsUHC; diff --git a/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.test.ts b/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.test.ts new file mode 100644 index 000000000..728b165ef --- /dev/null +++ b/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.test.ts @@ -0,0 +1,18 @@ +import GameCountsUHCModes from './GameCountsUHCModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsUHCModes', () => { + const data = new GameCountsUHCModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsUHCModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.teams).toBeDefined(); + expect(data.teams).toBeGreaterThanOrEqual(0); + expectTypeOf(data.teams).toEqualTypeOf(); + expect(data.solo).toBeDefined(); + expect(data.solo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.solo).toEqualTypeOf(); + expect(data.brawlDuo).toBeDefined(); + expect(data.brawlDuo).toBeGreaterThanOrEqual(0); + expectTypeOf(data.brawlDuo).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.ts b/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.ts new file mode 100644 index 000000000..85048b96f --- /dev/null +++ b/src/Structures/Static/GameCounts/UHC/GameCountsUHCModes.ts @@ -0,0 +1,12 @@ +class GameCountsUHCModes { + teams: number; + solo: number; + brawlDuo: number; + constructor(data: Record) { + this.teams = data?.TEAMS || 0; + this.solo = data?.SOLO || 0; + this.brawlDuo = data?.BRAWL_DUO || 0; + } +} + +export default GameCountsUHCModes; diff --git a/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.test.ts b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.test.ts new file mode 100644 index 000000000..7477bab8e --- /dev/null +++ b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.test.ts @@ -0,0 +1,13 @@ +import GameCountsWalls3 from './GameCountsWalls3.js'; +import GameCountsWalls3Modes from './GameCountsWalls3Modes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsWalls3', () => { + const data = new GameCountsWalls3({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsWalls3); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsWalls3Modes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.ts b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.ts new file mode 100644 index 000000000..78c5eb822 --- /dev/null +++ b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3.ts @@ -0,0 +1,12 @@ +import GameCountsGeneric from '../GameCountsGeneric.ts'; +import GameCountsWalls3Modes from './GameCountsWalls3Modes.js'; + +class GameCountsWalls3 extends GameCountsGeneric { + modes: GameCountsWalls3Modes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsWalls3Modes(data?.modes); + } +} + +export default GameCountsWalls3; diff --git a/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.test.ts b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.test.ts new file mode 100644 index 000000000..bad3d4dc7 --- /dev/null +++ b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.test.ts @@ -0,0 +1,15 @@ +import GameCountsWalls3Modes from './GameCountsWalls3Modes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsWalls3Modes', () => { + const data = new GameCountsWalls3Modes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsWalls3Modes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.standard).toBeDefined(); + expect(data.standard).toBeGreaterThanOrEqual(0); + expectTypeOf(data.standard).toEqualTypeOf(); + expect(data.faceOff).toBeDefined(); + expect(data.faceOff).toBeGreaterThanOrEqual(0); + expectTypeOf(data.faceOff).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.ts b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.ts new file mode 100644 index 000000000..a4f456329 --- /dev/null +++ b/src/Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.ts @@ -0,0 +1,10 @@ +class GameCountsWalls3Modes { + standard: number; + faceOff: number; + constructor(data: Record) { + this.standard = data?.standard || 0; + this.faceOff = data?.face_off || 0; + } +} + +export default GameCountsWalls3Modes; diff --git a/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.test.ts b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.test.ts new file mode 100644 index 000000000..52abe92be --- /dev/null +++ b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.test.ts @@ -0,0 +1,13 @@ +import GameCountsGameCountsWoolGamesModes from './GameCountsWoolGamesModes.js'; +import GameCountsWoolGames from './GameCountsWoolGames.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsWoolGames', () => { + const data = new GameCountsWoolGames({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsWoolGames); + expectTypeOf(data).toEqualTypeOf(); + expect(data.modes).toBeDefined(); + expect(data.modes).toBeInstanceOf(GameCountsGameCountsWoolGamesModes); + expectTypeOf(data.modes).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.ts b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.ts new file mode 100644 index 000000000..476656fd7 --- /dev/null +++ b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.ts @@ -0,0 +1,12 @@ +import GameCountsGameCountsWoolGamesModes from './GameCountsWoolGamesModes.js'; +import GameCountsGeneric from '../GameCountsGeneric.ts'; + +class GameCountsWoolGames extends GameCountsGeneric { + modes: GameCountsGameCountsWoolGamesModes; + constructor(data: Record) { + super(data); + this.modes = new GameCountsGameCountsWoolGamesModes(data?.modes); + } +} + +export default GameCountsWoolGames; diff --git a/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.test.ts b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.test.ts new file mode 100644 index 000000000..089c7ada7 --- /dev/null +++ b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.test.ts @@ -0,0 +1,18 @@ +import GameCountsWoolGamesModes from './GameCountsWoolGamesModes.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameCountsWoolGamesModes', () => { + const data = new GameCountsWoolGamesModes({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameCountsWoolGamesModes); + expectTypeOf(data).toEqualTypeOf(); + expect(data.captureTheWoolTwoTwenty).toBeDefined(); + expect(data.captureTheWoolTwoTwenty).toBeGreaterThanOrEqual(0); + expectTypeOf(data.captureTheWoolTwoTwenty).toEqualTypeOf(); + expect(data.sheepWarsTwoSix).toBeDefined(); + expect(data.sheepWarsTwoSix).toBeGreaterThanOrEqual(0); + expectTypeOf(data.sheepWarsTwoSix).toEqualTypeOf(); + expect(data.woolWarsTwoFour).toBeDefined(); + expect(data.woolWarsTwoFour).toBeGreaterThanOrEqual(0); + expectTypeOf(data.woolWarsTwoFour).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.ts b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.ts new file mode 100644 index 000000000..47c44afb3 --- /dev/null +++ b/src/Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.ts @@ -0,0 +1,12 @@ +class GameCountsWoolGamesModes { + captureTheWoolTwoTwenty: number; + sheepWarsTwoSix: number; + woolWarsTwoFour: number; + constructor(data: Record) { + this.captureTheWoolTwoTwenty = data?.capture_the_wool_two_twenty || 0; + this.sheepWarsTwoSix = data?.sheep_wars_two_six || 0; + this.woolWarsTwoFour = data?.wool_wars_two_four || 0; + } +} + +export default GameCountsWoolGamesModes; diff --git a/src/Structures/Static/GameQuests.test.ts b/src/Structures/Static/GameQuests.test.ts new file mode 100644 index 000000000..c4bf76615 --- /dev/null +++ b/src/Structures/Static/GameQuests.test.ts @@ -0,0 +1,14 @@ +import GameQuests from './GameQuests.js'; +import Quest from './Quest.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('GameQuests', () => { + const data = new GameQuests('', [{ stats: 'meow' }]); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(GameQuests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.quests).toBeDefined(); + expectTypeOf(data.quests).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/GameQuests.ts b/src/Structures/Static/GameQuests.ts new file mode 100644 index 000000000..9789f0b65 --- /dev/null +++ b/src/Structures/Static/GameQuests.ts @@ -0,0 +1,12 @@ +import Quest from './Quest.js'; + +class GameQuests { + game: string; + quests: Quest[]; + constructor(name: string, data: Record[]) { + this.game = name; + this.quests = data.map((quest: Record) => new Quest(quest)); + } +} + +export default GameQuests; diff --git a/src/Structures/Static/Quest.test.ts b/src/Structures/Static/Quest.test.ts new file mode 100644 index 000000000..541552f13 --- /dev/null +++ b/src/Structures/Static/Quest.test.ts @@ -0,0 +1,28 @@ +import Quest from './Quest.js'; +import QuestObjective from './QuestObjective.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { QuestReward, QuestType } from '../../Types/Static.js'; + +test('Quest', () => { + const data = new Quest({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Quest); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.name).toBeDefined(); + expectTypeOf(data.name).toEqualTypeOf(); + expect(data.description).toBeDefined(); + expectTypeOf(data.description).toEqualTypeOf(); + expect(data.rewards).toBeDefined(); + expectTypeOf(data.rewards).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.objectives).toBeDefined(); + expectTypeOf(data.objectives).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => string>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.name); + expectTypeOf(data.toString()).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/Quest.ts b/src/Structures/Static/Quest.ts new file mode 100644 index 000000000..7d96bb93e --- /dev/null +++ b/src/Structures/Static/Quest.ts @@ -0,0 +1,25 @@ +import QuestObjective from './QuestObjective.js'; +import type { QuestReward, QuestType } from '../../Types/Static.js'; + +class Quest { + id: string; + name: string; + description: string; + rewards: QuestReward[]; + type: QuestType; + objectives: QuestObjective[]; + constructor(data: Record) { + this.id = (data?.id || '').trim(); + this.name = (data?.name || '').trim(); + this.description = (data?.description || '').trim(); + this.rewards = data.rewards || []; + this.type = data.requirements?.[0].type === 'DailyResetQuestRequirement' ? 'Daily' : 'Weekly'; + this.objectives = (data?.objectives || []).map((objective: any) => new QuestObjective(objective)); + } + + toString(): string { + return this.name; + } +} + +export default Quest; diff --git a/src/Structures/Static/QuestObjective.test.ts b/src/Structures/Static/QuestObjective.test.ts new file mode 100644 index 000000000..973e640bc --- /dev/null +++ b/src/Structures/Static/QuestObjective.test.ts @@ -0,0 +1,17 @@ +import QuestObjective from './QuestObjective.js'; +import { expect, expectTypeOf, test } from 'vitest'; +import type { QuestObjectiveType } from '../../Types/Static.js'; + +test('QuestObjective', () => { + const data = new QuestObjective({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(QuestObjective); + expectTypeOf(data).toEqualTypeOf(); + expect(data.id).toBeDefined(); + expectTypeOf(data.id).toEqualTypeOf(); + expect(data.type).toBeDefined(); + expectTypeOf(data.type).toEqualTypeOf(); + expect(data.amountNeeded).toBeDefined(); + expect(data.amountNeeded).toBeGreaterThanOrEqual(0); + expectTypeOf(data.amountNeeded).toEqualTypeOf(); +}); diff --git a/src/Structures/Static/QuestObjective.ts b/src/Structures/Static/QuestObjective.ts new file mode 100644 index 000000000..a142ce891 --- /dev/null +++ b/src/Structures/Static/QuestObjective.ts @@ -0,0 +1,14 @@ +import type { QuestObjectiveType } from '../../Types/Static.js'; + +class QuestObjective { + id: string; + type: QuestObjectiveType; + amountNeeded: number; + constructor(objective: Record) { + this.id = objective.id || 'UNKNOWN'; + this.type = objective.type === 'IntegerObjective' ? 'Integer' : 'Boolean'; + this.amountNeeded = parseInt(objective.integer || '1', 10); + } +} + +export default QuestObjective; diff --git a/src/Structures/Static/Quests.test.ts b/src/Structures/Static/Quests.test.ts new file mode 100644 index 000000000..35c7cf09d --- /dev/null +++ b/src/Structures/Static/Quests.test.ts @@ -0,0 +1,18 @@ +import GameQuests from './GameQuests.js'; +import Quests from './Quests.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Quests', () => { + const data = new Quests({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Quests); + expectTypeOf(data).toEqualTypeOf(); + expect(data.lastUpdatedTimestamp).toBeDefined(); + expect(data.lastUpdatedTimestamp).toBeGreaterThanOrEqual(0); + expectTypeOf(data.lastUpdatedTimestamp).toEqualTypeOf(); + expect(data.lastUpdatedAt).toBeDefined(); + expect(data.lastUpdatedAt).toBeInstanceOf(Date); + expectTypeOf(data.lastUpdatedAt).toEqualTypeOf(); + expect(data.questsPerGame).toBeDefined(); + expectTypeOf(data.questsPerGame).toEqualTypeOf>(); +}); diff --git a/src/Structures/Static/Quests.ts b/src/Structures/Static/Quests.ts new file mode 100644 index 000000000..8b84230d0 --- /dev/null +++ b/src/Structures/Static/Quests.ts @@ -0,0 +1,22 @@ +import GameQuests from './GameQuests.js'; +import type RequestData from '../../Private/RequestData.js'; + +class Quests { + lastUpdatedTimestamp: number; + lastUpdatedAt: Date; + questsPerGame: Record; + constructor(data: Record) { + this.lastUpdatedTimestamp = data.lastUpdated || 0; + this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); + this.questsPerGame = {}; + Object.keys(data.quests || {}).forEach((game) => { + this.questsPerGame[game] = new GameQuests(game, data.quests[game]); + }); + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Quests; diff --git a/src/Structures/Status.test.ts b/src/Structures/Status.test.ts new file mode 100644 index 000000000..fa5d5c235 --- /dev/null +++ b/src/Structures/Status.test.ts @@ -0,0 +1,23 @@ +import Game from './Game.js'; +import Status from './Status.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Status', () => { + const data = new Status({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(Status); + expectTypeOf(data).toEqualTypeOf(); + expect(data.online).toBeDefined(); + expectTypeOf(data.online).toEqualTypeOf(); + expect(data.game).toBeDefined(); + expectTypeOf(data.game).toEqualTypeOf(); + expect(data.mode).toBeDefined(); + expectTypeOf(data.mode).toEqualTypeOf(); + expect(data.map).toBeDefined(); + expectTypeOf(data.map).toEqualTypeOf(); + expect(data.toString).toBeDefined(); + expectTypeOf(data.toString).toEqualTypeOf<() => 'Online' | 'Offline'>(); + expect(data.toString()).toBeDefined(); + expect(data.toString()).toBe(data.online ? 'Online' : 'Offline'); + expectTypeOf(data.toString()).toEqualTypeOf<'Online' | 'Offline'>(); +}); diff --git a/src/Structures/Status.ts b/src/Structures/Status.ts new file mode 100644 index 000000000..18494bf18 --- /dev/null +++ b/src/Structures/Status.ts @@ -0,0 +1,25 @@ +import Game from './Game.js'; +import type RequestData from '../Private/RequestData.js'; + +class Status { + online: boolean; + game: Game | null; + mode: string | null; + map: string | null; + constructor(data: Record) { + this.online = data?.online || false; + this.game = data.gameType ? new Game(data.gameType) : null; + this.mode = data?.mode || null; + this.map = data?.map || null; + } + + toString(): 'Online' | 'Offline' { + return this.online ? 'Online' : 'Offline'; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default Status; diff --git a/src/Structures/WatchdogStats.test.ts b/src/Structures/WatchdogStats.test.ts new file mode 100644 index 000000000..930803409 --- /dev/null +++ b/src/Structures/WatchdogStats.test.ts @@ -0,0 +1,24 @@ +import WatchdogStats from './WatchdogStats.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('WatchdogStats', () => { + const data = new WatchdogStats({ stats: 'meow' }); + expect(data).toBeDefined(); + expect(data).toBeInstanceOf(WatchdogStats); + expectTypeOf(data).toEqualTypeOf(); + expect(data.byWatchdogTotal).toBeDefined(); + expect(data.byWatchdogTotal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogTotal).toEqualTypeOf(); + expect(data.byWatchdogLastMinute).toBeDefined(); + expect(data.byWatchdogLastMinute).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogLastMinute).toEqualTypeOf(); + expect(data.byWatchdogRollingDay).toBeDefined(); + expect(data.byWatchdogRollingDay).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byWatchdogRollingDay).toEqualTypeOf(); + expect(data.byStaffTotal).toBeDefined(); + expect(data.byStaffTotal).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byStaffTotal).toEqualTypeOf(); + expect(data.byStaffRollingDay).toBeDefined(); + expect(data.byStaffRollingDay).toBeGreaterThanOrEqual(0); + expectTypeOf(data.byStaffRollingDay).toEqualTypeOf(); +}); diff --git a/src/Structures/WatchdogStats.ts b/src/Structures/WatchdogStats.ts new file mode 100644 index 000000000..1d6dae870 --- /dev/null +++ b/src/Structures/WatchdogStats.ts @@ -0,0 +1,22 @@ +import type RequestData from '../Private/RequestData.js'; + +class WatchdogStats { + byWatchdogTotal: number; + byWatchdogLastMinute: number; + byWatchdogRollingDay: number; + byStaffTotal: number; + byStaffRollingDay: number; + constructor(data: Record) { + this.byWatchdogTotal = data?.watchdog_total || 0; + this.byWatchdogLastMinute = data?.watchdog_lastMinute || 0; + this.byWatchdogRollingDay = data?.watchdog_rollingDaily || 0; + this.byStaffTotal = data?.staff_total || 0; + this.byStaffRollingDay = data?.staff_rollingDaily || 0; + } + + isRaw(): this is RequestData { + return false; + } +} + +export default WatchdogStats; diff --git a/src/Types/API.ts b/src/Types/API.ts new file mode 100644 index 000000000..72c0c1061 --- /dev/null +++ b/src/Types/API.ts @@ -0,0 +1,38 @@ +import type RequestData from '../Private/RequestData.js'; +import type SkyBlockAuction from '../Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import type SkyBlockAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.js'; +import type SkyBlockBaseAuctionInfo from '../Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import type { RequestOptions } from './Requests.js'; +import type { SkyblockProfileWithMe } from './SkyBlock.js'; + +export interface PlayerRequestOptions extends RequestOptions { + guild?: boolean; + houses?: boolean; + recentGames?: boolean; +} + +export interface AuctionRequestOptions extends RequestOptions { + includeItemBytes?: boolean; +} + +export interface SkyBlockRequestOptions extends RequestOptions { + garden?: boolean; + museum?: boolean; +} + +export interface SkyBlockAuctionResult { + info: SkyBlockBaseAuctionInfo; + auctions: SkyBlockAuction[]; + isRaw(): this is RequestData; +} + +export interface SkyBlockAuctionsResult { + info: SkyBlockAuctionInfo; + auctions: SkyBlockAuction[]; + isRaw(): this is RequestData; +} +export type WithRaw = T & { isRaw(): this is RequestData }; +export type WithSelectedProfile = WithRaw & { selectedProfile?: SkyblockProfileWithMe }; + +export type GuildFetchOptions = 'id' | 'name' | 'player'; +export type AuctionFetchOptions = 'PROFILE' | 'PLAYER' | 'AUCTION_ID'; diff --git a/src/Types/Booster.ts b/src/Types/Booster.ts new file mode 100644 index 000000000..dbcd95e22 --- /dev/null +++ b/src/Types/Booster.ts @@ -0,0 +1 @@ +export type BoosterType = 'STACKED' | 'QUEUED' | 'ACTIVE'; diff --git a/src/Types/Client.ts b/src/Types/Client.ts new file mode 100644 index 000000000..877fabc7d --- /dev/null +++ b/src/Types/Client.ts @@ -0,0 +1,10 @@ +export interface ClientOptions { + cache?: boolean; + cacheTime?: number; + cacheMaxKeys?: number; + cacheCheckPeriod?: number; + rateLimit?: 'AUTO' | 'NONE'; + silent?: boolean; + checkForUpdates?: boolean; + checkForUpdatesInterval?: number; +} diff --git a/src/Types/Color.ts b/src/Types/Color.ts new file mode 100644 index 000000000..cf49dd30f --- /dev/null +++ b/src/Types/Color.ts @@ -0,0 +1,71 @@ +export type ColorCode = + | 'BLACK' + | 'DARK_BLUE' + | 'DARK_GREEN' + | 'DARK_AQUA' + | 'DARK_RED' + | 'DARK_PURPLE' + | 'GOLD' + | 'GRAY' + | 'DARK_GRAY' + | 'BLUE' + | 'GREEN' + | 'AQUA' + | 'RED' + | 'LIGHT_PURPLE' + | 'YELLOW' + | 'WHITE'; + +export type ColorString = + | 'Black' + | 'Dark Blue' + | 'Dark Green' + | 'Dark Aqua' + | 'Dark Red' + | 'Dark Purple' + | 'Gold' + | 'Gray' + | 'Dark Gray' + | 'Blue' + | 'Green' + | 'Aqua' + | 'Red' + | 'Light Purple' + | 'Yellow' + | 'White'; + +export type ColorHex = + | '#000000' + | '#0000AA' + | '#008000' + | '#00AAAA' + | '#AA0000' + | '#AA00AA' + | '#FFAA00' + | '#AAAAAA' + | '#555555' + | '#5555FF' + | '#3CE63C' + | '#3CE6E6' + | '#FF5555' + | '#FF55FF' + | '#FFFF55' + | '#FFFFFF'; + +export type InGameCode = + | '§0' + | '§1' + | '§2' + | '§3' + | '§4' + | '§5' + | '§6' + | '§7' + | '§8' + | '§9' + | '§a' + | '§b' + | '§c' + | '§d' + | '§e' + | '§f'; diff --git a/src/Types/Game.ts b/src/Types/Game.ts new file mode 100644 index 000000000..e5665402c --- /dev/null +++ b/src/Types/Game.ts @@ -0,0 +1,95 @@ +export type GameID = + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 13 + | 14 + | 17 + | 20 + | 21 + | 23 + | 24 + | 25 + | 26 + | 51 + | 52 + | 54 + | 55 + | 56 + | 57 + | 58 + | 59 + | 60 + | 61 + | 63 + | 64 + | 65 + | 67 + | 68; + +export type GameCode = + | 'QUAKECRAFT' + | 'WALLS' + | 'PAINTBALL' + | 'SURVIVAL_GAMES' + | 'TNTGAMES' + | 'VAMPIREZ' + | 'WALLS3' + | 'ARCADE' + | 'ARENA' + | 'UHC' + | 'MCGO' + | 'BATTLEGROUND' + | 'SUPER_SMASH' + | 'GINGERBREAD' + | 'HOUSING' + | 'SKYWARS' + | 'TRUE_COMBAT' + | 'SPEED_UHC' + | 'SKYCLASH' + | 'LEGACY' + | 'PROTOTYPE' + | 'BEDWARS' + | 'MURDER_MYSTERY' + | 'BUILD_BATTLE' + | 'DUELS' + | 'SKYBLOCK' + | 'PIT' + | 'REPLAY' + | 'SMP' + | 'WOOL_GAMES'; + +export type GameString = + | 'Quake' + | 'Walls' + | 'Paintball' + | 'Blitz Survival Games' + | 'TNT Games' + | 'VampireZ' + | 'Mega Walls' + | 'Arcade' + | 'Arena' + | 'UHC Champions' + | 'Cops and Crims' + | 'Warlords' + | 'Smash Heroes' + | 'Turbo Kart Racers' + | 'Housing' + | 'SkyWars' + | 'Crazy Walls' + | 'Speed UHC' + | 'SkyClash' + | 'Classic Games' + | 'Prototype' + | 'Bed Wars' + | 'Murder Mystery' + | 'Build Battle' + | 'Duels' + | 'SkyBlock' + | 'Pit' + | 'Replay' + | 'SMP' + | 'Wool Wars'; diff --git a/src/Types/Global.ts b/src/Types/Global.ts new file mode 100644 index 000000000..5df8973f0 --- /dev/null +++ b/src/Types/Global.ts @@ -0,0 +1,3 @@ +export type UUID = string; +export type UserInput = string; +export type SortName = 'a_to_z' | 'z_to_a'; diff --git a/src/Types/Guild.ts b/src/Types/Guild.ts new file mode 100644 index 000000000..3fa114ab5 --- /dev/null +++ b/src/Types/Guild.ts @@ -0,0 +1,6 @@ +export interface ExpHistory { + day: string; + date: Date | undefined; + exp: number; + totalExp: number; +} diff --git a/src/Types/Player.ts b/src/Types/Player.ts new file mode 100644 index 000000000..1bf5e6e6d --- /dev/null +++ b/src/Types/Player.ts @@ -0,0 +1,4383 @@ +// Credits: Pixelic: https://github.com/pixelicc - Most types in player + +import PitInventoryItem from '../Structures/MiniGames/Pit/PitInventoryItem.js'; +import type { SortName } from './Global.js'; + +export type PlayerHousingSettingsTextInputType = 'CHAT'; +export type PlayerHousingPlotSize = 'SMALL' | 'MEDIUM' | 'LARGE' | 'MASSIVE' | 'EXTREME'; +export type PlayerHousingTutorialStage = 'WAITING_FOR_INTERACTION' | 'GIVING_KIT' | 'FINISHED' | 'FINISH_FINISHED'; +export type PlayerTourneyShopSort = 'highest_cost' | SortName; +export type PlayerAchievementsOneTimeSort = 'highest_points' | SortName; +export type SeasonName = 'christmas' | 'easter' | 'summer' | 'halloween' | 'anniversary'; +export type SocialMediaId = 'DISCORD' | 'TWITTER' | 'YOUTUBE' | 'INSTAGRAM' | 'TIKTOK' | 'TWITCH' | 'HYPIXEL'; +export type EnderSpleefTrails = 'RAINBOW' | 'GREEN' | 'DEFAULT' | 'RED' | 'BLUE'; +export type TurboKartRacersMaps = 'retro' | 'hypixelgp' | 'olympus' | 'junglerush' | 'canyon'; +export type VampireZRoles = 'human' | 'vampire'; +export type PixelPartyGameModes = 'normal' | 'hyper'; +export type QuakecraftBarrels = 'SMALL_BALL' | 'LARGE_BALL' | 'BURST' | 'STAR' | 'CREEPER'; +export type QuakecraftTriggers = 'ZERO_POINT_EIGHT_FIVE' | 'ZERO_POINT_NINE' | 'ONE_POINT_ONE' | 'ONE_POINT_THREE'; +export type ArenaBrawlModes = '1v1' | '2v2' | '4v4'; +export type ArenaBrawlRunes = 'slowing' | 'energy' | 'damage' | 'tank' | 'speed'; +export type MiniWallsKits = 'soldier' | 'archer' | 'builder'; +export type WoolWarsClassNames = 'ASSAULT' | 'TANK' | 'GOLEM' | 'SWORDSMAN' | 'ENGINEER' | 'ARCHER'; +export type SmashHeoresModes = 'normal' | '2v2' | 'teams'; +export type MegaWallsModes = 'face_off' | 'gvg'; +export type SpeedUHCModes = 'solo' | 'solo_normal' | 'solo_insane' | 'team' | 'team_normal' | 'team_insane'; +export type UHCModes = 'solo' | 'red_vs_blue' | 'no_diamonds' | 'brawl' | 'solo_brawl' | 'duo_brawl'; +export type CopsAndCrimsGamemodes = 'deathmatch' | 'gungame'; + +export type MegaWallsKits = + | 'cow' + | 'hunter' + | 'shark' + | 'arcanist' + | 'deadlord' + | 'golem' + | 'herobrine' + | 'pigman' + | 'zombie' + | 'blaze' + | 'enderman' + | 'shaman' + | 'squid' + | 'creeper' + | 'pirate' + | 'sheep' + | 'skeleton' + | 'spider' + | 'werewolf' + | 'angel' + | 'assassin' + | 'automaton' + | 'moleman' + | 'phoenix' + | 'renegade' + | 'snowman'; + +export type SmashHeoresHeros = + | 'THE_BULK' + | 'CAKE_MONSTER' + | 'GENERAL_CLUCK' + | 'BOTMUN' + | 'MARAUDER' + | 'PUG' + | 'TINMAN' + | 'SPODERMAN' + | 'FROSTY' + | 'SERGEANT_SHIELD' + | 'SKULLFIRE' + | 'GOKU' + | 'SANIC' + | 'DUSK_CRAWLER' + | 'SHOOP_DA_WHOOP' + | 'GREEN_HOOD'; + +export type WarlordsClasses = + | 'pyromancer' + | 'mage' + | 'thunderlord' + | 'shaman' + | 'earthwarden' + | 'aquamancer' + | 'paladin' + | 'avenger' + | 'warrior' + | 'defender' + | 'cryomancer' + | 'crusader' + | 'berserker' + | 'protector' + | 'revenant' + | 'spiritguard'; + +export type DuelsModes = + | 'blitz' + | 'classic' + | 'bow' + | 'no_debuff' + | 'combo' + | 'tnt_games' + | 'sumo' + | 'parkour' + | 'bridge' + | 'bridge_duel' + | 'bridge_doubles' + | 'bridge_threes' + | 'bridge_fours' + | '2v2v2v2' + | '3v3v3v3' + | 'capture_threes' + | 'op' + | 'mega_walls' + | 'mw_duel' + | 'mw_doubles' + | 'sw' + | 'sw_duel' + | 'sw_doubles' + | 'uhc' + | 'uhc_duel' + | 'uhc_doubles' + | 'uhc_four' + | 'uhc_meetup' + | 'blitz_duel' + | 'classic_duel' + | 'bow_duel' + | 'potion_duel' + | 'combo_duel' + | 'bowspleef_duel' + | 'sumo_duel' + | 'parkour_eight' + | 'duel_arena' + | 'op_duel' + | 'op_doubles'; + +export type PaintballHats = + | 'speed_hat' + | 'vip_kevinkool_hat' + | 'vip_rezzus_hat' + | 'vip_agentk_hat' + | 'normal_hat' + | 'tnt_hat' + | 'vip_paintballkitty_hat' + | 'vip_ghost_hat' + | 'hard_hat' + | 'ender_hat' + | 'vip_codename_b_hat' + | 'snow_hat' + | 'vip_hypixel_hat' + | 'vip_noxyd_hat' + | 'squid_hat' + | 'shaky_hat' + | 'spider_hat' + | 'drunk_hat'; + +export type QuakecraftKillSounds = + | 'anvil_land' + | 'pig_death' + | 'bat_death' + | 'level_up' + | 'cow_hurt' + | 'ghast_death' + | 'creeper_death' + | 'blaze_death' + | 'zombie_woodbreak' + | 'enderman_death' + | 'wither_idle' + | 'dragon_growl' + | 'villager_mhm' + | 'horse_death' + | 'golem_death' + | 'thunder'; + +export type QuakecraftCase = + | 'SHINY_DIAMOND_HOE' + | 'STONE_HOE' + | 'SHINY_IRON_HOE' + | 'SHINY_STONE_HOE' + | 'SHINY_WOOD_HOE' + | 'WOOD_HOE' + | 'DIAMOND_HOE' + | 'SHINY_GOLD_HOE' + | 'IRON_HOE'; + +export type QuakecraftMuzzle = + | 'SOUL_SAND' + | 'QUARTZ' + | 'REDSTONE' + | 'NONE' + | 'IRON' + | 'DIAMOND' + | 'LAPIS' + | 'OBSIDIAN' + | 'PRISMARINE' + | 'EMERALD' + | 'PUMPKIN' + | 'COMMAND_BLOCK' + | 'SEA_LANTERN'; + +export type QuakecraftSights = + | 'BLACK' + | 'RED' + | 'YELLOW' + | 'SILVER' + | 'BLUE' + | 'DIAMOND' + | 'WHITE' + | 'PURPLE' + | 'EMERALD' + | 'GRAY' + | 'GOLD' + | 'ORANGE' + | 'PINK' + | 'GREEN'; + +export type UHCKits = + | 'ARCHERY_TOOLS' + | 'WORKING_TOOLS' + | 'HORSEMAN' + | 'ECOLOGIST' + | 'LOOTER' + | 'MAGIC_TOOLS' + | 'TRAPPER'; + +export type CopsAndCrimsGuns = + | 'smg' + | 'rifle' + | 'carbine' + | 'magnum' + | 'shotgun' + | 'sniper' + | 'scoped_rifle' + | 'handgun' + | 'auto_shotgun' + | 'bullpup' + | 'knife'; + +export interface RanksPurchaseTime { + VIP: Date | null; + VIP_PLUS: Date | null; + MVP: Date | null; + MVP_PLUS: Date | null; +} + +export interface ScorpiusBribe { + year: number; + timestamp: number; +} + +export type BedWarsPrestige = + | 'Stone' + | 'Iron' + | 'Gold' + | 'Diamond' + | 'Emerald' + | 'Sapphire' + | 'Ruby' + | 'Crystal' + | 'Opal' + | 'Amethyst' + | 'Rainbow' + | 'Iron Prime' + | 'Gold Prime' + | 'Diamond Prime' + | 'Emerald Prime' + | 'Sapphire Prime' + | 'Ruby Prime' + | 'Crystal Prime' + | 'Opal Prime' + | 'Amethyst Prime' + | 'Mirror' + | 'Light' + | 'Dawn' + | 'Dusk' + | 'Air' + | 'Wind' + | 'Nebula' + | 'Thunder' + | 'Earth' + | 'Water' + | 'Fire' + | 'Sunrise' + | 'Eclipse' + | 'Gamma' + | 'Majestic' + | 'Andesine' + | 'Marine' + | 'Element' + | 'Galaxy' + | 'Atomic' + | 'Sunset' + | 'Time' + | 'Winter' + | 'Obsidian' + | 'Spring' + | 'Ice' + | 'Summer' + | 'Spinel' + | 'Autumn' + | 'Mystic' + | 'Eternal'; + +export type TurboKartRacersHorn = + | 'DEFAULT' + | 'SHY' + | 'ALIEN' + | 'TAXI' + | 'KLAXON' + | 'TRICYCLE' + | 'ALARM' + | 'KLOON' + | 'TEDDY' + | 'TRUCK' + | 'JERRY'; + +export type DuelsBaseDivision = + | 'Rookie' + | 'Iron' + | 'Gold' + | 'Diamond' + | 'Master' + | 'Legend' + | 'Grandmaster' + | 'Godlike' + | 'Celestial' + | 'Divine' + | 'Ascended'; + +export interface WoolGamesPrivateGameConfig { + one_hit_one_kill: boolean; + rainbow_wool: 'Enabled' | 'Disabled'; + health_buff: string; + game_speed: string; + speed: string; + no_class: 'Enabled' | 'Disabled'; + respawn_enable: boolean; +} + +export interface PitArmor { + helmet: PitInventoryItem | null; + chestplate: PitInventoryItem | null; + leggings: PitInventoryItem | null; + boots: PitInventoryItem | null; +} + +export type PlayerAchievementsTotemColors = 'blue' | 'purple' | 'overgrown' | 'yellow' | 'green' | 'steampunk' | 'red'; +export type PlayerAchievementsTotemParts = + | 'birdy' + | 'happy' + | 'arrow' + | 'snake' + | 'pong' + | 'corner' + | 'weird' + | 'window' + | 'grumpy' + | 'grizzly' + | 'sad' + | 'connection' + | 'cube' + | 'cat'; + +export type PlayerRank = + | null + | 'VIP' + | 'VIP+' + | 'MVP' + | 'MVP+' + | 'MVP++' + | 'YouTube' + | 'Staff' + | 'Innit' + | 'PIG+++' + | 'Mojang' + | 'Events'; + +export interface LevelProgress { + level: number; + totalXp: number; + xpToNext: number; + remainingXP: number; + currentXP: number; + percent: number; + percentRemaining: number; +} + +export type Language = + | 'CHINESE_SIMPLIFIED' + | 'CHINESE_TRADITIONAL' + | 'CZECH' + | 'DANISH' + | 'DUTCH' + | 'ENGLISH' + | 'FINNISH' + | 'FRENCH' + | 'GERMAN' + | 'GREEK' + | 'HUNGARIAN' + | 'ITALIAN' + | 'JAPANESE' + | 'KOREAN' + | 'NORWEGIAN' + | 'POLISH' + | 'PORTUGUESE_BR' + | 'PORTUGUESE_PT' + | 'PIRATE' + | 'ROMANIAN' + | 'RUSSIAN' + | 'SERBIAN_CYRILLIC' + | 'SPANISH' + | 'SWEDISH' + | 'TURKISH' + | 'UKRAINIAN'; + +export type PlayerCosmeticsPetName = + | 'sheep_white' + | 'pig' + | 'mule' + | 'black_rabbit' + | 'sheep_blue_baby' + | 'cat_black' + | 'frozen_skeleton' + | 'brown_horse_baby' + | 'silverfish' + | 'wolf' + | 'sheep_magenta' + | 'sheep_silver' + | 'sheep_gray' + | 'zombie_baby' + | 'horse_grey' + | 'sheep_brown' + | 'cat_red_baby' + | 'zombie' + | 'chicken' + | 'sheep_light_blue' + | 'magma_cube_small' + | 'cow' + | 'chicken_baby' + | 'magma_cube_big' + | 'zombie_villager' + | 'horse_black' + | 'horse_dark_brown_baby' + | 'cat_siamese' + | 'horse_creamy' + | 'horse_chestnut_baby' + | 'horse_white' + | 'cat_black_baby' + | 'slime_big' + | 'horse_brown' + | 'pig_baby' + | 'brown_rabbit' + | 'horse_chestnut' + | 'sheep_blue' + | 'pig_zombie' + | 'sheep_white_baby' + | 'sheep_red_baby' + | 'slime_small' + | 'slime_tiny' + | 'magma_cube_tiny' + | 'totem' + | 'sheep_red' + | 'cat_siamese_baby' + | 'cat_red' + | 'wolf_baby' + | 'pig_zombie_baby' + | 'sheep_green' + | 'sheep_black_baby' + | 'sheep_yellow' + | 'donkey' + | 'mooshroom_baby' + | 'mooshroom' + | 'cow_baby' + | 'spider_jockey' + | 'villager_butcher' + | 'villager_priest' + | 'spider' + | 'white_rabbit' + | 'skeleton' + | 'sheep_black' + | 'sheep_yellow_baby' + | 'villager_farmer' + | 'enderman' + | 'horse_undead' + | 'gold_rabbit' + | 'salt_pepper_rabbit' + | 'black_white_rabbit' + | 'villager_butcher_baby' + | 'villager_priest_baby' + | 'creeper' + | 'villager_blacksmith_baby' + | 'villager_blacksmith' + | 'villager_farmer_baby' + | 'villager_librarian' + | 'villager_librarian_baby' + | 'cave_spider' + | 'horse_dark_brown' + | 'bat' + | 'horse_creamy_baby' + | 'iron_golem' + | 'creeper_powered' + | 'fish' + | 'frozen_zombie' + | 'sheep_lime' + | 'sheep_rainbow' + | 'enderman_snow_block' + | 'sheep_cyan' + | 'sheep_purple' + | 'herobrine' + | 'sheep_pink_baby' + | 'sheep_orange' + | 'witch' + | 'merry_sheep' + | 'sheep_orange_baby' + | 'clownfish' + | 'sheep_silver_baby' + | 'sheep_gray_baby' + | 'rabbit_jockey' + | 'endermite' + | 'black_pug' + | 'sheep_pink' + | 'specter' + | 'enderman_pumpkin' + | 'snowman' + | 'red_helper' + | 'green_helper' + | 'horse_gray_baby' + | 'sheep_lime_baby' + | 'white_pug' + | 'sheep_magenta_baby' + | 'sheep_cyan_baby' + | 'growing_zombie' + | 'bee' + | 'smoldering_skeleton' + | 'mini_wither' + | 'zombie_villager_baby' + | 'sheep_brown_baby' + | 'sheep_purple_baby' + | 'snowman_jockey' + | 'sheep_light_blue_baby' + | 'sheep_green_baby' + | 'flying_squid' + | 'bouncy_sheep' + | 'little_you' + | 'duck' + | 'frog' + | 'elephant' + | 'panda' + | 'gorrila' + | 'chimp' + | 'sloth' + | 'horse_skeleton' + | 'killer_rabbit' + | 'enderman_hay_bale' + | 'chicken_jockey' + | 'burning_zombie' + | 'bouncy_spider' + | 'colorbox' + | 'guardian' + | 'hp8'; + +export type PlayerCosmeticsSuit = + | 'mermaid_leggings' + | 'bumblebee_boots' + | 'spiderman_boots' + | 'frog_chestplate' + | 'baker_chestplate' + | 'elf_leggings' + | 'grinch_leggings' + | 'elf_boots' + | 'grinch_helmet' + | 'plumber_boots' + | 'chicken_chestplate' + | 'chicken_helmet' + | 'chicken_boots' + | 'ghost_boots' + | 'flash_boots' + | 'warrior_boots' + | 'ghost_leggings' + | 'death_angel_boots' + | 'arctic_leggings' + | 'frog_leggings' + | 'necromancer_leggings' + | 'mermaid_boots' + | 'baker_leggings' + | 'baker_boots' + | 'thor_boots' + | 'necromancer_boots' + | 'mermaid_chestplate' + | 'warrior_leggings' + | 'death_angel_leggings' + | 'fireman_helmet' + | 'arctic_boots' + | 'ninja_boots' + | 'dragon_breath_helmet' + | 'pirate_boots' + | 'necromancer_helmet' + | 'solar_chestplate' + | 'arctic_chestplate' + | 'soccer_boots' + | 'pirate_helmet' + | 'wolf_leggings' + | 'warrior_chestplate' + | 'bumblebee_helmet' + | 'frog_boots' + | 'costume_helmet' + | 'disco_leggings' + | 'flash_helmet' + | 'costume_boots' + | 'vampire_boots' + | 'costume_leggings' + | 'costume_chestplate' + | 'magma_boss_leggings' + | 'headless_horseman_chestplate' + | 'vampire_leggings' + | 'skeleton_samurai_chestplate' + | 'disco_boots' + | 'flash_leggings' + | 'plumber_leggings' + | 'fireman_boots' + | 'new_years_boots' + | 'santa_boots' + | 'disco_helmet' + | 'new_years_leggings' + | 'santa_chestplate' + | 'thor_leggings' + | 'mermaid_helmet' + | 'ninja_helmet' + | 'flash_chestplate' + | 'baker_helmet' + | 'spiderman_leggings' + | 'plumber_chestplate' + | 'ghost_chestplate' + | 'thor_chestplate' + | 'easter_egg_chestplate' + | 'warrior_helmet' + | 'bumblebee_leggings' + | 'ninja_leggings' + | 'yeti_leggings' + | 'new_years_chestplate' + | 'frog_helmet' + | 'death_angel_helmet' + | 'tnt_boots' + | 'tnt_chestplate' + | 'tnt_helmet' + | 'tnt_leggings' + | 'dragon_breath_chestplate' + | 'dragon_breath_leggings' + | 'dragon_breath_boots' + | 'solar_boots' + | 'solar_leggings' + | 'solar_helmet' + | 'elf_helmet' + | 'elf_chestplate' + | 'thor_helmet' + | 'bumblebee_chestplate' + | 'pumpkin_helmet' + | 'skeleton_samurai_boots' + | 'skeleton_samurai_helmet' + | 'yeti_chestplate' + | 'yeti_boots' + | 'arctic_helmet' + | 'grinch_boots' + | 'disco_chestplate' + | 'fireman_leggings' + | 'easter_egg_boots' + | 'easter_egg_leggings' + | 'chicken_leggings' + | 'headless_horseman_boots' + | 'magma_boss_boots' + | 'ghost_helmet' + | 'necromancer_chestplate' + | 'death_angel_chestplate' + | 'plumber_helmet' + | 'pirate_leggings' + | 'ninja_chestplate' + | 'spiderman_chestplate' + | 'spiderman_helmet' + | 'fireman_chestplate' + | 'toy_chestplate' + | 'toy_leggings' + | 'santa_leggings' + | 'grinch_chestplate' + | 'soccer_helmet' + | 'vampire_chestplate' + | 'soccer_leggings' + | 'wolf_helmet' + | 'wolf_chestplate' + | 'pumpkin_boots' + | 'vampire_helmet' + | 'toy_boots' + | 'pirate_chestplate' + | 'new_years_helmet' + | 'easter_egg_helmet' + | 'treasure_boots' + | 'toy_helmet' + | 'wolf_boots' + | 'headless_horseman_helmet' + | 'headless_horseman_leggings' + | 'yeti_helmet' + | 'soccer_chestplate' + | 'pumpkin_chestplate' + | 'treasure_helmet' + | 'magma_boss_chestplate' + | 'pumpkin_leggings' + | 'santa_helmet' + | 'magma_boss_helmet' + | 'skeleton_samurai_leggings' + | 'treasure_chestplate' + | 'treasure_leggings' + | 'phoenix_helmet'; + +export type PlayerCosmeticsHat = + | 'bee' + | 'number_5' + | 'letter_r' + | 'letter_g' + | 'letter_plus' + | 'clownfish' + | 'earth' + | 'letter_v' + | 'festive_zombie' + | 'festive_skeleton' + | 'festive_villager' + | 'festive_squid' + | 'festive_herobrine' + | 'rainbow_present' + | 'wood_elf' + | 'lady_bug' + | 'number_1' + | 'chick' + | 'toaster' + | 'letter_a' + | 'koala' + | 'beach_ball' + | 'chocolate_egg' + | 'golden_knight' + | 'orc' + | 'letter_x' + | 'duckling' + | 'bird' + | 'burger' + | 'cactus' + | 'polar_bear' + | 'ferret' + | 'demon_knight' + | 'mars' + | 'letter_u' + | 'letter_h' + | 'letter_q' + | 'letter_z' + | 'letter_k' + | 'letter_d' + | 'letter_y' + | 'letter_p' + | 'letter_n' + | 'groopo' + | 'evil_eye' + | 'aqua_orb' + | 'letter_question' + | 'fire_demon' + | 'forester' + | 'number_2' + | 'vintage' + | 'number_9' + | 'letter_w' + | 'panda' + | 'broken_tv' + | 'number_4' + | 'squid' + | 'elephant' + | 'letter_o' + | 'elf_princess' + | 'letter_l' + | 'letter_j' + | 'cheese' + | 'number_8' + | 'owl' + | 'assassin' + | 'egyptian_queen' + | 'halloween_pig_zombie' + | 'halloween_skull' + | 'mummy' + | 'jason' + | 'sloth' + | 'letter_b' + | 'duck' + | 'rainbow_glitch' + | 'number_3' + | 'football_star' + | 'letter_exclaimation' + | 'miner' + | 'letter_e' + | 'dead_pirate' + | 'frog' + | 'egg_head' + | 'ginger_bread' + | 'elfgirl' + | 'bell' + | 'pug_black' + | 'horse' + | 'otter' + | 'letter_s' + | 'letter_hashtag' + | 'number_7' + | 'alien_slug' + | 'skull_king_banner' + | 'fox' + | 'monkey' + | 'number_6' + | 'letter_t' + | 'easter_egg' + | 'snowglobe' + | 'penguin' + | 'snow_globe' + | 'candy_cane' + | 'present_hat' + | 'grinch' + | 'decoration_ball' + | 'lucky_dragon' + | 'monk' + | 'sandwich' + | 'monitor' + | 'unlock_machine' + | 'parrot' + | 'golem' + | 'snowball' + | 'rabbit' + | 'letter_i' + | 'odin' + | 'scavenger' + | 'space' + | 'mage' + | 'astronaut' + | 'wood_steve' + | 'ender_dragon' + | 'clown' + | 'scarecrow2' + | 'halloween_ghast' + | 'walrus' + | 'stone_steve' + | 'gingerbread' + | 'snowman' + | 'white_wizard' + | 'turtle' + | 'cauldron' + | 'elfboy' + | 'letter_c' + | 'dinosaur' + | 'letter_f' + | 'minotaur' + | 'hp8' + | 'number_0' + | 'reindeer' + | 'robo_bird' + | 'pug_white' + | 'basketball' + | 'letter_m' + | 'scarecrow' + | 'hypixel_h' + | 'magic_dog' + | 'easter_basket' + | 'bauble' + | 'joe_penguin' + | 'gingerbread_man' + | 'ghost' + | 'santa' + | 'comet_reindeer' + | 'siren' + | 'halloween_marionette' + | 'clown2' + | 'doge' + | 'werewolf' + | 'stocking' + | 'derpy_snowman' + | 'halloween_evil_pumpkin' + | 'crown' + | 'gorilla' + | 'shibe' + | 'eater' + | 'devourer' + | 'pumpkin' + | 'iron_steve' + | 'traffic_light' + | 'ice_mage' + | 'spooked_pufferfish' + | 'gold_steve'; + +export type PlayerCosmeticsGadget = + | 'explosive_bow' + | 'snowman' + | 'holiday_tree' + | 'advent_proof' + | 'christmas_cracker' + | 'exploding_sheep' + | 'tree_planter' + | 'flaming_egg_launcher' + | 'bunny_party' + | 'magic_carpet' + | 'parachute' + | 'paintball_gun' + | 'fortune_cookie' + | 'fire_trail' + | 'rush_pearl' + | 'rocket' + | 'wizardwand' + | 'jetpack' + | 'horror_movie' + | 'bbq_grill' + | 'flower_giver' + | 'tic_tac_toe' + | 'paint_trail' + | 'volleyball' + | 'secret_service' + | 'dice' + | 'swarm' + | 'party_popper' + | 'tnt_fountain' + | 'hype_train' + | 'teleporter' + | 'grappling_hook' + | 'ghosts' + | 'tetherball' + | 'hot_potato' + | 'radio' + | 'rock_paper_shears' + | 'meteorite' + | 'disco_ball' + | 'latte' + | 'sled' + | 'new_year_countdown' + | 'tidal_wave' + | 'pinata' + | 'tennis_ball' + | 'water_balloon' + | 'creeper_astronaut' + | 'poop_bomb' + | 'rainbow' + | 'chicken_cannon' + | 'bat_launcher' + | 'firework_launcher' + | 'treat_fountain' + | 'holiday_choir' + | 'snow_globe' + | 'flammable_grappling_hook' + | 'cornucopia' + | 'trampoline' + | 'anniversary_trampoline' + | 'diving_board' + | 'dreidel' + | 'let_snow' + | 'pong' + | 'giant_skeleton' + | 'levitation_gun' + | 'new_year' + | 'swing' + | 'pocket_beach' + | 'trick_or_treat' + | 'pumpkin_cannon' + | 'duels_banner' + | 'sand_castle' + | 'scare_crow' + | 'ice_skating' + | 'ice_cream_stand' + | 'anniversary_knight' + | 'corrupted' + | 'pumpkin_rain' + | 'graveyard' + | 'skywars_banner' + | 'tournament_banner' + | 'tournament_banner_grinch_simulator_0' + | 'frisbee' + | 'dj_booth' + | 'witch_cauldron' + | 'golden_chicken_statue'; + +export type PlayerCosmeticsMorph = + | 'rabbit' + | 'spider' + | 'pig' + | 'sheep' + | 'chicken' + | 'zombie' + | 'creeper' + | 'cow' + | 'guardian' + | 'iron_golem' + | 'enderman' + | 'skeleton' + | 'wither_skeleton' + | 'blaze' + | 'snow_morph' + | 'grinch' + | 'cave_spider' + | 'witch'; + +export type PlayerCosmeticsCloak = + | 'monarch_wings' + | 'easter_egg' + | 'sweetwings' + | 'scanner' + | 'firewings' + | 'rose' + | 'clover' + | 'achievement_points' + | 'mystical' + | 'downpour' + | 'comets' + | 'frozen_dragon_wings' + | 'superhero' + | 'bone_wings' + | 'acid_rain' + | 'dark_angel' + | 'shimmering_wings' + | 'shaman' + | 'icy_wings' + | 'frosty_cloak' + | 'vampire_wings' + | 'menorah' + | 'rainy_day' + | 'egg_scanner' + | 'dark_energy' + | 'storm' + | 'blizzard' + | 'snowball' + | 'candy_cane' + | 'spooky_wings' + | 'twisted' + | 'colorbox' + | 'candy_spiral' + | 'lovely'; + +export type PlayerCosmeticsTaunt = + | 'goodbye' + | 'hype_dance' + | 'victory' + | 'clapping' + | 'wave_dance' + | 'cool_dance' + | 'hula' + | 'mind' + | 'jump' + | 'snowball_toss' + | 'can' + | 'zombie_dance' + | 'possessed' + | 'hi_5' + | 'sun' + | 'karaoke' + | 'graduation' + | 'ballet' + | 'treasure' + | 'crab_dance'; + +export type PlayerCosmeticsRankColor = + | 'gold' + | 'green' + | 'yellow' + | 'light_purple' + | 'white' + | 'blue' + | 'dark_green' + | 'dark_red' + | 'dark_aqua' + | 'dark_purple' + | 'dark_gray' + | 'black'; + +export type PlayerCosmeticsParticlePack = + | 'frozen' + | 'spring' + | 'huge_explosion' + | 'snow_trail' + | 'tinsel' + | 'spooky' + | 'red_dust' + | 'splash'; + +export type PlayerCosmeticsClickEffects = 'skull' | 'blizzard' | 'easter_egg' | 'holiday_firework' | 'hypixel'; +export type ChatChannel = 'ALL' | 'PARTY' | 'GUILD' | 'OFFICER' | 'PM' | 'SKYBLOCK_COOP'; +export type ShopSort = 'rarity_ascending' | 'rarity_descending' | SortName; +export type BuildBattleEmblemIcon = 'ALPHA' | 'OMEGA' | 'PODIUM' | 'REMINISCENCE' | 'RICH'; +export type BuildBattleLeaderboardSettingsMode = + | 'ALL_MODES' + | 'GUESS_THE_BUILD' + | 'PRO' + | 'SOLO' + | 'SOLO_LATEST' + | 'SPEED_BUILDERS' + | 'TEAMS'; +export type BuildBattleHat = + | 'hats_ancient_hat' + | 'hats_bakers_hat' + | 'hats_bankers_draught' + | 'hats_batters_helmet' + | 'hats_boogie_woogie_hat' + | 'hats_bounty_hat' + | 'hats_builder_hat' + | 'hats_canada_hat' + | 'hats_creeper_head' + | 'hats_desert_hat' + | 'hats_emerald_hat' + | 'hats_forest_hat' + | 'hats_frying_pan' + | 'hats_gnome_hat' + | 'hats_goldigger' + | 'hats_hardcore_hat' + | 'hats_jumpman_hat' + | 'hats_let_there_be_light_hat' + | 'hats_lumberjack_hat' + | 'hats_luminous_hat' + | 'hats_master_builder_hat' + | 'hats_miners_hat' + | 'hats_musician_hat' + | 'hats_over_the_rainbow' + | 'hats_scholars_cap' + | 'hats_scotland_hat' + | 'hats_shiny_hat' + | 'hats_shocked_hat' + | 'hats_skeleton_skull' + | 'hats_spaceman_helmet' + | 'hats_summer_hat' + | 'hats_the_attendant' + | 'hats_the_milkman' + | 'hats_the_superfan' + | 'hats_tnt_hat' + | 'hats_treasure_hat' + | 'hats_winter_hat' + | 'hats_wither_skull' + | 'hats_zombie_skull'; +export type BuildBattleSuit = + | 'suits_all_yellow' + | 'suits_blaze' + | 'suits_budder' + | 'suits_buildbattlesuit' + | 'suits_bumbleebee' + | 'suits_candy_corn' + | 'suits_commander' + | 'suits_disco' + | 'suits_elite' + | 'suits_fashionista' + | 'suits_invader' + | 'suits_majestic' + | 'suits_marine' + | 'suits_medieval' + | 'suits_metallic' + | 'suits_monochrome' + | 'suits_primary_colors' + | 'suits_revenge' + | 'suits_santa' + | 'suits_shiny' + | 'suits_slime' + | 'suits_snow' + | 'suits_soldier' + | 'suits_space' + | 'suits_special_ops' + | 'suits_swat'; +export type BuildBattleVictoryDance = + | 'better_fireworks' + | 'twerk_apocalypse' + | 'victory_dance_animal_rain' + | 'victory_dance_anvil_rain' + | 'victory_dance_cold_snap' + | 'victory_dance_egg_meteors' + | 'victory_dance_fireworks' + | 'victory_dance_ghast_rider' + | 'victory_dance_graveyardrave' + | 'victory_dance_guardians' + | 'victory_dance_heat_wave' + | 'victory_dance_meteor_shower' + | 'victory_dance_night_shift' + | 'victory_dance_pumpkin_bomber' + | 'victory_dance_rainbow_dolly' + | 'victory_dance_rooted' + | 'victory_dance_snow_bomber' + | 'victory_dance_special_fireworks' + | 'victory_dance_terror' + | 'victory_dance_toy_stick' + | 'victory_dance_twerk_apocalypse' + | 'victory_dance_winter_twister' + | 'victory_dance_wither_rider' + | 'victory_dance_yeehaw'; +export type BuildBattleBackdrop = + | 'backdrops_aquarium' + | 'backdrops_art' + | 'backdrops_artifact' + | 'backdrops_astro' + | 'backdrops_at_the_beach' + | 'backdrops_back_to_school' + | 'backdrops_city' + | 'backdrops_coffee' + | 'backdrops_cozy' + | 'backdrops_desert' + | 'backdrops_fireplace' + | 'backdrops_graveyard' + | 'backdrops_greyspire' + | 'backdrops_happy_world' + | 'backdrops_haunted_room' + | 'backdrops_hypixel_lobby' + | 'backdrops_knights_hall' + | 'backdrops_lunar1' + | 'backdrops_lunar2' + | 'backdrops_midnighttown' + | 'backdrops_monastery' + | 'backdrops_mountains' + | 'backdrops_pond' + | 'backdrops_potionmaking' + | 'backdrops_pumpkin_god' + | 'backdrops_ruins' + | 'backdrops_skyline' + | 'backdrops_snowflake' + | 'backdrops_ten_anniversary' + | 'backdrops_townpocalypse' + | 'backdrops_tropical_sands' + | 'backdrops_vanilla' + | 'backdrops_village' + | 'backdrops_web' + | 'backdrops_year_of_the_snake'; +export type BuildBattleIsland = + | 'island_bbq' + | 'island_clouds' + | 'island_desert' + | 'island_dice' + | 'island_dwarven_king' + | 'island_fish_bowl' + | 'island_flower' + | 'island_frog' + | 'island_gothic' + | 'island_greek_temple' + | 'island_hourglass' + | 'island_jerry' + | 'island_jungle' + | 'island_mesa' + | 'island_mines' + | 'island_mushroom' + | 'island_mycelium' + | 'island_nether' + | 'island_pickle_jar' + | 'island_sand_fort' + | 'island_sci_fi' + | 'island_serpent' + | 'island_snow' + | 'island_steam_punk' + | 'island_taiga' + | 'island_tiki' + | 'island_tnt' + | 'island_tower' + | 'island_waterfall'; +export type BuildBattleMovementTrail = + | 'movement_trail_black_smoke' + | 'movement_trail_fire' + | 'movement_trail_frosty' + | 'movement_trail_green_star'; +export type BuildBattleSong = + | 'aztec' + | 'balrog' + | 'blockjitsu' + | 'bohemian_rhapsody' + | 'cantina' + | 'cirno_noteblock' + | 'comptine' + | 'corpse_party' + | 'creeper_chase' + | 'creeper_salsa' + | 'crossing_field' + | 'end_lobby' + | 'fireflies' + | 'flight_bumblebee' + | 'flowering_night' + | 'fortune_start_jingle' + | 'fortune_stop_jingle' + | 'gamemode8' + | 'ghostly_band' + | 'happy_fish' + | 'hide_and_seek_sad' + | 'hilly_escapades' + | 'holiday' + | 'hoppin_blocks' + | 'i_cant_wait' + | 'i_wish_it_could_be_christmas_everday' + | 'icy_breeze' + | 'immortal_smoke' + | 'interdimensional' + | 'journey' + | 'journey_in_the_sky' + | 'kart_olympus' + | 'kewl' + | 'kirby_gourmet' + | 'let_it_go' + | 'license_to_infinity' + | 'lunatic_eyes' + | 'mad_world' + | 'mayan' + | 'mayan_theme' + | 'moonrvg' + | 'nyan_cat' + | 'onward' + | 'owen' + | 'pokemon_theme' + | 'pump_it_up' + | 'race_away' + | 'red_brick_house' + | 'retro_track' + | 'santa_claus_is_coming_to_town' + | 'seppette_of_the_dead_princess' + | 'silent_wish' + | 'storms' + | 'suspenseful' + | 'walking_mega' + | 'welcome'; +export type BuildBattlePackageItem = + | 'all_yellow' + | 'ancient_hat' + | 'anvil_rain' + | 'aquarium' + | 'astro' + | 'at_the_beach' + | 'aztec_track' + | 'back_to_school' + | 'backstreet' + | 'bad_apple' + | 'bakers_hat' + | 'bankers_draught' + | 'batters_helmet' + | 'bb_achieve_flag' + | 'bb_stat_flag' + | 'bblc' + | 'black_notes' + | 'bleeding_out' + | 'boogie_woogie_hat' + | 'bounty_hat' + | 'budder' + | 'buildbattlesuit' + | 'builder_hat' + | 'bumbleebee' + | 'canada_hat' + | 'carousel_ride' + | 'cold_snap' + | 'commander' + | 'creeper_head' + | 'desert_hat' + | 'disco' + | 'dungeon_drama' + | 'elite' + | 'emblem.color_unlocked' + | 'emerald_hat' + | 'entertainer' + | 'fashionista' + | 'feasibility' + | 'final_cubic_generator' + | 'fireworks' + | 'flight_in_fantasia' + | 'forester_hat' + | 'frying_pan' + | 'gamemode_88' + | 'ghast_rider' + | 'gnome_hat' + | 'goldigger' + | 'graveyard' + | 'guardians' + | 'happy' + | 'happy_world' + | 'hardcore_hat' + | 'haunted_room' + | 'hide_and_seek' + | 'how_you_love_me' + | 'hypixel_lobby' + | 'invader' + | 'jumpman_hat' + | 'knights_hall' + | 'larger_than_life' + | 'last_christmas' + | 'let_there_be_light_hat' + | 'level1' + | 'level2' + | 'level3' + | 'level4' + | 'level5' + | 'lobby' + | 'lobby_song' + | 'lumberjack_hat' + | 'luminous_hat' + | 'mad_jack' + | 'maidens_cappriccio' + | 'majestic' + | 'marine' + | 'master_builder_hat' + | 'mbison' + | 'medieval' + | 'metallic' + | 'meteor_shower' + | 'minecraft_is_my_life' + | 'miners_hat' + | 'monastery' + | 'mountains' + | 'musician_hat' + | 'native_faith' + | 'night_shift' + | 'nyny' + | 'olympus' + | 'over_the_rainbow' + | 'phwee' + | 'pond' + | 'potionmaking' + | 'primary_colors' + | 'pumpkin_god' + | 'rainbow_dolly' + | 'retro' + | 'revenge' + | 'reverse_ideology' + | 'rockin_around_the_christmas_tree' + | 'roll' + | 'santa' + | 'scholars_cap' + | 'scotland_hat' + | 'setbbtheme' + | 'shiny' + | 'shiny_hat' + | 'shocked_hat' + | 'similar' + | 'skeleton_skull' + | 'sky_of_trees' + | 'slime' + | 'snow' + | 'soldier' + | 'space' + | 'spaceman_helmet' + | 'special_ops' + | 'suit.monochrome' + | 'summer_hat' + | 'super_votes' + | 'swat' + | 'swd33' + | 'terror' + | 'the_attendant' + | 'the_milkman' + | 'the_superfan' + | 'tnt_hat' + | 'townpocalypse' + | 'toy_stick' + | 'traceway' + | 'treasure_hat' + | 'vessel_of_stars' + | 'victory' + | 'voting' + | 'what_ive_done' + | 'winter_hat' + | 'winter_wonderland' + | 'wither_rider' + | 'wither_skull' + | 'yeehaw' + | 'zelda_chest_opening' + | 'zinnias_theme' + | 'zombie_skull' + | BuildBattleHat + | BuildBattleSuit + | BuildBattleVictoryDance + | BuildBattleBackdrop + | BuildBattleMovementTrail + | BuildBattleIsland + | BuildBattleSong; +export type BuildBattleTitle = + | 'Rookie' + | 'Untrained' + | 'Amatuer' + | 'Prospect' + | 'Apprentice' + | 'Experienced' + | 'Seasoned' + | 'Trained' + | 'Skilled' + | 'Talented' + | 'Professional' + | 'Artisan' + | 'Expert' + | 'Master' + | 'Legend' + | 'Grandmaster' + | 'Celestial' + | 'Divine' + | 'Ascended'; + +export type LeaderboardSettingsResetType = 'MONTHLY' | 'NEVER' | 'WEEKLY'; + +export type PrivateGameSettingsGameSpeed = 'No Speed' | 'Speed I' | 'Speed II' | 'Speed III'; +export type PrivateGameSettingsHealthBuff = 'Normal Health' | 'Double Health' | 'Triple Health'; + +export type MurderMysteryDescentMode = 'ASSASSINS' | 'CLASSIC' | 'INFECTION'; +export type MurderMysteryMode = + | 'MURDER_ASSASSINS' + | 'MURDER_CLASSIC' + | 'MURDER_DOUBLE_UP' + | 'MURDER_HARDCORE' + | 'MURDER_INFECTION' + | 'MURDER_SHOWDOWN'; +export type MurderMysteryVictoryDance = + | 'victory_dance_abominable_snowman' + | 'victory_dance_bad_weather' + | 'victory_dance_bat_swarm' + | 'victory_dance_chicken_rider' + | 'victory_dance_chinese_dragon' + | 'victory_dance_cold_snap' + | 'victory_dance_dragon_fire' + | 'victory_dance_easter_bunnies' + | 'victory_dance_egg_meteors' + | 'victory_dance_exploding_bunnies' + | 'victory_dance_festive_music' + | 'victory_dance_fireworks' + | 'victory_dance_floating_lanterns' + | 'victory_dance_flower_bed' + | 'victory_dance_graveyardrave' + | 'victory_dance_guardians' + | 'victory_dance_haunted' + | 'victory_dance_heat_wave' + | 'victory_dance_infection' + | 'victory_dance_love_aura' + | 'victory_dance_meteor_shower' + | 'victory_dance_night_shift' + | 'victory_dance_pumpkin_bomber' + | 'victory_dance_pumpkin_laser' + | 'victory_dance_pumpkin_patch' + | 'victory_dance_puppy_party' + | 'victory_dance_rabbit_meteors' + | 'victory_dance_rainbow_dolly' + | 'victory_dance_raining_pigs' + | 'victory_dance_raining_swords' + | 'victory_dance_rooted' + | 'victory_dance_snow_bomber' + | 'victory_dance_snowman_army' + | 'victory_dance_swarm' + | 'victory_dance_to_build_a_snowman' + | 'victory_dance_toy_stick' + | 'victory_dance_twerk_apocalypse' + | 'victory_dance_winter_twister' + | 'victory_dance_wither_rider' + | 'victory_dance_yeehaw'; +export type MurderMysteryVictoryDanceRaw = + | 'abominable_snowman' + | 'bad_weather' + | 'bat_swarm' + | 'chicken_rider' + | 'chinese_dragon' + | 'cold_snap' + | 'dragon_fire' + | 'easter_bunnies' + | 'egg_meteors' + | 'exploding_bunnies' + | 'festive_music' + | 'fireworks' + | 'floating_lanterns' + | 'flower_bed' + | 'graveyardrave' + | 'guardians' + | 'haunted' + | 'heat_wave' + | 'infection' + | 'love_aura' + | 'meteor_shower' + | 'night_shift' + | 'pumpkin_bomber' + | 'pumpkin_laser' + | 'pumpkin_patch' + | 'puppy_party' + | 'rabbit_meteors' + | 'rainbow_dolly' + | 'raining_pigs' + | 'raining_swords' + | 'rooted' + | 'snow_bomber' + | 'snowman_army' + | 'swarm' + | 'to_build_a_snowman' + | 'toy_stick' + | 'twerk_apocalypse' + | 'winter_twister' + | 'wither_rider' + | 'yeehaw'; +export type MurderMysteryProjectileTrail = + | 'projectile_trail_Jack_O_Lantern_Trail' + | 'projectile_trail_angry_villager' + | 'projectile_trail_bee' + | 'projectile_trail_black_smoke' + | 'projectile_trail_blood' + | 'projectile_trail_blue_dust' + | 'projectile_trail_bone' + | 'projectile_trail_bubbles' + | 'projectile_trail_candy_basket' + | 'projectile_trail_chains' + | 'projectile_trail_cheese' + | 'projectile_trail_cursedflame' + | 'projectile_trail_derailed' + | 'projectile_trail_ender' + | 'projectile_trail_fanged' + | 'projectile_trail_fiery_wind' + | 'projectile_trail_fire' + | 'projectile_trail_fireball' + | 'projectile_trail_firework' + | 'projectile_trail_flame_rings' + | 'projectile_trail_glitch' + | 'projectile_trail_green_star' + | 'projectile_trail_hanukkah' + | 'projectile_trail_hearts' + | 'projectile_trail_hoops' + | 'projectile_trail_howling_wind' + | 'projectile_trail_icicle' + | 'projectile_trail_jack_o_lantern_trail' + | 'projectile_trail_lava' + | 'projectile_trail_let_there_be_leather' + | 'projectile_trail_lunar_dust' + | 'projectile_trail_magic' + | 'projectile_trail_magic_wind' + | 'projectile_trail_merry' + | 'projectile_trail_notes' + | 'projectile_trail_orb' + | 'projectile_trail_peep_hatching' + | 'projectile_trail_potion' + | 'projectile_trail_potion_rain' + | 'projectile_trail_present' + | 'projectile_trail_pumpkin_pie' + | 'projectile_trail_pumpkin_spice_powered' + | 'projectile_trail_pumpkin_volley_trail' + | 'projectile_trail_purple_dust' + | 'projectile_trail_rainbow' + | 'projectile_trail_rainy' + | 'projectile_trail_random' + | 'projectile_trail_red_dust' + | 'projectile_trail_rocket' + | 'projectile_trail_rose' + | 'projectile_trail_slime' + | 'projectile_trail_snowball' + | 'projectile_trail_snowball_rain' + | 'projectile_trail_sparkler' + | 'projectile_trail_spiders_silk' + | 'projectile_trail_spooky_wind' + | 'projectile_trail_spring_ribbons' + | 'projectile_trail_stormy' + | 'projectile_trail_tinsel' + | 'projectile_trail_trick_or_treat' + | 'projectile_trail_twin_dragon' + | 'projectile_trail_twirling_snowflake' + | 'projectile_trail_twisted_trail' + | 'projectile_trail_water' + | 'projectile_trail_white_smoke' + | 'projectile_trail_wingman' + | 'projectile_trail_wisp_whirlwind' + | 'projectile_trail_wither_skull'; +export type MurderMysteryProjectileTrailRaw = + | 'Jack_O_Lantern_Trail' + | 'angry_villager' + | 'bee' + | 'black_smoke' + | 'blood' + | 'blue_dust' + | 'bone' + | 'bubbles' + | 'candy_basket' + | 'chains' + | 'cheese' + | 'cursedflame' + | 'derailed' + | 'ender' + | 'fanged' + | 'fiery_wind' + | 'fire' + | 'fireball' + | 'firework' + | 'flame_rings' + | 'glitch' + | 'green_star' + | 'hanukkah' + | 'hearts' + | 'hoops' + | 'howling_wind' + | 'icicle' + | 'jack_o_lantern_trail' + | 'lava' + | 'let_there_be_leather' + | 'lunar_dust' + | 'magic' + | 'magic_wind' + | 'merry' + | 'notes' + | 'orb' + | 'peep_hatching' + | 'potion' + | 'potion_rain' + | 'present' + | 'pumpkin_pie' + | 'pumpkin_spice_powered' + | 'pumpkin_volley_trail' + | 'purple_dust' + | 'rainbow' + | 'rainy' + | 'random' + | 'red_dust' + | 'rocket' + | 'rose' + | 'slime' + | 'snowball' + | 'snowball_rain' + | 'sparkler' + | 'spiders_silk' + | 'spooky_wind' + | 'spring_ribbons' + | 'stormy' + | 'tinsel' + | 'trick_or_treat' + | 'twin_dragon' + | 'twirling_snowflake' + | 'twisted_trail' + | 'water' + | 'white_smoke' + | 'wingman' + | 'wisp_whirlwind' + | 'wither_skull'; +export type MurderMysteryLastWords = + | 'last_words_10th_anniversary' + | 'last_words_buzz' + | 'last_words_chicken' + | 'last_words_condescending' + | 'last_words_crybaby' + | 'last_words_deathcount' + | 'last_words_dontcare' + | 'last_words_eggstraordinary_puns' + | 'last_words_eggy' + | 'last_words_fashion' + | 'last_words_festive' + | 'last_words_glutton' + | 'last_words_hypixel_fan' + | 'last_words_jolly' + | 'last_words_meme' + | 'last_words_meow' + | 'last_words_mrobvious' + | 'last_words_naughty' + | 'last_words_oxymorons' + | 'last_words_philosoph' + | 'last_words_pirate' + | 'last_words_protips' + | 'last_words_rage' + | 'last_words_rats' + | 'last_words_reindeer' + | 'last_words_spooky' + | 'last_words_squeak' + | 'last_words_superstitions' + | 'last_words_trick_or_treat' + | 'last_words_woof' + | 'last_words_wrapped_up'; +export type MurderMysteryLastWordsRaw = + | '10th_anniversary' + | 'buzz' + | 'chicken' + | 'condescending' + | 'crybaby' + | 'deathcount' + | 'dontcare' + | 'eggstraordinary_puns' + | 'eggy' + | 'fashion' + | 'festive' + | 'glutton' + | 'hypixel_fan' + | 'jolly' + | 'meme' + | 'meow' + | 'mrobvious' + | 'naughty' + | 'oxymorons' + | 'philosoph' + | 'pirate' + | 'protips' + | 'rage' + | 'rats' + | 'reindeer' + | 'spooky' + | 'squeak' + | 'superstitions' + | 'trick_or_treat' + | 'woof' + | 'wrapped_up'; +export type MurderMysteryKnifeSkin = + | 'knife_skin_10000_spoons' + | 'knife_skin_apple' + | 'knife_skin_basted_turkey' + | 'knife_skin_blaze_stick' + | 'knife_skin_bloody_brick' + | 'knife_skin_bone' + | 'knife_skin_campfire_leftovers' + | 'knife_skin_carrot_on_stick' + | 'knife_skin_cheapo' + | 'knife_skin_cheese' + | 'knife_skin_chewed_bush' + | 'knife_skin_diamond_shovel' + | 'knife_skin_double_death_scythe' + | 'knife_skin_dragon_egg' + | 'knife_skin_earthen_dagger' + | 'knife_skin_easter_basket' + | 'knife_skin_farming_implement' + | 'knife_skin_feather' + | 'knife_skin_fragile_plant' + | 'knife_skin_frisbee' + | 'knife_skin_glistening_melon' + | 'knife_skin_gold_digger' + | 'knife_skin_grilled_steak' + | 'knife_skin_grimoire' + | 'knife_skin_ice_shard' + | 'knife_skin_mouse_trap' + | 'knife_skin_prickly' + | 'knife_skin_pumpkin_pie' + | 'knife_skin_rudolphs_nose' + | 'knife_skin_rudolphs_snack' + | 'knife_skin_salmon' + | 'knife_skin_scythe' + | 'knife_skin_shears' + | 'knife_skin_shiny_snack' + | 'knife_skin_shovel' + | 'knife_skin_shred' + | 'knife_skin_spray_painted_shovel' + | 'knife_skin_stake' + | 'knife_skin_stick' + | 'knife_skin_stick_with_hat' + | 'knife_skin_sweet_treat' + | 'knife_skin_timber' + | 'knife_skin_wood_axe'; +export type MurderMysteryKnifeSkinRaw = + | '10000_spoons' + | 'apple' + | 'basted_turkey' + | 'blaze_stick' + | 'bloody_brick' + | 'bone' + | 'campfire_leftovers' + | 'carrot_on_stick' + | 'cheapo' + | 'cheese' + | 'chewed_bush' + | 'diamond_shovel' + | 'double_death_scythe' + | 'dragon_egg' + | 'earthen_dagger' + | 'easter_basket' + | 'farming_implement' + | 'feather' + | 'fragile_plant' + | 'frisbee' + | 'glistening_melon' + | 'gold_digger' + | 'grilled_steak' + | 'grimoire' + | 'ice_shard' + | 'mouse_trap' + | 'prickly' + | 'pumpkin_pie' + | 'rudolphs_nose' + | 'rudolphs_snack' + | 'salmon' + | 'scythe' + | 'shears' + | 'shiny_snack' + | 'shovel' + | 'shred' + | 'spray_painted_shovel' + | 'stake' + | 'stick' + | 'stick_with_hat' + | 'sweet_treat' + | 'timber' + | 'wood_axe'; +export type MurderMysteryKillNote = + | 'kill_note_ace' + | 'kill_note_angelic_jerry' + | 'kill_note_angry_cow' + | 'kill_note_angry_turkey' + | 'kill_note_bad_time' + | 'kill_note_bee_that_chicken' + | 'kill_note_big_brother' + | 'kill_note_big_skull' + | 'kill_note_boo' + | 'kill_note_boom' + | 'kill_note_bowtie' + | 'kill_note_buff_chicken' + | 'kill_note_bunny_gg' + | 'kill_note_bunny_lantern' + | 'kill_note_bunny_parkour' + | 'kill_note_bye' + | 'kill_note_candy_cane_guns' + | 'kill_note_candy_cane_sniper' + | 'kill_note_candy_king' + | 'kill_note_casual_christmas' + | 'kill_note_chalk_outline' + | 'kill_note_chickens' + | 'kill_note_chocolate_feast' + | 'kill_note_christmas_tree' + | 'kill_note_comfy_web' + | 'kill_note_cookies_and_milk' + | 'kill_note_cooler_climates' + | 'kill_note_creeper_rudolph' + | 'kill_note_curled_ox' + | 'kill_note_cute_bunny' + | 'kill_note_deadboy' + | 'kill_note_derailed' + | 'kill_note_dice_roll' + | 'kill_note_distinguished_ghost' + | 'kill_note_dogs_of_wisdom' + | 'kill_note_dragon' + | 'kill_note_easter_basket' + | 'kill_note_easter_creeper' + | 'kill_note_easter_eggs' + | 'kill_note_easter_sweater' + | 'kill_note_egg_decorations' + | 'kill_note_egg_gunner' + | 'kill_note_egg_hit' + | 'kill_note_egg_hunt' + | 'kill_note_egg_surprise' + | 'kill_note_egg_time' + | 'kill_note_faboolous' + | 'kill_note_fake_vampire' + | 'kill_note_family_photo_christmas' + | 'kill_note_fatality' + | 'kill_note_fireworks' + | 'kill_note_flowers_for_you' + | 'kill_note_found_u' + | 'kill_note_fried' + | 'kill_note_game_over' + | 'kill_note_garlic' + | 'kill_note_gas' + | 'kill_note_ggwp_pumpkin' + | 'kill_note_ghosts' + | 'kill_note_gift_spray' + | 'kill_note_gingerbread_jerry' + | 'kill_note_gingerbread_murderer' + | 'kill_note_golden_egg' + | 'kill_note_golem_picnic' + | 'kill_note_good_fortune' + | 'kill_note_gothic_jerry' + | 'kill_note_gradient' + | 'kill_note_haunted_conscience' + | 'kill_note_haunted_house' + | 'kill_note_hide_and_seek' + | 'kill_note_ice_scream_cart' + | 'kill_note_im' + | 'kill_note_jerry_island_poster' + | 'kill_note_lantern' + | 'kill_note_lazy_bunnies' + | 'kill_note_lazy_spring' + | 'kill_note_lion_dancer' + | 'kill_note_lucky_rabbit' + | 'kill_note_masks_power' + | 'kill_note_master_sword' + | 'kill_note_menorah' + | 'kill_note_mistletoe' + | 'kill_note_mob_party' + | 'kill_note_monster_under_bed' + | 'kill_note_murder_mystery_poster' + | 'kill_note_one_of_us' + | 'kill_note_ouija' + | 'kill_note_ox_costume' + | 'kill_note_painted_dragon_egg' + | 'kill_note_party_crasher' + | 'kill_note_peaceful' + | 'kill_note_perfect_sword_throw' + | 'kill_note_pig_peace' + | 'kill_note_poison' + | 'kill_note_pumpkin_farm' + | 'kill_note_pumpkin_pals' + | 'kill_note_pumpkinz' + | 'kill_note_puppy_surprise' + | 'kill_note_rabbit_celebration' + | 'kill_note_rabbit_costume' + | 'kill_note_rabbits_in_basket' + | 'kill_note_rat_costume' + | 'kill_note_rats_2020' + | 'kill_note_rose' + | 'kill_note_sabeetage' + | 'kill_note_sand_castle' + | 'kill_note_santa' + | 'kill_note_santa_slips' + | 'kill_note_scared' + | 'kill_note_sea_bass' + | 'kill_note_seasons_greetings' + | 'kill_note_self_portrait' + | 'kill_note_selfie' + | 'kill_note_shh' + | 'kill_note_silent_night' + | 'kill_note_skeleton_wave' + | 'kill_note_skull' + | 'kill_note_sleeps_and_treats' + | 'kill_note_sloth_burn' + | 'kill_note_smug_pig' + | 'kill_note_sniper_snowball' + | 'kill_note_snow_angel' + | 'kill_note_snow_jerry' + | 'kill_note_snowball_fight' + | 'kill_note_snowman_rampage' + | 'kill_note_snowman_surprise' + | 'kill_note_soulless' + | 'kill_note_split_personality' + | 'kill_note_spooky_game_over' + | 'kill_note_spooky_skelington' + | 'kill_note_super_effective' + | 'kill_note_surfs_up' + | 'kill_note_sweets' + | 'kill_note_the_great_egg_hunt' + | 'kill_note_tombstone' + | 'kill_note_trick_or_treat' + | 'kill_note_turkey_day' + | 'kill_note_ugly_bed_wars_sweater' + | 'kill_note_undead_lifesaving_association' + | 'kill_note_vampire_jerry' + | 'kill_note_watcher' + | 'kill_note_witch_please' + | 'kill_note_wrong_eggs' + | 'kill_note_year_of_the_dog' + | 'kill_note_year_of_the_dragon' + | 'kill_note_year_of_the_ox' + | 'kill_note_year_of_the_pig' + | 'kill_note_year_of_the_rabbit' + | 'kill_note_year_of_the_rat' + | 'kill_note_year_of_the_snake' + | 'kill_note_year_of_the_tiger'; +export type MurderMysteryKillNoteRaw = + | 'ace' + | 'angelic_jerry' + | 'angry_cow' + | 'angry_turkey' + | 'bad_time' + | 'bee_that_chicken' + | 'big_brother' + | 'big_skull' + | 'boo' + | 'boom' + | 'bowtie' + | 'buff_chicken' + | 'bunny_gg' + | 'bunny_lantern' + | 'bunny_parkour' + | 'bye' + | 'candy_cane_guns' + | 'candy_cane_sniper' + | 'candy_king' + | 'casual_christmas' + | 'chalk_outline' + | 'chickens' + | 'chocolate_feast' + | 'christmas_tree' + | 'comfy_web' + | 'cookies_and_milk' + | 'cooler_climates' + | 'creeper_rudolph' + | 'curled_ox' + | 'cute_bunny' + | 'deadboy' + | 'derailed' + | 'dice_roll' + | 'distinguished_ghost' + | 'dogs_of_wisdom' + | 'dragon' + | 'easter_basket' + | 'easter_creeper' + | 'easter_eggs' + | 'easter_sweater' + | 'egg_decorations' + | 'egg_gunner' + | 'egg_hit' + | 'egg_hunt' + | 'egg_surprise' + | 'egg_time' + | 'faboolous' + | 'fake_vampire' + | 'family_photo_christmas' + | 'fatality' + | 'fireworks' + | 'flowers_for_you' + | 'found_u' + | 'fried' + | 'game_over' + | 'garlic' + | 'gas' + | 'ggwp_pumpkin' + | 'ghosts' + | 'gift_spray' + | 'gingerbread_jerry' + | 'gingerbread_murderer' + | 'golden_egg' + | 'golem_picnic' + | 'good_fortune' + | 'gothic_jerry' + | 'gradient' + | 'haunted_conscience' + | 'haunted_house' + | 'hide_and_seek' + | 'ice_scream_cart' + | 'im' + | 'jerry_island_poster' + | 'lantern' + | 'lazy_bunnies' + | 'lazy_spring' + | 'lion_dancer' + | 'lucky_rabbit' + | 'masks_power' + | 'master_sword' + | 'menorah' + | 'mistletoe' + | 'mob_party' + | 'monster_under_bed' + | 'murder_mystery_poster' + | 'one_of_us' + | 'ouija' + | 'ox_costume' + | 'painted_dragon_egg' + | 'party_crasher' + | 'peaceful' + | 'perfect_sword_throw' + | 'pig_peace' + | 'poison' + | 'pumpkin_farm' + | 'pumpkin_pals' + | 'pumpkinz' + | 'puppy_surprise' + | 'rabbit_celebration' + | 'rabbit_costume' + | 'rabbits_in_basket' + | 'rat_costume' + | 'rats_2020' + | 'rose' + | 'sabeetage' + | 'sand_castle' + | 'santa' + | 'santa_slips' + | 'scared' + | 'sea_bass' + | 'seasons_greetings' + | 'self_portrait' + | 'selfie' + | 'shh' + | 'silent_night' + | 'skeleton_wave' + | 'skull' + | 'sleeps_and_treats' + | 'sloth_burn' + | 'smug_pig' + | 'sniper_snowball' + | 'snow_angel' + | 'snow_jerry' + | 'snowball_fight' + | 'snowman_rampage' + | 'snowman_surprise' + | 'soulless' + | 'split_personality' + | 'spooky_game_over' + | 'spooky_skelington' + | 'super_effective' + | 'surfs_up' + | 'sweets' + | 'the_great_egg_hunt' + | 'tombstone' + | 'trick_or_treat' + | 'turkey_day' + | 'ugly_bed_wars_sweater' + | 'undead_lifesaving_association' + | 'vampire_jerry' + | 'watcher' + | 'witch_please' + | 'wrong_eggs' + | 'year_of_the_dog' + | 'year_of_the_dragon' + | 'year_of_the_ox' + | 'year_of_the_pig' + | 'year_of_the_rabbit' + | 'year_of_the_rat' + | 'year_of_the_snake' + | 'year_of_the_tiger'; +export type MurderMysteryGravestone = + | 'gravestone_basic' + | 'gravestone_botanic' + | 'gravestone_creeper' + | 'gravestone_floral' + | 'gravestone_frozen_skeleton' + | 'gravestone_humble' + | 'gravestone_mossy_basic' + | 'gravestone_niche' + | 'gravestone_sand_castle' + | 'gravestone_unadorned' + | 'gravestone_unsubtle' + | 'gravestone_warrior'; +export type MurderMysteryGravestoneRaw = + | 'basic' + | 'botanic' + | 'creeper' + | 'floral' + | 'frozen_skeleton' + | 'humble' + | 'mossy_basic' + | 'niche' + | 'sand_castle' + | 'unadorned' + | 'unsubtle' + | 'warrior'; +export type MurderMysteryGesture = + | 'gesture_ballet' + | 'gesture_can_can' + | 'gesture_clapping' + | 'gesture_cool_dance' + | 'gesture_crab_dance' + | 'gesture_goodbye' + | 'gesture_graduation' + | 'gesture_high_five' + | 'gesture_hula' + | 'gesture_hype_dance' + | 'gesture_jump' + | 'gesture_karaoke' + | 'gesture_mind_blown' + | 'gesture_possessed' + | 'gesture_snowball_toss' + | 'gesture_sun' + | 'gesture_treasure' + | 'gesture_victory' + | 'gesture_wave_dance' + | 'gesture_zombie_dance'; +export type MurderMysteryGestureRaw = + | 'ballet' + | 'can_can' + | 'clapping' + | 'cool_dance' + | 'crab_dance' + | 'goodbye' + | 'graduation' + | 'high_five' + | 'hula' + | 'hype_dance' + | 'jump' + | 'karaoke' + | 'mind_blown' + | 'possessed' + | 'snowball_toss' + | 'sun' + | 'treasure' + | 'victory' + | 'wave_dance' + | 'zombie_dance'; +export type MurderMysteryFavoriteMap = + | 'favoritemap_ancient tomb' + | 'favoritemap_aquarium' + | 'favoritemap_archives' + | 'favoritemap_archives top floor' + | 'favoritemap_cattleridge farm' + | 'favoritemap_cruise ship' + | 'favoritemap_darkfall' + | 'favoritemap_easter world' + | 'favoritemap_gold rush' + | 'favoritemap_headquarters' + | 'favoritemap_hollywood' + | 'favoritemap_hypixel world' + | 'favoritemap_library' + | 'favoritemap_mountain' + | 'favoritemap_san peratico' + | 'favoritemap_san peratico v2' + | 'favoritemap_skyway pier' + | 'favoritemap_snowfall' + | 'favoritemap_snowglobe' + | 'favoritemap_spooky mansion' + | 'favoritemap_subway' + | 'favoritemap_towerfall' + | 'favoritemap_transport' + | 'favoritemap_villa' + | "favoritemap_widow's den"; +export type MurderMysteryFavoriteMapRaw = + | 'ancient tomb' + | 'aquarium' + | 'archives' + | 'archives top floor' + | 'cattleridge farm' + | 'cruise ship' + | 'darkfall' + | 'easter world' + | 'gold rush' + | 'headquarters' + | 'hollywood' + | 'hypixel world' + | 'library' + | 'mountain' + | 'san peratico' + | 'san peratico v2' + | 'skyway pier' + | 'snowfall' + | 'snowglobe' + | 'spooky mansion' + | 'subway' + | 'towerfall' + | 'transport' + | 'villa' + | "widow's den"; +export type MurderMysteryDeathCry = + | 'deathcry_coffin_close' + | 'deathcry_dark_portal' + | 'deathcry_dinosaur' + | 'deathcry_doused_lantern' + | 'deathcry_dragon_roar' + | 'deathcry_drama_queen' + | 'deathcry_firework' + | 'deathcry_ghosts_cry' + | 'deathcry_greed' + | 'deathcry_grumble' + | 'deathcry_grumpy_villager' + | 'deathcry_haunted_curse' + | 'deathcry_howl' + | 'deathcry_pig' + | 'deathcry_puddle' + | 'deathcry_rage' + | 'deathcry_sad_moo' + | 'deathcry_sad_puppy' + | 'deathcry_scurry' + | 'deathcry_sigh' + | 'deathcry_sniff' + | 'deathcry_squeal' + | 'deathcry_static' + | 'deathcry_up_in_flames'; +export type MurderMysteryDeathCryRaw = + | 'coffin_close' + | 'dark_portal' + | 'dinosaur' + | 'doused_lantern' + | 'dragon_roar' + | 'drama_queen' + | 'firework' + | 'ghosts_cry' + | 'greed' + | 'grumble' + | 'grumpy_villager' + | 'haunted_curse' + | 'howl' + | 'pig' + | 'puddle' + | 'rage' + | 'sad_moo' + | 'sad_puppy' + | 'scurry' + | 'sigh' + | 'sniff' + | 'squeal' + | 'static' + | 'up_in_flames'; +export type MurderMysteryAnimatedHat = + | 'animated_hat_blushy' + | 'animated_hat_chroma_slime' + | 'animated_hat_cyborg' + | 'animated_hat_demon_eyes' + | 'animated_hat_derpy_eyes' + | 'animated_hat_elfgirl' + | 'animated_hat_ender_pulse' + | 'animated_hat_eye' + | 'animated_hat_flower_crown' + | 'animated_hat_grinch' + | 'animated_hat_happy_dude' + | 'animated_hat_herobrine' + | 'animated_hat_pumpkin' + | 'animated_hat_rainbow_present' + | 'animated_hat_reindeer' + | 'animated_hat_sacred_cattle' + | 'animated_hat_santa' + | 'animated_hat_sherlock' + | 'animated_hat_shining_tiger'; +export type MurderMysteryAnimatedHatRaw = + | 'blushy' + | 'chroma_slime' + | 'cyborg' + | 'demon_eyes' + | 'derpy_eyes' + | 'elfgirl' + | 'ender_pulse' + | 'eye' + | 'flower_crown' + | 'grinch' + | 'happy_dude' + | 'herobrine' + | 'pumpkin' + | 'rainbow_present' + | 'reindeer' + | 'sacred_cattle' + | 'santa' + | 'sherlock' + | 'shining_tiger'; +export type MurderMysteryItem = + | 'displayed_youtuber_book' + | 'emblem.color_unlocked' + | 'increase_yt_detective' + | 'increase_yt_murderer' + | 'rudolphs_nose' + | 'sep2021AchievementSync' + | 'sep2021achievementsync' + | MurderMysteryVictoryDance + | MurderMysteryProjectileTrail + | MurderMysteryLastWords + | MurderMysteryKnifeSkin + | MurderMysteryKillNote + | MurderMysteryGravestone + | MurderMysteryGesture + | MurderMysteryFavoriteMap + | MurderMysteryDeathCry + | MurderMysteryAnimatedHat; +export type MurderMysteryMapName = + | 'ancient_tomb' + | 'aquarium' + | 'archives' + | 'archives_top_floor' + | 'cattleridge_farm' + | 'cruise_ship' + | 'darkfall' + | 'easter_world' + | 'gold_rush' + | 'headquarters' + | 'hollywood' + | 'hypixel_world' + | 'library' + | 'mountain' + | 'san_peratico' + | 'san_peratico_v2' + | 'skyway_pier' + | 'snowfall' + | 'snowglobe' + | 'spooky_mansion' + | 'subway' + | 'towerfall' + | 'transport' + | 'villa' + | "widow's_den"; +export type MurderMysteryRole = 'detective' | 'innocent' | 'murderer'; +export type MurderMysteryEmblemIcon = + | 'ALPHA' + | 'DIVINE' + | 'EQUIVALENCE' + | 'FLORIN' + | 'OMEGA' + | 'PODIUM' + | 'RICH' + | 'SIGMA' + | 'ZERO'; +export type ArcadePartyGamesGame = + | 'animal_slaughter' + | 'anvil_spleef' + | 'avalanche' + | 'bombardment' + | 'cannon_painting' + | 'chicken_rings' + | 'dive' + | 'fire_leapers' + | 'frozen_floor' + | 'high_ground' + | 'hoe_hoe_hoe' + | 'jigsaw_rush' + | 'jungle_jump' + | 'lab_escape' + | 'lawn_moower' + | 'minecart_racing' + | 'pig_fishing' + | 'pig_jousting' + | 'rpg_16' + | 'shooting_range' + | 'spider_maze' + | 'super_sheep' + | 'the_floor_is_lava' + | 'trampolinio' + | 'volcano' + | 'workshop'; +export type ArcadeZombiesMaps = 'alienarcadium' | 'badblood' | 'deadend' | 'prison'; +export type ArcadeZombiesDifficulty = 'normal' | 'hard' | 'rip'; +export type ArcadeEnderSpleefTrail = 'BLUE' | 'DEFAULT' | 'GREEN' | 'RAINBOW' | 'RED'; +export type ArcadeHoleInTheWallColor = 'CYAN' | 'DEFAULT' | 'FROSTED' | 'GREEN' | 'PUMPKIN' | 'RED' | 'YELLOW'; +export type ArcadeThrowOutDisguise = 'COW' | 'PIG' | 'SHEEP' | 'SNOWMAN' | 'ZOMBIE'; +export type ArcadeBountyHead = 'DEFAULT' | 'EMOTION' | 'HUNTER' | 'MOB' | 'TARGET'; +export type ArcadeMeleeWeapon = + | 'BASEBALL_BAT' + | 'CLIMBER_PICKAXE' + | 'COMBAT_KNIFE' + | 'CRICKET_BAT' + | 'FIRE_AXE' + | 'GOLF_CLUB' + | 'KATANA' + | 'KNIFE' + | 'MACHETE' + | 'POLICE_BATON'; +export type ArcadeMovementTrail = + | 'movement_trail_black_smoke' + | 'movement_trail_fire' + | 'movement_trail_frosty' + | 'movement_trail_green_star' + | 'movement_trail_magic' + | 'movement_trail_notes' + | 'movement_trail_rainbow' + | 'movement_trail_white_smoke'; +export type ArcadeProjectileTrail = + | 'projectile_trail_angry_villager' + | 'projectile_trail_bee' + | 'projectile_trail_black_smoke' + | 'projectile_trail_blood' + | 'projectile_trail_blue_dust' + | 'projectile_trail_bone' + | 'projectile_trail_candy_basket' + | 'projectile_trail_cursedflame' + | 'projectile_trail_ender' + | 'projectile_trail_fanged' + | 'projectile_trail_fire' + | 'projectile_trail_fireball' + | 'projectile_trail_firework' + | 'projectile_trail_flame_rings' + | 'projectile_trail_green_star' + | 'projectile_trail_hearts' + | 'projectile_trail_howling_wind' + | 'projectile_trail_icicle' + | 'projectile_trail_jack_o_lantern_trail' + | 'projectile_trail_lava' + | 'projectile_trail_magic' + | 'projectile_trail_notes' + | 'projectile_trail_potion' + | 'projectile_trail_pumpkin_pie' + | 'projectile_trail_pumpkin_spice_powered' + | 'projectile_trail_pumpkin_volley_trail' + | 'projectile_trail_purple_dust' + | 'projectile_trail_rainbow' + | 'projectile_trail_random' + | 'projectile_trail_red_dust' + | 'projectile_trail_rose' + | 'projectile_trail_slime' + | 'projectile_trail_sparkler' + | 'projectile_trail_spiders_silk' + | 'projectile_trail_stormy' + | 'projectile_trail_twirling_snowflake' + | 'projectile_trail_water' + | 'projectile_trail_white_smoke' + | 'projectile_trail_wisp_whirlwind'; +export type ArcadeVictoryDance = + | 'victory_dance_animal_rain' + | 'victory_dance_anvil_rain' + | 'victory_dance_chicken_rider' + | 'victory_dance_cold_snap' + | 'victory_dance_dragon_fire' + | 'victory_dance_egg_meteors' + | 'victory_dance_fireworks' + | 'victory_dance_graveyardrave' + | 'victory_dance_guardians' + | 'victory_dance_heat_wave' + | 'victory_dance_meteor_shower' + | 'victory_dance_pumpkin_bomber' + | 'victory_dance_pumpkin_laser' + | 'victory_dance_rooted' + | 'victory_dance_snow_bomber' + | 'victory_dance_special_fireworks' + | 'victory_dance_toy_stick' + | 'victory_dance_twerk_apocalypse' + | 'victory_dance_winter_twister' + | 'victory_dance_wither_rider'; +export type ArcadeTrail = + | 'blue_trail' + | 'emotion_trail' + | 'green_trail' + | 'hunter_trail' + | 'mob_trail' + | 'rainbow_trail' + | 'red_trail' + | 'target_trail'; +export type ArcadeWall = 'cyan_wall' | 'frosted_wall' | 'green_wall' | 'pumpkin_wall' | 'red_wall' | 'yellow_wall'; +export type ArcadeMelee = + | 'baseball_bat_melee' + | 'climber_pickaxe_melee' + | 'combat_knife_melee' + | 'cricket_bat_melee' + | 'fire_axe_melee' + | 'golf_club_melee' + | 'katana_melee' + | 'machete_melee' + | 'police_baton_melee'; +export type ArcadePixelPartyPants = + | 'aqua_pixel_party_pants' + | 'bling_pixel_party_pants' + | 'blurple_pixel_party_pants' + | 'breathable_pixel_party_pants' + | 'bright_pink_pixel_party_pants' + | 'cold_hearted_pixel_party_pants' + | 'deep_ocean_pixel_party_pants' + | 'disco_pixel_party_pants' + | 'hot_pink_pixel_party_pants' + | 'light_blue_pixel_party_pants' + | 'lime_pixel_party_pants' + | 'mint_pixel_party_pants' + | 'peach_pixel_party_pants' + | 'purple_pixel_party_pants' + | 'rank_color_pixel_party_pants' + | 'snow_pixel_party_pants' + | 'yellow_pixel_party_pants'; +export type ArcadePixelPartyDiscoHelmet = + | 'blue_pixel_party_disco_helmet' + | 'cyan_pixel_party_disco_helmet' + | 'green_pixel_party_disco_helmet' + | 'light_blue_pixel_party_disco_helmet' + | 'lime_pixel_party_disco_helmet' + | 'magenta_pixel_party_disco_helmet' + | 'orange_pixel_party_disco_helmet' + | 'party_pixel_party_disco_helmet' + | 'pink_pixel_party_disco_helmet' + | 'purple_pixel_party_disco_helmet' + | 'red_pixel_party_disco_helmet' + | 'spaceman_pixel_party_disco_helmet' + | 'yellow_pixel_party_disco_helmet'; +export type ArcadePixelParty = ArcadePixelPartyPants | ArcadePixelPartyDiscoHelmet; +export type ArcadeDisguise = 'cow_disguise' | 'sheep_disguise' | 'snowman_disguise' | 'zombie_disguise'; +export type ArcadePackage = + | 'mini_walls_mini_me' + | 'setbbtheme' + | ArcadeMovementTrail + | ArcadeProjectileTrail + | ArcadeVictoryDance + | ArcadeTrail + | ArcadeWall + | ArcadeMelee + | ArcadePixelPartyPants + | ArcadePixelPartyDiscoHelmet + | ArcadePixelParty + | ArcadeDisguise; +export type BedWarsFinalType = + | '' + | 'custom' + | 'drowning' + | 'entity_attack' + | 'entity_explosion' + | 'fall' + | 'fire' + | 'fire_tick' + | 'magic' + | 'projectile' + | 'suffocation' + | 'void' + | 'falling_block' + | 'lava' + | 'contact' + | 'thorns' + | 'wither' + | 'block_explosion'; +export type BedWarsModesEightOne = 'eight_one_oneblock' | 'eight_one_rush' | 'eight_one_ultimate' | 'eight_one'; +export type BedWarsModesEightTwo = + | 'tourney_bedwars_eight_two_1' + | 'tourney_bedwars_eight_two_0' + | 'eight_two_tourney' + | 'eight_two_armed' + | 'eight_two_lucky' + | 'eight_two_rush' + | 'eight_two_swap' + | 'eight_two_ultimate' + | 'eight_two_underworld' + | 'eight_two_voidless' + | 'eight_two'; +export type BedWarsModesFourThree = 'four_three'; +export type BedWarsModesFourFour = + | 'tourney_bedwars4s_1' + | 'tourney_bedwars4s_0' + | 'tourney_bedwars4s' + | 'four_four_armed' + | 'four_four_lucky' + | 'four_four_rush' + | 'four_four_swap' + | 'four_four_ultimate' + | 'four_four_underworld' + | 'four_four_voidless' + | 'four_four'; +export type BedWarsModesTwoFour = 'tourney_bedwars_two_four_0' | 'two_four'; +export type BedWarsModeId = + | 'castle' + | BedWarsModesEightOne + | BedWarsModesEightTwo + | BedWarsModesFourThree + | BedWarsModesFourFour + | BedWarsModesTwoFour; +export type BedWarsChallengeId = + | 'archer_only' + | 'assassin' + | 'cant_touch_this' + | 'capped_resources' + | 'collector' + | 'defuser' + | 'delayed_hitting' + | 'hotbar' + | 'invisible_shop' + | 'knockback_stick_only' + | 'master_assassin' + | 'mining_fatigue' + | 'no_healing' + | 'no_hitting' + | 'no_shift' + | 'no_sprint' + | 'no_swords' + | 'no_team_upgrades' + | 'no_utilities' + | 'patriot' + | 'protect_the_president' + | 'reset_armor' + | 'selfish' + | 'slow_generator' + | 'sponge' + | 'stamina' + | 'stop_light' + | 'toxic_rain' + | 'weighted_items' + | 'woodworker'; +export type BedWarsChallengeName = + | 'ARCHER_ONLY' + | 'ASSASSIN' + | 'CANT_TOUCH_THIS' + | 'COLLECTOR' + | 'DEFUSER' + | 'INVISIBLE_SHOP' + | 'KNOCKBACK_STICK_ONLY' + | 'MINING_FATIGUE' + | 'NO_HEALING' + | 'NO_HITTING' + | 'NO_SHIFT' + | 'NO_SPRINT' + | 'NO_TEAM_UPGRADES' + | 'NO_UTILITIES' + | 'PROTECT_THE_PRESIDENT' + | 'RESET_ARMOR' + | 'SELFISH' + | 'SLOW_GENERATOR' + | 'STOP_LIGHT' + | 'TOXIC_RAIN'; +export type BedWarsPrivateGameSettingsEventTime = '0.5x - Slower' | '1x - Normal' | '2x - Faster' | '4x - Fastest'; +export type BedWarsPrivateGameSettingsRespawnTime = '1 Second' | '5 Seconds' | '10 Seconds'; +export type BedWarsSettingsDeposit = 'ENABLED' | 'DISABLED' | 'HOLOGRAMS_HIDDEN'; +export type BedWarsSettingsSlumberItemNotification = 'CHAT_MESSAGES' | 'ABOVE_HOTBAR' | 'DISABLED'; +export type BedWarsSlumberBag = + | 'EXPLORERS_WALLET' + | 'HOTEL_STAFF_WALLET' + | 'LIGHT_IMPERIAL_WALLET' + | 'LIGHT_SLUMBERS_WALLET' + | 'MINI_WALLET' + | 'PLATINUM_MEMBERSHIP_WALLET'; +export type BedWarsQuickbuyPrivacy = 'MAX' | 'HIGH' | 'MEDIUM' | 'NONE'; +export type BedWarsUltimate = + | 'BUILDER' + | 'DEMOLITION' + | 'FROZO' + | 'GATHERER' + | 'HEALER' + | 'JUMPER' + | 'KANGAROO' + | 'SWORDSMAN'; +export type BedWarsBedDestroy = + | 'beddestroy_bedbugs' + | 'beddestroy_blizzard' + | 'beddestroy_burned_up' + | 'beddestroy_egg_popper' + | 'beddestroy_eggsplosion' + | 'beddestroy_firework' + | 'beddestroy_fishy' + | 'beddestroy_ghosts' + | 'beddestroy_glyph' + | 'beddestroy_ladybug' + | 'beddestroy_lava_explosion' + | 'beddestroy_lighting_strike' + | 'beddestroy_pig_missile' + | 'beddestroy_pigsplosion' + | 'beddestroy_present' + | 'beddestroy_pumpkin_explosion' + | 'beddestroy_shattering_ice_bed' + | 'beddestroy_squid_missile' + | 'beddestroy_stormy' + | 'beddestroy_thief' + | 'beddestroy_tornado' + | 'beddestroy_water_spout'; +export type BedWarsPackageChallenge = + | 'bw_challenge_archer_only_collected' + | 'bw_challenge_assassin_collected' + | 'bw_challenge_cant_touch_this_collected' + | 'bw_challenge_capped_resources_collected' + | 'bw_challenge_collector_collected' + | 'bw_challenge_defuser_collected' + | 'bw_challenge_delayed_hitting_collected' + | 'bw_challenge_hotbar_collected' + | 'bw_challenge_invisible_shop_collected' + | 'bw_challenge_knockback_stick_only_collected' + | 'bw_challenge_master_assassin_collected' + | 'bw_challenge_mining_fatigue_collected' + | 'bw_challenge_no_healing_collected' + | 'bw_challenge_no_hitting_collected' + | 'bw_challenge_no_shift_collected' + | 'bw_challenge_no_sprint_collected' + | 'bw_challenge_no_swords_collected' + | 'bw_challenge_no_team_upgrades_collected' + | 'bw_challenge_no_utilities_collected' + | 'bw_challenge_patriot_collected' + | 'bw_challenge_protect_the_president_collected' + | 'bw_challenge_reset_armor_collected' + | 'bw_challenge_selfish_collected' + | 'bw_challenge_slow_generator_collected' + | 'bw_challenge_sponge_collected' + | 'bw_challenge_stamina_collected' + | 'bw_challenge_stop_light_collected' + | 'bw_challenge_toxic_rain_collected' + | 'bw_challenge_weighted_items_collected' + | 'bw_challenge_woodworker_collected'; +export type BedWarsDeathCry = + | 'deathcry_arcade' + | 'deathcry_aww' + | 'deathcry_bat' + | 'deathcry_bazinga' + | 'deathcry_burp' + | 'deathcry_cat_hit' + | 'deathcry_dark_portal' + | 'deathcry_deflated_toy' + | 'deathcry_ding' + | 'deathcry_dinosaur' + | 'deathcry_doused_lantern' + | 'deathcry_dragon_roar' + | 'deathcry_dry_bones' + | 'deathcry_enderman' + | 'deathcry_energy' + | 'deathcry_fireball' + | 'deathcry_firework' + | 'deathcry_ghosts_cry' + | 'deathcry_gone' + | 'deathcry_grumble' + | 'deathcry_grumpy_villager' + | 'deathcry_guardian_death' + | 'deathcry_haunted_curse' + | 'deathcry_howl' + | 'deathcry_miracle' + | 'deathcry_monster_burp' + | 'deathcry_pig' + | 'deathcry_plop' + | 'deathcry_rage' + | 'deathcry_robot_mouse' + | 'deathcry_sad_moo' + | 'deathcry_sad_puppy' + | 'deathcry_scurry' + | 'deathcry_sniff' + | 'deathcry_splash' + | 'deathcry_squeak' + | 'deathcry_squeal'; +export type BedWarsFavoriteMap = + | 'favoritemap_acropolis' + | 'favoritemap_aetius' + | 'favoritemap_airshow' + | 'favoritemap_alaric' + | 'favoritemap_amazon' + | 'favoritemap_ambush' + | 'favoritemap_antenna' + | 'favoritemap_apollo' + | 'favoritemap_aqil' + | 'favoritemap_aquarium' + | 'favoritemap_arcade' + | 'favoritemap_archway' + | 'favoritemap_arid' + | 'favoritemap_artemis' + | 'favoritemap_ashfire' + | 'favoritemap_ashore' + | 'favoritemap_babylon' + | 'favoritemap_beeeee' + | 'favoritemap_bio-hazard' + | 'favoritemap_blitzen' + | 'favoritemap_blizzard bay' + | 'favoritemap_bloom' + | 'favoritemap_blossom' + | 'favoritemap_boardwalk' + | 'favoritemap_boletum' + | 'favoritemap_bucket bay' + | 'favoritemap_build site' + | 'favoritemap_bunnywars' + | 'favoritemap_burrow' + | 'favoritemap_carapace' + | 'favoritemap_cascade' + | 'favoritemap_casita' + | 'favoritemap_catalyst' + | 'favoritemap_cauldron' + | 'favoritemap_chained' + | 'favoritemap_chalk cliffs' + | 'favoritemap_cliffside' + | 'favoritemap_coastal' + | 'favoritemap_comet' + | 'favoritemap_crimson' + | 'favoritemap_crogorm' + | 'favoritemap_crypt' + | 'favoritemap_daolong' + | 'favoritemap_darkened' + | 'favoritemap_deadwood' + | 'favoritemap_deposit' + | 'favoritemap_dockyard' + | 'favoritemap_dragon light' + | 'favoritemap_dragonstar' + | 'favoritemap_dreamgrove' + | 'favoritemap_duye' + | 'favoritemap_easter basket' + | 'favoritemap_easter garden' + | 'favoritemap_eastwood' + | 'favoritemap_eden' + | 'favoritemap_egg factory' + | 'favoritemap_egg hunt' + | 'favoritemap_egg run' + | 'favoritemap_enchanted' + | 'favoritemap_extinction' + | 'favoritemap_fang outpost' + | 'favoritemap_fireplace' + | 'favoritemap_fort doon' + | 'favoritemap_foxtrots' + | 'favoritemap_frogiton' + | 'favoritemap_frosted' + | 'favoritemap_fruitbrawl' + | 'favoritemap_gateway' + | 'favoritemap_gelato' + | 'favoritemap_ghoulish' + | 'favoritemap_gingerbread' + | 'favoritemap_glacier' + | 'favoritemap_grave' + | 'favoritemap_graveship' + | 'favoritemap_grotto' + | 'favoritemap_halloweeneastwood' + | 'favoritemap_halloweenspeedway' + | 'favoritemap_haloweeneastwood' + | 'favoritemap_haloweenspeedway' + | 'favoritemap_hanging gardens' + | 'favoritemap_harvest' + | 'favoritemap_harvesting' + | 'favoritemap_hell temple' + | 'favoritemap_highland peaks' + | 'favoritemap_hollow' + | 'favoritemap_hollow hills' + | 'favoritemap_holmgang' + | 'favoritemap_horizon' + | 'favoritemap_impere' + | 'favoritemap_inca' + | 'favoritemap_infinite' + | 'favoritemap_invasion' + | 'favoritemap_ironclad' + | 'favoritemap_jurassic' + | 'favoritemap_katsu' + | 'favoritemap_keep' + | 'favoritemap_kubo' + | 'favoritemap_lectus' + | 'favoritemap_lighthouse' + | 'favoritemap_lightstone' + | 'favoritemap_loft' + | 'favoritemap_lost temple' + | 'favoritemap_lotice' + | 'favoritemap_lotus' + | 'favoritemap_lucky rush' + | 'favoritemap_lunarhouse' + | 'favoritemap_meadow' + | 'favoritemap_meso' + | 'favoritemap_mirage' + | 'favoritemap_montipora' + | 'favoritemap_mortuus' + | 'favoritemap_mystery' + | 'favoritemap_nebuc' + | 'favoritemap_nostalgia' + | 'favoritemap_nutcracker' + | 'favoritemap_obelisk' + | 'favoritemap_ominosity' + | 'favoritemap_orbit' + | 'favoritemap_orchestra' + | 'favoritemap_orchid' + | 'favoritemap_orientwood' + | 'favoritemap_paladin' + | 'favoritemap_paradox' + | 'favoritemap_pavilion' + | 'favoritemap_pernicious' + | 'favoritemap_pharaoh' + | 'favoritemap_pharoah' + | 'favoritemap_planet 98' + | 'favoritemap_playground' + | 'favoritemap_polygon' + | 'favoritemap_pool party' + | 'favoritemap_pumpkin bay' + | 'favoritemap_raze' + | 'favoritemap_relic' + | 'favoritemap_retreat' + | 'favoritemap_rigged' + | 'favoritemap_rise' + | 'favoritemap_rooftop' + | 'favoritemap_rooted' + | 'favoritemap_salmon bay' + | 'favoritemap_sanctuary' + | 'favoritemap_sanctum' + | 'favoritemap_sandcastle' + | "favoritemap_santa's rush" + | 'favoritemap_scareshow' + | 'favoritemap_scorched sands' + | 'favoritemap_screamway' + | 'favoritemap_seraph' + | 'favoritemap_serenity' + | 'favoritemap_shark attack' + | 'favoritemap_siege' + | 'favoritemap_silver birch' + | 'favoritemap_sky festival' + | 'favoritemap_sky rise' + | 'favoritemap_slumber' + | 'favoritemap_snails' + | 'favoritemap_snowkeep' + | 'favoritemap_snowy square' + | 'favoritemap_solace' + | 'favoritemap_speedway' + | 'favoritemap_springtide' + | 'favoritemap_steampumpkin' + | 'favoritemap_steampunk' + | 'favoritemap_stilted' + | 'favoritemap_stonekeep' + | 'favoritemap_sunflower' + | 'favoritemap_swashbuckle' + | 'favoritemap_sweet wonderland' + | 'favoritemap_symphonic' + | 'favoritemap_temple' + | 'favoritemap_tengshe' + | 'favoritemap_terminal' + | 'favoritemap_terraced' + | 'favoritemap_tigris' + | 'favoritemap_tinselbury' + | 'favoritemap_toro' + | 'favoritemap_toy factory' + | 'favoritemap_treenan' + | 'favoritemap_trick or treat' + | 'favoritemap_trick or yeet' + | 'favoritemap_turtle cove' + | 'favoritemap_tuzi' + | 'favoritemap_unchained' + | 'favoritemap_unturned' + | 'favoritemap_urban plaza' + | 'favoritemap_usagi' + | 'favoritemap_varyth' + | 'favoritemap_vigilante' + | 'favoritemap_waterfall' + | 'favoritemap_whiskers' + | 'favoritemap_winterland' + | 'favoritemap_wrapped up' + | 'favoritemap_yandi' + | 'favoritemap_yue' + | 'favoritemap_zarzul' + | 'favoritemap_zen plaza'; +export type BedwarsFigurine = + | 'figurine_alchemy' + | 'figurine_alex' + | 'figurine_blitz_star' + | 'figurine_bridge_egg' + | 'figurine_build_battle' + | 'figurine_cerberus' + | 'figurine_creeper' + | 'figurine_crossed_swords' + | 'figurine_dante' + | 'figurine_defended_bed' + | 'figurine_delivery_man' + | 'figurine_diamond_hoe' + | 'figurine_diamonds' + | 'figurine_don_espresso' + | 'figurine_dragon_slayer' + | 'figurine_emeralds' + | 'figurine_ender_pearl' + | 'figurine_enderman' + | 'figurine_executives_meeting' + | 'figurine_fireballs' + | 'figurine_fishing_rod' + | 'figurine_golden_apple' + | 'figurine_golden_sandman' + | 'figurine_grass_block' + | 'figurine_groopo' + | 'figurine_guardian' + | 'figurine_hammer_vs_heatwave' + | 'figurine_hot_air_balloon' + | 'figurine_housing' + | 'figurine_hypixel' + | 'figurine_hypixel_logo' + | 'figurine_iron_punch' + | 'figurine_iron_rose' + | 'figurine_kart_racing' + | 'figurine_knockback' + | 'figurine_legacy' + | 'figurine_magma_boss' + | 'figurine_missing_bed' + | 'figurine_portal' + | 'figurine_ratman' + | 'figurine_regular_sandman' + | 'figurine_rezzus' + | 'figurine_shears' + | 'figurine_sheep' + | 'figurine_sky_island' + | 'figurine_sniper' + | 'figurine_steve' + | 'figurine_the_pit' + | 'figurine_tic_tac_toe' + | 'figurine_tnt' + | 'figurine_top_beds' + | 'figurine_top_killer' + | 'figurine_zombie'; +export type BedWarsGlyph = + | 'glyph_angry_face' + | 'glyph_bat' + | 'glyph_bauble' + | 'glyph_bed' + | 'glyph_big_smile' + | 'glyph_black_cat' + | 'glyph_bloom' + | 'glyph_blossom' + | 'glyph_bronze_shield' + | 'glyph_bunny' + | 'glyph_bunny_guy' + | 'glyph_burn' + | 'glyph_candy' + | 'glyph_candy_cane' + | 'glyph_candy_corn' + | 'glyph_carrot' + | 'glyph_cat' + | 'glyph_cauldron' + | 'glyph_celebration_popper' + | 'glyph_chick' + | 'glyph_chicken' + | 'glyph_chinese_firecracker' + | 'glyph_chocolate' + | 'glyph_chocolate_egg' + | 'glyph_christmas_tree' + | 'glyph_coconut' + | 'glyph_creeper_scream' + | 'glyph_cry_face' + | 'glyph_cute_ghost' + | 'glyph_cute_pumpkin' + | 'glyph_daisy' + | 'glyph_diamond' + | 'glyph_dog' + | 'glyph_dragon' + | 'glyph_dreidel' + | 'glyph_earth' + | 'glyph_easter_egg' + | 'glyph_easter_flower' + | 'glyph_egg_basket' + | 'glyph_egg_with_bow' + | 'glyph_elf' + | 'glyph_emerald' + | 'glyph_eyeball' + | 'glyph_fai_chun' + | 'glyph_festive_bell' + | 'glyph_flame' + | 'glyph_gg' + | 'glyph_ghost' + | 'glyph_gift' + | 'glyph_gingerbread_man' + | 'glyph_gold' + | 'glyph_gold_lunar' + | 'glyph_gold_shield' + | 'glyph_grave' + | 'glyph_halloween' + | 'glyph_heart' + | 'glyph_hi' + | 'glyph_holly' + | 'glyph_hot' + | 'glyph_hot_cross_bun' + | 'glyph_iron' + | 'glyph_lantern' + | 'glyph_lion_dancer' + | 'glyph_lol' + | 'glyph_lucky_rabbit' + | 'glyph_menorah' + | 'glyph_moon' + | 'glyph_mouse' + | 'glyph_no' + | 'glyph_no_1' + | 'glyph_orange' + | 'glyph_palm_tree' + | 'glyph_party' + | 'glyph_pig' + | 'glyph_pilgrim_hat' + | 'glyph_player_face' + | 'glyph_pumpkin' + | 'glyph_pumpkin_2' + | 'glyph_quack' + | 'glyph_rabbit' + | 'glyph_rainbow' + | 'glyph_red_envelope' + | 'glyph_reindeer' + | 'glyph_rip' + | 'glyph_rose' + | 'glyph_santa_hat' + | 'glyph_scream_face' + | 'glyph_shell' + | 'glyph_shock_face' + | 'glyph_silver_shield' + | 'glyph_skull' + | 'glyph_smiley_face' + | 'glyph_snowflake' + | 'glyph_snowman' + | 'glyph_sparkle' + | 'glyph_spectrum' + | 'glyph_spider' + | 'glyph_squeak' + | 'glyph_star' + | 'glyph_stocking' + | 'glyph_storm' + | 'glyph_strawberry' + | 'glyph_sunflower' + | 'glyph_sword' + | 'glyph_this_is_fine' + | 'glyph_thumbs_down' + | 'glyph_thumbs_up' + | 'glyph_tiger' + | 'glyph_tnt' + | 'glyph_umbrella' + | 'glyph_winky_face' + | 'glyph_witch_hat' + | 'glyph_wreath' + | 'glyph_yes'; +export type BedWarsIslandTopper = + | 'islandtopper_angel' + | 'islandtopper_assassin' + | 'islandtopper_assassin_sword' + | 'islandtopper_ballista' + | 'islandtopper_basket' + | 'islandtopper_bee' + | 'islandtopper_bell' + | 'islandtopper_big_present' + | 'islandtopper_birdhouse' + | 'islandtopper_bleeding_heart' + | 'islandtopper_bluebird' + | 'islandtopper_bomb' + | 'islandtopper_brick_house' + | 'islandtopper_broken_pumpkin' + | 'islandtopper_bungalow' + | 'islandtopper_bunny' + | 'islandtopper_bunny_in_hat' + | 'islandtopper_candle' + | 'islandtopper_candles' + | 'islandtopper_candy_basket' + | 'islandtopper_candy_cane' + | 'islandtopper_candy_corn' + | 'islandtopper_carrot' + | 'islandtopper_chalice' + | 'islandtopper_cherry_blossom' + | 'islandtopper_chicken' + | 'islandtopper_chimney' + | 'islandtopper_chocolate_bunny' + | 'islandtopper_chocolate_egg' + | 'islandtopper_chocolatebar' + | 'islandtopper_christmas_hat' + | 'islandtopper_christmas_tree' + | 'islandtopper_clown' + | 'islandtopper_coconut_drink' + | 'islandtopper_coffin' + | 'islandtopper_collector' + | 'islandtopper_cow' + | 'islandtopper_crab' + | 'islandtopper_crystal_ball' + | 'islandtopper_cyclops' + | 'islandtopper_dead_tree' + | 'islandtopper_demon' + | 'islandtopper_devil' + | 'islandtopper_dragon_head' + | 'islandtopper_dreidel' + | 'islandtopper_easter_bell' + | 'islandtopper_easter_egg' + | 'islandtopper_eyeball' + | 'islandtopper_fancy_helmet' + | 'islandtopper_firecracker' + | 'islandtopper_firework_rocket' + | 'islandtopper_fish_bowl' + | 'islandtopper_fishing_rod' + | 'islandtopper_flame' + | 'islandtopper_flamingo' + | 'islandtopper_fountain_firework' + | 'islandtopper_frankenstein' + | 'islandtopper_gapple' + | 'islandtopper_gargoyle' + | 'islandtopper_ghost' + | 'islandtopper_gingerbread_house' + | 'islandtopper_gold_present' + | 'islandtopper_gong' + | 'islandtopper_gravestone' + | 'islandtopper_hatching_egg' + | 'islandtopper_haunted_mansion' + | 'islandtopper_heart' + | 'islandtopper_hermit_crab' + | 'islandtopper_hot_cocoa' + | 'islandtopper_hypixel_knight' + | 'islandtopper_invisible_villager' + | 'islandtopper_ladybug' + | 'islandtopper_lantern' + | 'islandtopper_large_rabbit' + | 'islandtopper_lazy_miner' + | 'islandtopper_leaf' + | 'islandtopper_lunar_dragon' + | 'islandtopper_mark_of_the_paw' + | 'islandtopper_mister_egg' + | 'islandtopper_monocle' + | 'islandtopper_mummy' + | 'islandtopper_nest_of_chicks' + | 'islandtopper_new_ghost' + | 'islandtopper_note' + | 'islandtopper_nutcracker' + | 'islandtopper_owl' + | 'islandtopper_ox' + | 'islandtopper_pagoda' + | 'islandtopper_panda' + | 'islandtopper_parasol' + | 'islandtopper_parchment' + | 'islandtopper_party_sloth' + | 'islandtopper_penguin' + | 'islandtopper_penguin_stack' + | 'islandtopper_penjing' + | 'islandtopper_picnic_basket' + | 'islandtopper_pig' + | 'islandtopper_pinecone' + | 'islandtopper_pot' + | 'islandtopper_presents' + | 'islandtopper_president_goons' + | 'islandtopper_pudding' + | 'islandtopper_pumpkin' + | 'islandtopper_rabbit_ears' + | 'islandtopper_rain' + | 'islandtopper_rainbow_sheep' + | 'islandtopper_ramen' + | 'islandtopper_reaper' + | 'islandtopper_red_envelope' + | 'islandtopper_reindeer' + | 'islandtopper_roast_turkey' + | 'islandtopper_robin' + | 'islandtopper_rubix_cube' + | 'islandtopper_sailboat' + | 'islandtopper_sand_castle' + | 'islandtopper_sapling' + | 'islandtopper_sheep' + | 'islandtopper_shopping_cart' + | 'islandtopper_skeleton_thumbs_up' + | 'islandtopper_skullsword' + | 'islandtopper_sleigh' + | 'islandtopper_slime' + | 'islandtopper_sloth' + | 'islandtopper_small_rabbit' + | 'islandtopper_smiley_face' + | 'islandtopper_snake' + | 'islandtopper_snowflake' + | 'islandtopper_snowglobe' + | 'islandtopper_snowman' + | 'islandtopper_snowy_cabin' + | 'islandtopper_spooky_hypixel' + | 'islandtopper_spooky_lantern' + | 'islandtopper_sprout' + | 'islandtopper_stocking' + | 'islandtopper_stoplight' + | 'islandtopper_sun_glasses' + | 'islandtopper_sunflower' + | 'islandtopper_surfboard' + | 'islandtopper_sword' + | 'islandtopper_tall_carrot' + | 'islandtopper_temple' + | 'islandtopper_temple_hut' + | 'islandtopper_the_l' + | 'islandtopper_thunder' + | 'islandtopper_tiger' + | 'islandtopper_tnt' + | 'islandtopper_top_hat' + | 'islandtopper_tourney' + | 'islandtopper_toxic_rain' + | 'islandtopper_treasure_chest' + | 'islandtopper_tree' + | 'islandtopper_tulips' + | 'islandtopper_watering_can' + | 'islandtopper_watermelon' + | 'islandtopper_wave' + | 'islandtopper_werewolf' + | 'islandtopper_whale' + | 'islandtopper_wicked_zombie' + | 'islandtopper_witch' + | 'islandtopper_witch_hat' + | 'islandtopper_witch_house' + | 'islandtopper_witchs_potion' + | 'islandtopper_yin_and_yang' + | 'islandtopper_zombiehand'; +export type BedWarsKillEffect = + | 'killeffect_after_life' + | 'killeffect_anvil_smash' + | 'killeffect_balloons' + | 'killeffect_batcrux' + | 'killeffect_bee_abduction' + | 'killeffect_beef_everywhere' + | 'killeffect_black_mark' + | 'killeffect_blood_bats' + | 'killeffect_blood_explosion' + | 'killeffect_bunny_explosion' + | 'killeffect_burning_shoes' + | 'killeffect_campfire' + | 'killeffect_candle' + | 'killeffect_chicken_tower' + | 'killeffect_cookie_fountain' + | 'killeffect_cow_rocket' + | 'killeffect_crackling_ice' + | 'killeffect_draculas_flight' + | 'killeffect_egg_theft' + | 'killeffect_final_smash' + | 'killeffect_fire_breath' + | 'killeffect_firework' + | 'killeffect_frozen_in_time' + | 'killeffect_gift_explosion' + | 'killeffect_golemyeet' + | 'killeffect_guardian_rocket' + | 'killeffect_hatching_eggs' + | 'killeffect_haunted' + | 'killeffect_head_rocket' + | 'killeffect_heart_aura' + | 'killeffect_heartbeat' + | 'killeffect_holiday_fireworks' + | 'killeffect_holiday_tree' + | 'killeffect_jack_o_twister' + | 'killeffect_kill_counter_holo' + | 'killeffect_lantern_spiral' + | 'killeffect_lighting_strike' + | 'killeffect_lightning_strike' + | 'killeffect_lit' + | 'killeffect_magnolia' + | 'killeffect_pedestal' + | 'killeffect_petal_gust' + | 'killeffect_pigsmash' + | 'killeffect_piñata' + | 'killeffect_present_rain' + | 'killeffect_pumpkin_popper' + | 'killeffect_pumpkin_rocket' + | 'killeffect_rain_on_my_parade' + | 'killeffect_rainbow' + | 'killeffect_raining_eggs' + | 'killeffect_raining_gold' + | 'killeffect_rekt' + | 'killeffect_ring_of_fire' + | 'killeffect_rising_dragon' + | 'killeffect_shattered' + | 'killeffect_shockwave' + | 'killeffect_skeletalremains' + | 'killeffect_smiley' + | 'killeffect_snow_globe' + | 'killeffect_snowplosion' + | 'killeffect_soul_ripper' + | 'killeffect_spirit' + | 'killeffect_squid_missile' + | 'killeffect_team_destroy' + | 'killeffect_tnt' + | 'killeffect_tornado' + | 'killeffect_wing_gusts' + | 'killeffect_witch_ritual' + | 'killeffect_xp_orb'; +export type BedWarsKillMessage = + | 'killmessages_bbq' + | 'killmessages_bridging_for_dummies' + | 'killmessages_buzz' + | 'killmessages_celebratory' + | 'killmessages_counter' + | 'killmessages_dramatic' + | 'killmessages_eggy' + | 'killmessages_festive' + | 'killmessages_fire' + | 'killmessages_glorious' + | 'killmessages_honourable' + | 'killmessages_limbo' + | 'killmessages_love' + | 'killmessages_memed' + | 'killmessages_multiverse' + | 'killmessages_noble' + | 'killmessages_oink' + | 'killmessages_old_man' + | 'killmessages_oxed' + | 'killmessages_pirate' + | 'killmessages_primal' + | 'killmessages_roar' + | 'killmessages_santa_workshop' + | 'killmessages_snow_storm' + | 'killmessages_social_distancing' + | 'killmessages_spooky' + | 'killmessages_squeak' + | 'killmessages_to_the_moon' + | 'killmessages_western' + | 'killmessages_woof_woof' + | 'killmessages_wrapped_up'; +export type BedWarsNPCSkin = + | 'npcskin_aqua_duck_pajamas' + | 'npcskin_astronaut' + | 'npcskin_bao' + | 'npcskin_bed_researcher' + | 'npcskin_bed_salesman' + | 'npcskin_blaze' + | 'npcskin_blue_rabbit' + | 'npcskin_blue_sheep_pajamas' + | 'npcskin_bright_tiger' + | 'npcskin_bundled_snowman' + | 'npcskin_bunny_costume' + | 'npcskin_bunny_in_suit' + | 'npcskin_cheesy' + | 'npcskin_chen' + | 'npcskin_clown' + | 'npcskin_cluck_stack' + | 'npcskin_creeper' + | 'npcskin_cute_puppy' + | 'npcskin_dark_dragon' + | 'npcskin_defuser' + | 'npcskin_dragon' + | 'npcskin_egg_delivery' + | 'npcskin_ender_pulse' + | 'npcskin_enderman' + | 'npcskin_evil_eye' + | 'npcskin_frog_man' + | 'npcskin_ghost' + | 'npcskin_gold_tiger' + | 'npcskin_green_cow_pajamas' + | 'npcskin_grinch' + | 'npcskin_hammer' + | 'npcskin_heatwave' + | 'npcskin_holiday_bartender' + | 'npcskin_holiday_tree' + | 'npcskin_ice_queen' + | 'npcskin_john_indigos' + | 'npcskin_killer' + | 'npcskin_king_of_beds' + | 'npcskin_lester_brody' + | 'npcskin_li' + | 'npcskin_lucky_cat' + | 'npcskin_lumberjack' + | 'npcskin_magic_vendor' + | 'npcskin_man_wearing_suit' + | 'npcskin_marksman' + | 'npcskin_merchant' + | 'npcskin_mouse' + | 'npcskin_mr_giftman' + | 'npcskin_oasis_spirit' + | 'npcskin_patriot_eagle' + | 'npcskin_penguin' + | 'npcskin_pink_bunny_pajamas' + | 'npcskin_pink_rabbit' + | 'npcskin_present_man' + | 'npcskin_president_sloth' + | 'npcskin_purple_pig_pajamas' + | 'npcskin_quack' + | 'npcskin_rat' + | 'npcskin_ratman' + | 'npcskin_red_frog_pajamas' + | 'npcskin_reindeer' + | 'npcskin_reindeer2' + | 'npcskin_sacred_cattle' + | 'npcskin_santa' + | 'npcskin_scarecrow' + | 'npcskin_skeleton' + | 'npcskin_skeletor' + | 'npcskin_slumber_receptionist' + | 'npcskin_snow_globe_elf' + | 'npcskin_snowman' + | 'npcskin_spaceman' + | 'npcskin_stack_o_lantern' + | 'npcskin_stellar' + | 'npcskin_upside_down_snowman' + | 'npcskin_villager_zombie' + | 'npcskin_warrior' + | 'npcskin_watcher' + | 'npcskin_wei' + | 'npcskin_witch' + | 'npcskin_wither' + | 'npcskin_wither_skeleton' + | 'npcskin_wither_tower' + | 'npcskin_xiu' + | 'npcskin_you' + | 'npcskin_zhao' + | 'npcskin_zombie' + | 'npcskin_zombie_pigman'; +export type BedWarsProjectileTrail = + | 'projectileTrail_Jack_O_Lantern_Trail' + | 'projectileTrail_angry_villager' + | 'projectileTrail_bee' + | 'projectileTrail_bite' + | 'projectileTrail_black_smoke' + | 'projectileTrail_blood' + | 'projectileTrail_blue_dust' + | 'projectileTrail_bone' + | 'projectileTrail_chains' + | 'projectileTrail_cheese' + | 'projectileTrail_ender' + | 'projectileTrail_fire' + | 'projectileTrail_fire_spiral' + | 'projectileTrail_fireball' + | 'projectileTrail_firework' + | 'projectileTrail_green_star' + | 'projectileTrail_hanukkah' + | 'projectileTrail_hearts' + | 'projectileTrail_hoops' + | 'projectileTrail_lava' + | 'projectileTrail_let_there_be_leather' + | 'projectileTrail_lunar_dust' + | 'projectileTrail_magic' + | 'projectileTrail_magic_wind' + | 'projectileTrail_merry' + | 'projectileTrail_meteorblaze' + | 'projectileTrail_notes' + | 'projectileTrail_peep_hatching' + | 'projectileTrail_portal_trail' + | 'projectileTrail_potion' + | 'projectileTrail_present' + | 'projectileTrail_pumpkin_pie' + | 'projectileTrail_purple_dust' + | 'projectileTrail_rainbow' + | 'projectileTrail_rainy' + | 'projectileTrail_random' + | 'projectileTrail_red_dust' + | 'projectileTrail_rocket' + | 'projectileTrail_slime' + | 'projectileTrail_slumber' + | 'projectileTrail_snowball_rain' + | 'projectileTrail_spring_ribbons' + | 'projectileTrail_the_end_trail' + | 'projectileTrail_tinsel' + | 'projectileTrail_trick_or_treat' + | 'projectileTrail_twin_dragon' + | 'projectileTrail_twisted_trail' + | 'projectileTrail_water' + | 'projectileTrail_white_smoke' + | 'projectileTrail_wingman' + | 'projectiletrail_Jack_O_Lantern_Trail' + | 'projectiletrail_angry_villager' + | 'projectiletrail_bee' + | 'projectiletrail_bite' + | 'projectiletrail_black_smoke' + | 'projectiletrail_blood' + | 'projectiletrail_blue_dust' + | 'projectiletrail_bone' + | 'projectiletrail_candy_basket' + | 'projectiletrail_chains' + | 'projectiletrail_cheese' + | 'projectiletrail_cold' + | 'projectiletrail_cursedflame' + | 'projectiletrail_ender' + | 'projectiletrail_fanged' + | 'projectiletrail_fire' + | 'projectiletrail_fire_spiral' + | 'projectiletrail_fireball' + | 'projectiletrail_firework' + | 'projectiletrail_flame_rings' + | 'projectiletrail_green_star' + | 'projectiletrail_hanukkah' + | 'projectiletrail_hearts' + | 'projectiletrail_hoops' + | 'projectiletrail_howling_wind' + | 'projectiletrail_icicle' + | 'projectiletrail_jack_o_lantern_trail' + | 'projectiletrail_lava' + | 'projectiletrail_let_there_be_leather' + | 'projectiletrail_lunar_dust' + | 'projectiletrail_magic' + | 'projectiletrail_magic_wind' + | 'projectiletrail_merry' + | 'projectiletrail_meteorblaze' + | 'projectiletrail_notes' + | 'projectiletrail_peep_hatching' + | 'projectiletrail_portal_trail' + | 'projectiletrail_potion' + | 'projectiletrail_present' + | 'projectiletrail_pumpkin_pie' + | 'projectiletrail_pumpkin_spice_powered' + | 'projectiletrail_pumpkin_volley_trail' + | 'projectiletrail_purple_dust' + | 'projectiletrail_rainbow' + | 'projectiletrail_rainy' + | 'projectiletrail_random' + | 'projectiletrail_red_dust' + | 'projectiletrail_rocket' + | 'projectiletrail_rose' + | 'projectiletrail_slime' + | 'projectiletrail_slumber' + | 'projectiletrail_snowball_rain' + | 'projectiletrail_sparkler' + | 'projectiletrail_spiders_silk' + | 'projectiletrail_spring_ribbons' + | 'projectiletrail_stormy' + | 'projectiletrail_the_end_trail' + | 'projectiletrail_tinsel' + | 'projectiletrail_trick_or_treat' + | 'projectiletrail_twin_dragon' + | 'projectiletrail_twirling_snowflake' + | 'projectiletrail_twisted_trail' + | 'projectiletrail_water' + | 'projectiletrail_white_smoke' + | 'projectiletrail_wingman' + | 'projectiletrail_wisp_whirlwind'; +export type BedWarsSpray = + | 'sprays_angelic_jerry' + | 'sprays_angry_cow' + | 'sprays_angry_turkey' + | 'sprays_bed_breaker' + | 'sprays_bed_shield' + | 'sprays_bee_that_chicken' + | 'sprays_boo' + | 'sprays_buff_chicken' + | 'sprays_bunny_gg' + | 'sprays_bunny_lantern' + | 'sprays_bunny_parkour' + | 'sprays_bye_bye' + | 'sprays_candy_cane_sniper' + | 'sprays_candy_king' + | 'sprays_carried' + | 'sprays_casual_christmas' + | 'sprays_cat_graffiti' + | 'sprays_chickens' + | 'sprays_choc_feast' + | 'sprays_christmas_tree' + | 'sprays_comfy_web' + | 'sprays_cooler_climates' + | 'sprays_creeper' + | 'sprays_curled_ox' + | 'sprays_cute_bunny' + | 'sprays_decorative_island' + | 'sprays_diamond' + | 'sprays_disco_pumpkin' + | 'sprays_distinguished_ghost' + | 'sprays_dogs_of_wisdom' + | 'sprays_doot' + | 'sprays_dragon' + | 'sprays_dragon_slayer' + | 'sprays_earth_pig' + | 'sprays_easter_basket' + | 'sprays_easter_creeper' + | 'sprays_easter_eggs' + | 'sprays_easter_sweater' + | 'sprays_egg_decorations' + | 'sprays_egg_gunner' + | 'sprays_egg_hit' + | 'sprays_egg_hunt' + | 'sprays_egg_surprise' + | 'sprays_egg_time' + | 'sprays_enderman' + | 'sprays_faboolous' + | 'sprays_fake_vampire' + | 'sprays_family_photo_christmas' + | 'sprays_festive_harbinger' + | 'sprays_fireworks' + | 'sprays_flowers_for_you' + | 'sprays_found_u' + | 'sprays_garlic' + | 'sprays_gg_wp' + | 'sprays_ggwp_pumpkin' + | 'sprays_ghost' + | 'sprays_gingerbread_jerry' + | 'sprays_golden_egg' + | 'sprays_golem_picnic' + | 'sprays_golem_riding' + | 'sprays_good_fortune' + | 'sprays_gothic_jerry' + | 'sprays_great_egg_hunt' + | 'sprays_grudge' + | 'sprays_haunted_conscience' + | 'sprays_haunted_house' + | 'sprays_hypixel_logo' + | 'sprays_hypixel_logo_default' + | 'sprays_i_love_you' + | 'sprays_ice_scream_cart' + | 'sprays_invisibility_potion' + | 'sprays_jerry_island_poster' + | 'sprays_lantern' + | 'sprays_lazy_bunnies' + | 'sprays_lazy_spring' + | 'sprays_leaping_potion' + | 'sprays_lion_dancer' + | 'sprays_loot_chest' + | 'sprays_lucky_rabbit' + | 'sprays_menorah' + | 'sprays_mistletoe' + | 'sprays_mob_party' + | 'sprays_monster_under_bed' + | 'sprays_murder_mystery_poster' + | 'sprays_one_of_us' + | 'sprays_ouija' + | 'sprays_ox_costume' + | 'sprays_painted_dragon_egg' + | 'sprays_party_crasher' + | 'sprays_peaceful' + | 'sprays_perfect_sword_throw' + | 'sprays_pig_peace' + | 'sprays_pumpkin' + | 'sprays_pumpkin_farm' + | 'sprays_pumpkin_pals' + | 'sprays_pumpkinz' + | 'sprays_puppy_surprise' + | 'sprays_rabbit_celebration' + | 'sprays_rabbit_costume' + | 'sprays_rabbits_in_basket' + | 'sprays_rat_costume' + | 'sprays_rats_2020' + | 'sprays_reveillon' + | 'sprays_sabeetage' + | 'sprays_sand_castle' + | 'sprays_santa' + | 'sprays_santa_slips' + | 'sprays_scared' + | 'sprays_sea_bass' + | 'sprays_seasons_greetings' + | 'sprays_shiny' + | 'sprays_silent_night' + | 'sprays_skeleton_wave' + | 'sprays_sleep_well' + | 'sprays_sleeps_and_treats' + | 'sprays_sloth_burn' + | 'sprays_smug_pig' + | 'sprays_sniper_snowball' + | 'sprays_snow_angel' + | 'sprays_snow_jerry' + | 'sprays_snowball_fight' + | 'sprays_snowball_spammer' + | 'sprays_snowman_rampage' + | 'sprays_sorry' + | 'sprays_spooky_game_over' + | 'sprays_spooky_skelington' + | 'sprays_surfs_up' + | 'sprays_surprise_snowball' + | 'sprays_sweet_dreams' + | 'sprays_sweets' + | 'sprays_thanks' + | 'sprays_tnt_drop' + | 'sprays_trick_or_treat' + | 'sprays_turkey_day' + | 'sprays_ugly_bed_wars_sweater' + | 'sprays_undead_lifesaving_association' + | 'sprays_vampire_jerry' + | 'sprays_watcher' + | 'sprays_witch' + | 'sprays_witch_please' + | 'sprays_wrong_eggs' + | 'sprays_year_of_the_dog' + | 'sprays_year_of_the_dragon' + | 'sprays_year_of_the_ox' + | 'sprays_year_of_the_pig' + | 'sprays_year_of_the_rabbit' + | 'sprays_year_of_the_rat' + | 'sprays_year_of_the_snake' + | 'sprays_year_of_the_tiger'; +export type BedWarsVictoryDance = + | 'victorydance_abominable_snowman' + | 'victorydance_anvil_rain' + | 'victorydance_aura' + | 'victorydance_cake_walk' + | 'victorydance_chicken_rider' + | 'victorydance_chinese_dragon' + | 'victorydance_cold_snap' + | 'victorydance_dragon_fire' + | 'victorydance_dragon_rider' + | 'victorydance_dreamscape' + | 'victorydance_easter_bunnies' + | 'victorydance_egg_meteors' + | 'victorydance_elder_guardian_rider' + | 'victorydance_exploding_bunnies' + | 'victorydance_fanbase' + | 'victorydance_festive_music' + | 'victorydance_figurine_rain' + | 'victorydance_fireworks' + | 'victorydance_floating_lanterns' + | 'victorydance_flower_bed' + | 'victorydance_ghast_rider' + | 'victorydance_graveyardrave' + | 'victorydance_guardians' + | 'victorydance_haunted' + | 'victorydance_heat_wave' + | 'victorydance_hurricanehell' + | 'victorydance_infection' + | 'victorydance_kartaway' + | 'victorydance_meteor_shower' + | 'victorydance_night_shift' + | 'victorydance_portal' + | 'victorydance_pumpkin_bomber' + | 'victorydance_pumpkin_laser' + | 'victorydance_pumpkin_patch' + | 'victorydance_puppy_party' + | 'victorydance_rabbit_meteors' + | 'victorydance_rainbow_dolly' + | 'victorydance_raining_pigs' + | 'victorydance_rooted' + | 'victorydance_snow_bomber' + | 'victorydance_snowed_in' + | 'victorydance_special_fireworks' + | 'victorydance_terror' + | 'victorydance_to_build_a_snowman' + | 'victorydance_toy_stick' + | 'victorydance_twerk_apocalypse' + | 'victorydance_winter_twister' + | 'victorydance_wither_rider' + | 'victorydance_yeehaw'; +export type BedWarsWoodSkin = + | 'woodskin_acacia_log' + | 'woodskin_birch_log' + | 'woodskin_dark_oak_log' + | 'woodskin_jungle_log' + | 'woodskin_oak_log' + | 'woodskin_spruce_log'; +export type BedWarsStartingWeapon = 'starting_weapon_golden_sword' | 'starting_weapon_wooden_sword'; +export type BedWarsPackage = + | '5_percent_multiplier_tournament' + | 'capture_book_0' + | 'leaderboards_resync_mar_2021' + | 'tiered_achievement_flag_1' + | 'tiered_achievement_flag_2' + | 'tiered_achievement_flag_3' + | 'tiered_achievement_flag_4' + | 'v14_book' + | BedWarsBedDestroy + | BedWarsPackageChallenge + | BedWarsDeathCry + | BedWarsFavoriteMap + | BedwarsFigurine + | BedWarsGlyph + | BedWarsIslandTopper + | BedWarsKillEffect + | BedWarsKillMessage + | BedWarsNPCSkin + | BedWarsProjectileTrail + | BedWarsSpray + | BedWarsVictoryDance + | BedWarsWoodSkin + | BedWarsStartingWeapon; +export type PlayerGeneralSelectedCosmetic = 'random_cosmetic' | 'random_favorite_cosmetic'; +export type BedWarsPracticeModeId = 'BOW' | 'BRIDGING' | 'FIREBALL_JUMPING' | 'MLG' | 'PEARL_CLUTCHING'; +export type BedWarsPracticeBridgingRecordsDistances = '100' | '50' | '30'; +export type BedWarsPracticeBridgingRecordsElevations = 'NONE' | 'SLIGHT' | 'STAIRCASE'; + +export type SkyWarsModeSolo = 'solo_normal' | 'solo_insane' | 'lab_solo' | 'solo'; +export type SkyWarsModeTeam = 'team_normal' | 'team_insane' | 'team'; +export type SkyWarsModeMege = 'mega_doubles_normal' | 'mega_doubles' | 'mega_normal' | 'mega'; +export type SkyWarsModeMini = 'mini_normal' | 'mini'; +export type SkyWarsModeRanked = 'ranked_normal' | 'ranked'; +export type SkyWarsModeTourney = 'crazytourney_normal' | 'tourney_crazytourney' | 'crazytourney' | 'tourney'; +export type SkyWarsModeId = + | SkyWarsModeSolo + | SkyWarsModeTeam + | SkyWarsModeMege + | SkyWarsModeMini + | SkyWarsModeRanked + | SkyWarsModeTourney + | 'lab'; + +export type SkyWarsMythicKitId = + | 'kit_mythical_chronobreaker' + | 'kit_mythical_nether-lord' + | 'kit_mythical_end-lord' + | 'kit_mythical_monster-trainer' + | 'kit_mythical_cryomancer' + | 'kit_mythical_thundermeister' + | 'kit_mythical_fishmonger'; +export type SkyWarsBasicSoloKitId = + | 'kit_basic_solo_default' + | 'kit_basic_solo_armorsmith' + | 'kit_basic_solo_ecologist' + | 'kit_basic_solo_fisherman' + | 'kit_basic_solo_speleologist' + | 'kit_basic_solo_troll' + | 'kit_basic_solo_snowman' + | 'kit_basic_solo_rookie' + | 'kit_basic_solo_scout' + | 'kit_basic_solo_energix' + | 'kit_basic_solo_grenade' + | 'kit_basic_solo_pharaoh' + | 'kit_basic_solo_disco' + | 'kit_basic_solo_frog' + | 'kit_basic_solo_baseball-player' + | 'kit_basic_solo_princess' + | 'kit_basic_solo_batguy' + | 'kit_basic_solo_healer' + | 'kit_basic_solo_cactus' + | 'kit_basic_solo_warlock' + | 'kit_basic_solo_archeologist' + | 'kit_basic_solo_fallen-angel'; +export type SkyWarsAdvancedSoloKitId = + | 'kit_advanced_solo_farmer' + | 'kit_advanced_solo_enchanter' + | 'kit_advanced_solo_hunter' + | 'kit_advanced_solo_knight' + | 'kit_advanced_solo_armorer' + | 'kit_advanced_solo_cannoneer' + | 'kit_advanced_solo_pyro' + | 'kit_advanced_solo_salmon' + | 'kit_advanced_solo_zookeeper' + | 'kit_advanced_solo_enderman' + | 'kit_advanced_solo_slime' + | 'kit_advanced_solo_pig-rider' + | 'kit_advanced_solo_sloth' + | 'kit_advanced_solo_jester' + | 'kit_advanced_solo_guardian' + | 'kit_advanced_solo_engineer' + | 'kit_advanced_solo_magician'; +export type SkyWarsMiniSoloKitId = + | 'kit_mini_solo_athlete' + | 'kit_mini_solo_scout' + | 'kit_mini_solo_champion' + | 'kit_mini_solo_magician' + | 'kit_mini_solo_bowman' + | 'kit_mini_solo_healer' + | 'kit_mini_solo_pyromancer' + | 'kit_mini_solo_armorer' + | 'kit_mini_solo_blacksmith' + | 'kit_mini_solo_hound' + | 'kit_mini_solo_paladin'; +export type SkyWarsBasicLabSoloKitId = + | 'lab_kit_basic_solo_scout' + | 'lab_kit_basic_solo_ecologist' + | 'lab_kit_basic_solo_speleologist' + | 'lab_kit_basic_solo_armorsmith' + | 'lab_kit_basic_solo_energix' + | 'lab_kit_basic_solo_baseball-player' + | 'lab_kit_basic_solo_disco' + | 'lab_kit_basic_solo_pharaoh' + | 'lab_kit_basic_solo_default' + | 'lab_kit_basic_solo_frog' + | 'lab_kit_basic_solo_grenade' + | 'lab_kit_basic_solo_fisherman' + | 'lab_kit_basic_solo_rookie' + | 'lab_kit_basic_solo_troll' + | 'lab_kit_basic_solo_snowman' + | 'lab_kit_basic_solo_princess' + | 'lab_kit_basic_solo_batguy'; +export type SkyWarsAdvancedLabSoloKitId = + | 'lab_kit_advanced_solo_armorer' + | 'lab_kit_advanced_solo_salmon' + | 'lab_kit_advanced_solo_knight' + | 'lab_kit_advanced_solo_pyro' + | 'lab_kit_advanced_solo_zookeeper' + | 'lab_kit_advanced_solo_slime' + | 'lab_kit_advanced_solo_farmer' + | 'lab_kit_advanced_solo_enchanter' + | 'lab_kit_advanced_solo_jester' + | 'lab_kit_advanced_solo_engineer' + | 'lab_kit_advanced_solo_enderman' + | 'lab_kit_advanced_solo_cannoneer' + | 'lab_kit_advanced_solo_hunter' + | 'lab_kit_advanced_solo_sloth' + | 'lab_kit_advanced_solo_pig-rider' + | 'lab_kit_advanced_solo_magician'; +export type SkyWarsLabSoloKitId = + | SkyWarsBasicLabSoloKitId + | SkyWarsAdvancedLabSoloKitId + | 'lab_kit_enderchest_solo_enderchest'; +export type SkyWarsBasicTourneySoloKitId = + | 'tourney_kit_basic_solo_frog' + | 'tourney_kit_basic_solo_disco' + | 'tourney_kit_basic_solo_armorsmith' + | 'tourney_kit_basic_solo_fisherman' + | 'tourney_kit_basic_solo_pharaoh' + | 'tourney_kit_basic_solo_ecologist' + | 'tourney_kit_basic_solo_healer' + | 'tourney_kit_basic_solo_energix' + | 'tourney_kit_basic_solo_speleologist' + | 'tourney_kit_basic_solo_cactus' + | 'tourney_kit_basic_solo_rookie' + | 'tourney_kit_basic_solo_baseball-player' + | 'tourney_kit_basic_solo_default' + | 'tourney_kit_basic_solo_scout' + | 'tourney_kit_basic_solo_snowman' + | 'tourney_kit_basic_solo_princess' + | 'tourney_kit_basic_solo_grenade' + | 'tourney_kit_basic_solo_troll' + | 'tourney_kit_basic_solo_warlock' + | 'tourney_kit_basic_solo_batguy'; +export type SkyWarsAdvancedTourneySoloKitId = + | 'tourney_kit_advanced_solo_armorer' + | 'tourney_kit_advanced_solo_enderman' + | 'tourney_kit_advanced_solo_knight' + | 'tourney_kit_advanced_solo_enchanter' + | 'tourney_kit_advanced_solo_farmer' + | 'tourney_kit_advanced_solo_cannoneer' + | 'tourney_kit_advanced_solo_jester' + | 'tourney_kit_advanced_solo_hunter' + | 'tourney_kit_advanced_solo_magician' + | 'tourney_kit_advanced_solo_zookeeper' + | 'tourney_kit_advanced_solo_slime' + | 'tourney_kit_advanced_solo_engineer' + | 'tourney_kit_advanced_solo_pig-rider' + | 'tourney_kit_advanced_solo_guardian'; +export type SkyWarsTourneySoloKitId = + | SkyWarsBasicTourneySoloKitId + | SkyWarsAdvancedTourneySoloKitId + | 'tourney_kit_enderchest_solo_enderchest'; +export type SkyWarsSoloKitId = + | SkyWarsTourneySoloKitId + | SkyWarsLabSoloKitId + | SkyWarsBasicSoloKitId + | SkyWarsAdvancedSoloKitId + | SkyWarsMiniSoloKitId + | 'kit_enderchest_solo_enderchest'; + +export type SkyWarsMegaKitId = + | 'kit_mega_mega_default' + | 'kit_mega_mega_hunter' + | 'kit_mega_mega_scout' + | 'kit_mega_mega_baseball-player' + | 'kit_mega_mega_armorer' + | 'kit_mega_mega_knight' + | 'kit_mega_mega_cannoneer' + | 'kit_mega_mega_hellhound' + | 'kit_mega_mega_witch' + | 'kit_mega_mega_fisherman' + | 'kit_mega_mega_armorsmith' + | 'kit_mega_mega_pyromaniac' + | 'kit_mega_mega_paladin' + | 'kit_mega_mega_healer' + | 'kit_mega_mega_skeletor' + | 'kit_mega_mega_enderman'; + +export type SkyWarsRankedPerkId = + | 'kit_ranked_ranked_default' + | 'kit_ranked_ranked_scout' + | 'kit_ranked_ranked_armorer' + | 'kit_ranked_ranked_bowman' + | 'kit_ranked_ranked_champion' + | 'kit_ranked_ranked_pyromancer' + | 'kit_ranked_ranked_hound' + | 'kit_ranked_ranked_athlete' + | 'kit_ranked_ranked_magician' + | 'kit_ranked_ranked_healer' + | 'kit_ranked_ranked_paladin' + | 'kit_ranked_ranked_blacksmith'; + +export type SkyWarsMiningTeamsKitId = + | 'kit_mining_team_default' + | 'kit_mining_team_cannoneer' + | 'kit_mining_team_speleologist' + | 'kit_mining_teams_default'; +export type SkyWarsDefendingTeamsKitId = + | 'kit_defending_team_armorer' + | 'kit_defending_team_baseball-player' + | 'kit_defending_team_guardian' + | 'kit_defending_team_batguy' + | 'kit_defending_team_frog' + | 'kit_defending_team_disco' + | 'kit_defending_team_farmer' + | 'kit_defending_team_cactus' + | 'kit_defending_team_golem'; +export type SkyWarsSupportingTeamsKitId = + | 'kit_supporting_team_healer' + | 'kit_supporting_team_ecologist' + | 'kit_supporting_team_armorsmith' + | 'kit_supporting_team_rookie' + | 'kit_supporting_team_enchanter' + | 'kit_supporting_team_pyro' + | 'kit_supporting_team_pharaoh' + | 'kit_supporting_team_warlock' + | 'kit_supporting_team_zookeeper' + | 'kit_supporting_team_princess' + | 'kit_supporting_team_troll'; +export type SkyWarsAttackingTeamsKitId = + | 'kit_attacking_team_scout' + | 'kit_attacking_team_knight' + | 'kit_attacking_team_snowman' + | 'kit_attacking_team_hunter' + | 'kit_attacking_team_enderman' + | 'kit_attacking_team_energix' + | 'kit_attacking_team_slime' + | 'kit_attacking_team_salmon' + | 'kit_attacking_team_sloth' + | 'kit_attacking_team_pig-rider' + | 'kit_attacking_team_grenade' + | 'kit_attacking_team_engineer' + | 'kit_attacking_team_magician' + | 'kit_attacking_team_default' + | 'kit_attacking_team_jester' + | 'kit_attacking_team_fisherman' + | 'kit_attacking_team_archeologist' + | 'kit_attacking_teams_default' + | 'kit_attacking_team_fallen-angel'; +export type SkyWarsTeamsKitId = + | SkyWarsMiningTeamsKitId + | SkyWarsDefendingTeamsKitId + | SkyWarsSupportingTeamsKitId + | SkyWarsAttackingTeamsKitId + | 'kit_enderchest_team_enderchest'; + +export type SkyWarsKitId = + | SkyWarsSoloKitId + | SkyWarsMegaKitId + | SkyWarsMythicKitId + | SkyWarsRankedPerkId + | SkyWarsTeamsKitId; +export type SkyWarsKillType = '' | 'melee' | 'void' | 'bow' | 'mob' | 'fall'; +export type SkyWarsSoloPerkId = + | 'ender_mastery' + | 'arrow_recovery' + | 'mining_expertise' + | 'blazing_arrows' + | 'instant_smelting' + | 'resistance_boost' + | 'speed_boost' + | 'bulldozer' + | 'marksmanship' + | 'juggernaut' + | 'knowledge' + | 'fat' + | 'nourishment' + | 'annoy' + | 'revenge' + | 'lucky_charm' + | 'bridger' + | 'environmental_expert' + | 'necromancer' + | 'black_magic' + | 'robbery' + | 'frost' + | 'barbarian' + | 'savior'; +export type SkyWarsMegePerkId = + | 'rusher' + | 'mining_expertise' + | 'ender_mastery' + | 'blazing_arrows' + | 'arrow_recovery' + | 'juggernaut' + | 'tank' + | 'nourishment' + | 'notoriety' + | 'instant_smelting' + | 'marksmanship' + | 'environmental_expert' + | 'bridger' + | 'lucky_charm' + | 'black_magic' + | 'necromancer' + | 'telekinesis'; +export type SkyWarsTeamsPerkId = + | 'instant_smelting' + | 'ender_mastery' + | 'resistance_boost' + | 'mining_expertise' + | 'juggernaut' + | 'blazing_arrows' + | 'arrow_recovery' + | 'speed_boost' + | 'fat' + | 'nourishment' + | 'knowledge' + | 'savior' + | 'marksmanship' + | 'bridger' + | 'lucky_charm' + | 'necromancer' + | 'black_magic' + | 'environmental_expert' + | 'robbery' + | 'frost' + | 'annoy-o-mite' + | 'bulldozer' + | 'barbarian'; +export type SkyWarsPerkId = SkyWarsSoloPerkId | SkyWarsMegePerkId | SkyWarsTeamsPerkId; + +export type BlitzSurvivalGamesKitId = + | 'arachnologist' + | 'archer' + | 'armorer' + | 'astronaut' + | 'backup' + | 'baker' + | 'blaze' + | 'creepertamer' + | 'diver' + | 'donkeytamer' + | 'farmer' + | 'fisherman' + | 'florist' + | 'golem' + | 'guardian' + | 'horsetamer' + | 'hunter' + | 'hype train' + | 'jockey' + | 'knight' + | 'meatmaster' + | 'milkman' + | 'necromancer' + | 'paladin' + | 'phoenix' + | 'pigman' + | 'rambo' + | 'random' + | 'ranger' + | 'reaper' + | 'reddragon' + | 'rogue' + | 'scout' + | 'shadow knight' + | 'shark' + | 'slimeyslime' + | 'snowman' + | 'speleologist' + | 'tim' + | 'toxicologist' + | 'troll' + | 'viking' + | 'warlock' + | 'warrior' + | 'wolftamer'; +export type BlitzSurvivalGamesKitName = + | 'Arachnologist' + | 'Archer' + | 'Armorer' + | 'Astronaut' + | 'Baker' + | 'Blaze' + | 'Creepertamer' + | 'Diver' + | 'Donkeytamer' + | 'Farmer' + | 'Fisherman' + | 'Florist' + | 'Golem' + | 'Guardian' + | 'Horsetamer' + | 'Hunter' + | 'Hype Train' + | 'Jockey' + | 'Knight' + | 'MeatMaster' + | 'Meatmaster' + | 'Milkman' + | 'Necromancer' + | 'Paladin' + | 'Phoenix' + | 'Pigman' + | 'Ranger' + | 'Reaper' + | 'RedDragon' + | 'Rogue' + | 'Scout' + | 'Shadow Knight' + | 'SlimeySlime' + | 'Snowman' + | 'Speleologist' + | 'Tim' + | 'Toxicologist' + | 'Troll' + | 'Viking' + | 'Warlock' + | 'Warrior' + | 'Wolftamer'; +export type BlitzSurvivalGamesAura = + | 'BLUE_PARTICLE' + | 'DAYLIGHT_PARTICLE' + | 'DRAGON_EGG_PARTICLE' + | 'DUST_PARTICLE' + | 'ENCHANTING_PARTICLE' + | 'FLOWER_TRAIL' + | 'GREEN_PARTICLE' + | 'LAVA_PARTICLE' + | 'MYCELIUM_TRAIL' + | 'NETHERRACK_TRAIL' + | 'PORTAL_PARTICLE' + | 'RAINBOW_PARTICLE' + | 'RED_PARTICLE' + | 'SLIME_PARTICLE' + | 'SNOW_PARTICLE' + | 'TRON_BLUE_TRAIL' + | 'TRON_GREEN_TRAIL' + | 'TRON_RAINBOW_TRAIL' + | 'TRON_RED_TRAIL' + | 'WATER_PARTICLE' + | 'WHEAT_TRAIL'; +export type BlitzSurvivalGamesTaunt = + | 'DEFAULT' + | 'BAT_DUDE' + | 'CHICKEN_DANCE' + | 'COOKIE' + | 'FIREWORK' + | 'I_REFUSE' + | 'KILLER_BUNNY' + | 'PIG_DANCE' + | 'PRESTIGE' + | 'RICH_JAMES' + | 'SHEEP_PARADE' + | 'VILLAGER_MUSIC_BAND' + | 'WOLF_PACK'; +export type BlitzSurvivalGamesVictoryDance = + | 'BLAZING_SPEED' + | 'COLORFUL_CHICKEN_RAIN' + | 'CREEPER' + | 'DRAGON_RIDER' + | 'EARTH' + | 'LEAPING_BUNNY' + | 'METEOR_SHOWER' + | 'PLAYER_FIREWORK'; +export type BlitzSurvivalGamesFinisher = + | 'CREEPER_FIREWORK' + | 'EXPLOSIONS' + | 'GRAVESTONE' + | 'INFESTATION' + | 'LIGHTNING_STRIKE' + | 'RABBIT_GIFT' + | 'REKT_HOLOGRAM' + | 'SQUID_MISSILE'; +export type BlitzSurvivalGamesKillEffect = 'gravedigger' | 'random' | 'rapid_fire' | 'regeneration' | 'resistance'; +export type BlitzSurvivalGamesLeaderboardSettingsMode = 'ALL_MODES' | 'SOLO' | 'TEAMS'; +export type BlitzSurvivalGamesPrivateGamesExtraStars = + | '1 Star - Normal' + | '2 Stars' + | '3 Stars' + | '4 Stars' + | '5 Stars'; diff --git a/src/Types/Requests.ts b/src/Types/Requests.ts new file mode 100644 index 000000000..3f9335a57 --- /dev/null +++ b/src/Types/Requests.ts @@ -0,0 +1,5 @@ +export interface RequestOptions { + raw?: boolean; + noCache?: boolean; + noCacheCheck?: boolean; +} diff --git a/src/Types/SkyBlock.ts b/src/Types/SkyBlock.ts new file mode 100644 index 000000000..76855c7ea --- /dev/null +++ b/src/Types/SkyBlock.ts @@ -0,0 +1,3630 @@ +import type SkyBlockMemberLeveling from '../Structures/SkyBlock/Member/SkyBlockMemberLeveling.js'; +import type SkyBlockMemberPlayerData from '../Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.js'; +import type SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import type { SortName } from './Global.js'; + +export interface RawAbiphoneData { + talked_to?: boolean; + completed_quest?: boolean; + incoming_calls_count?: number; + last_call_incoming?: number; +} + +export interface RawSkyBlockObjective { + status: 'COMPLETE' | 'ACTIVE'; + progress: number; + completed_at: number; +} + +export type HarpSong = + | 'hymn_joy' + | 'frere_jacques' + | 'amazing_grace' + | 'brahms' + | 'happy_birthday' + | 'greensleeves' + | 'jeopardy' + | 'minuet' + | 'joy_world' + | 'pure_imagination' + | 'vie_en_rose' + | 'fire_and_flames' + | 'pachelbel'; + +export type Rarity = + | 'COMMON' + | 'UNCOMMON' + | 'RARE' + | 'EPIC' + | 'LEGENDARY' + | 'MYTHIC' + | 'DIVINE' + | 'SPECIAL' + | 'VERY_SPECIAL'; + +export type Skills = + | 'farming' + | 'mining' + | 'combat' + | 'foraging' + | 'fishing' + | 'enchanting' + | 'alchemy' + | 'taming' + | 'carpentry' + | 'runecrafting' + | 'social'; + +export type GardenCrops = + | 'wheat' + | 'carrot' + | 'sugarCane' + | 'potato' + | 'pumpkin' + | 'melon' + | 'cactus' + | 'cocoaBeans' + | 'mushroom' + | 'netherWart' + | 'moonFlower' + | 'sunFlower' + | 'wildRose'; + +export type BankingTransactionAction = 'DEPOSIT' | 'WITHDRAW'; +export type CommunityUpgradesUpgrades = + | 'island_size' + | 'minion_slots' + | 'guests_count' + | 'coop_slots' + | 'coins_allowance'; + +export type SkyBlockProfileName = + | 'Apple' + | 'Banana' + | 'Blueberry' + | 'Coconut' + | 'Cucumber' + | 'Grapes' + | 'Kiwi' + | 'Lemon' + | 'Lime' + | 'Mango' + | 'Orange' + | 'Papaya' + | 'Pear' + | 'Peach' + | 'Pineapple' + | 'Pomegranate' + | 'Raspberry' + | 'Strawberry' + | 'Tomato' + | 'Watermelon' + | 'Zucchini' + | 'Not Allowed To Quit SkyBlock Ever Again' + | 'Complain Everyday' + | 'Restored' + | 'TEST'; + +export type SkyBlockArrow = + | 'ARROW' + | 'REINFORCED_IRON_ARROW' + | 'GOLD_TIPPED_ARROW' + | 'REDSTONE_TIPPED_ARROW' + | 'EMERALD_TIPPED_ARROW' + | 'BOUNCY_ARROW' + | 'ICY_ARROW' + | 'ARMORSHRED_ARROW' + | 'EXPLOSIVE_ARROW' + | 'GLUE_ARROW' + | 'NANSORB_ARROW'; + +export type MiningPickaxeAbility = + | 'mining_speed_boost' + | 'pickaxe_toss' + | 'anomalous_desire' + | 'maniac_miner' + | 'sheer_force'; + +export type MiningSkyMallEffect = + | 'dig_speed' + | 'mining_fortune' + | 'powder_bonus' + | 'pickaxe_ability_cooldown' + | 'goblin_chance' + | 'titanium_ore_multiplier'; +export type TaskLevelingSort = 'unlocked' | 'earned' | 'available' | SortName; +export type SkyBlockProfileType = 'bingo' | 'island' | 'ironman'; +export type CrimsonIsleFaction = 'mages' | 'barbarians'; +export type CrimsonIsleBelt = 'White' | 'Yellow' | 'Green' | 'Blue' | 'Brown' | 'Black'; +export type CrimsonIsleDojoRank = 'S' | 'A' | 'B' | 'C' | 'D' | 'F'; +export type CrimsonIsleTrophyFishRank = 'Bronze' | 'Silver' | 'Gold' | 'Diamond'; +export type CrimsonIsleKuudraTier = 'BASIC' | 'HOT' | 'BURNING' | 'FIERY' | 'INFERNAL'; +export type CrimsonIsleRingtone = + | 'DEFAULT' + | 'ENTERTAINER' + | 'NOTKIA' + | 'TEACHY' + | 'SCRAPPER' + | 'FUR_ELISE' + | 'JINGLE_BELLS' + | 'VIBRATE'; + +export type AbiphoneContactSort = 'first_added' | 'alphabetical' | 'last_called' | 'most_called' | 'dnd_enabled'; +export type AbiphoneContact = + | 'alchemist' + | 'alixer' + | 'anita' + | 'aranya' + | 'bingo' + | 'blacksmith' + | 'brynmor' + | 'builder' + | 'captain_ahone' + | 'dean' + | 'duncan' + | 'dusk' + | 'elizabeth' + | 'einary' + | 'elle' + | 'fann' + | 'fear_mongerer' + | 'fred' + | 'geo' + | 'george' + | 'hoppity' + | 'igrupan' + | 'jacob' + | 'jax' + | 'jotraeline_greatforge' + | 'kat' + | 'kaus' + | 'kuudra_gatekeeper' + | 'lumber_merchant' + | 'maddox_the_slayer' + | 'maxwell' + | 'mort' + | 'odger' + | 'ophelia' + | 'oringo' + | 'pablo' + | 'plumber_joe' + | 'queen_mismyla' + | 'queen_nyx' + | 'roddy' + | 'rollim' + | 'rusty' + | 'shifty' + | 'sirih' + | 'sirius' + | 'st._jerry' + | 'suus' + | 'tia_the_fairy' + | 'tomioka' + | 'trevor' + | 'trinity' + | 'vicent' + | 'walter' + | 'wool_weaver' + | 'zog'; +export type VisitorStatus = 'STARTED' | 'NOT_STARTED'; +export type SkyBlockSlayer = 'zombie' | 'spider' | 'wolf' | 'enderman' | 'blaze' | 'vampire'; +export type DungeonsTreasureType = 'wood' | 'gold' | 'diamond' | 'emerald' | 'obsidian' | 'bedrock'; +export type DungeonClass = 'healer' | 'mage' | 'berserk' | 'archer' | 'tank'; +export type DungeonGamemode = 'catacombs' | 'master_catacombs'; +export type SkyBlockDragon = 'protector' | 'old' | 'unstable' | 'young' | 'strong' | 'wise' | 'superior'; +export type ForgeItemType = + | 'REFINING' + | 'FORGING' + | 'PERFECT_GEMSTONES' + | 'REFINE' + | 'ITEM_CASTING' + | 'DRILL_PARTS' + | 'OTHER' + | 'PETS' + | 'GEAR'; +export type SkyBlockXPTables = Skills | 'default' | 'runecrafting' | 'dungeoneering' | 'hotm' | 'garden' | GardenCrops; +export type MiningPower = 'mithril' | 'gemstone' | 'glacite'; +export type MiningCrystal = + | 'jade' + | 'amber' + | 'amethyst' + | 'sapphire' + | 'topaz' + | 'jasper' + | 'ruby' + | 'aquamarine' + | 'opal' + | 'peridot' + | 'onyx' + | 'citrine'; + +export type MiningForgeItemId = + | 'REFINED_DIAMOND' + | 'REFINED_MITHRIL' + | 'REFINED_TITANIUM' + | 'REFINED_TUNGSTEN' + | 'REFINED_UMBER' + | 'MITHRIL_NECKLACE' + | 'MITHRIL_CLOAK' + | 'MITHRIL_BELT' + | 'MITHRIL_GAUNTLET' + | 'TITANIUM_NECKLACE' + | 'TITANIUM_CLOAK' + | 'TITANIUM_BELT' + | 'TITANIUM_GAUNTLET' + | 'TITANIUM_TALISMAN' + | 'TITANIUM_RING' + | 'TITANIUM_ARTIFACT' + | 'TITANIUM_RELIC' + | 'DIVAN_POWDER_COATING' + | 'DIVAN_HELMET' + | 'DIVAN_CHESTPLATE' + | 'DIVAN_LEGGINGS' + | 'DIVAN_BOOTS' + | 'AMBER_NECKLACE' + | 'SAPPHIRE_CLOAK' + | 'JADE_BELT' + | 'AMETHYST_GAUNTLET' + | 'GEMSTONE_CHAMBER' + | 'DWARVEN_HANDWARMERS' + | 'DWARVEN_METAL' + | 'DIVAN_PENDANT' + | 'POWER_RELIC' + | 'PERFECT_AMBER_GEM' + | 'PERFECT_AMETHYST_GEM' + | 'PERFECT_JADE_GEM' + | 'PERFECT_JASPER_GEM' + | 'PERFECT_OPAL_GEM' + | 'PERFECT_RUBY_GEM' + | 'PERFECT_SAPPHIRE_GEM' + | 'PERFECT_TOPAZ_GEM' + | 'PERFECT_AQUAMARINE_GEM' + | 'PERFECT_CITRINE_GEM' + | 'PERFECT_ONYX_GEM' + | 'PERFECT_PERIDOT_GEM' + | 'BEJEWELED_HANDLE' + | 'DRILL_ENGINE' + | 'FUEL_TANK' + | 'GEMSTONE_MIXTURE' + | 'GLACITE_AMALGAMATION' + | 'GOLDEN_PLATE' + | 'MITHRIL_PLATE' + | 'TUNGSTEN_PLATE' + | 'UMBER_PLATE' + | 'PERFECT_PLATE' + | 'DIAMONITE' + | 'POCKET_ICEBERG' + | 'PETRIFIED_STARFALL' + | 'PURE_MITHRIL' + | 'ROCK_GEMSTONE' + | 'TITANIUM_TESSERACT' + | 'GLEAMING_CRYSTAL' + | 'HOT_STUFF' + | 'AMBER_MATERIAL' + | 'FRIGID_HUSK' + | 'BEJEWELED_COLLAR' + | 'MOLE' + | 'AMMONITE' + | 'PENGUIN' + | 'TYRANNOSAURUS' + | 'SPINOSAURUS' + | 'GOBLIN' + | 'ANKYLOSAURUS' + | 'MAMMOTH' + | 'MITHRIL_DRILL_1' + | 'MITHRIL_DRILL_2' + | 'GEMSTONE_DRILL_1' + | 'GEMSTONE_DRILL_2' + | 'GEMSTONE_DRILL_3' + | 'GEMSTONE_DRILL_4' + | 'TOPAZ_ROD' + | 'TITANIUM_DRILL_1' + | 'TITANIUM_DRILL_2' + | 'TITANIUM_DRILL_3' + | 'TITANIUM_DRILL_4' + | 'CHISEL' + | 'REINFORCED_CHISEL' + | 'GLACITE_CHISEL' + | 'PERFECT_CHISEL' + | 'DIVAN_DRILL' + | 'STARFALL_SEASONING' + | 'GOBLIN_OMELETTE' + | 'GOBLIN_OMELETTE_BLUE_CHEESE' + | 'GOBLIN_OMELETTE_PESTO' + | 'GOBLIN_OMELETTE_SPICY' + | 'GOBLIN_OMELETTE_SUNNY_SIDE' + | 'TUNGSTEN_KEYCHAIN' + | 'MITHRIL_DRILL_ENGINE' + | 'TITANIUM_DRILL_ENGINE' + | 'RUBY_POLISHED_DRILL_ENGINE' + | 'SAPPHIRE_POLISHED_DRILL_ENGINE' + | 'AMBER_POLISHED_DRILL_ENGINE' + | 'MITHRIL_FUEL_TANK' + | 'TITANIUM_FUEL_TANK' + | 'GEMSTONE_FUEL_TANK' + | 'PERFECTLY_CUT_FUEL_TANK' + | 'BEACON_2' + | 'BEACON_3' + | 'BEACON_4' + | 'BEACON_5' + | 'FORGE_TRAVEL_SCROLL' + | 'BASE_CAMP_TRAVEL_SCROLL' + | 'POWER_CRYSTAL' + | 'SECRET_RAILROAD_PASS' + | 'TUNGSTEN_KEY' + | 'UMBER_KEY' + | 'SKELETON_KEY' + | 'PORTABLE_CAMPFIRE' + | 'PET'; + +export type MiningForgeItemName = + | 'Refined Diamond' + | 'Refined Mithril' + | 'Refined Titanium' + | 'Refined Tungsten' + | 'Refined Umber' + | 'Mithril Necklace' + | 'Mithril Cloak' + | 'Mithril Belt' + | 'Mithril Gauntlet' + | 'Titanium Necklace' + | 'Titanium Cloak' + | 'Titanium Belt' + | 'Titanium Gauntlet' + | 'Titanium Talisman' + | 'Titanium Ring' + | 'Titanium Artifact' + | 'Titanium Relic' + | 'Divan Powder Coating' + | 'Helmet Of Divan' + | 'Chestplate Of Divan' + | 'Leggings Of Divan' + | 'Boots Of Divan' + | 'Amber Necklace' + | 'Sapphire Cloak' + | 'Jade Belt' + | 'Amethyst Gauntlet' + | 'Gemstone Chamber' + | 'Dwarven Handwarmers' + | 'Dwarven Metal Talisman' + | 'Pendant of Divan' + | 'Relic of Power' + | 'Perfect Amber Gemstone' + | 'Perfect Amethyst Gemstone' + | 'Perfect Jade Gemstone' + | 'Perfect Jasper Gemstone' + | 'Perfect Opal Gemstone' + | 'Perfect Ruby Gemstone' + | 'Perfect Sapphire Gemstone' + | 'Perfect Topaz Gemstone' + | 'Perfect Aquamarine Gem' + | 'Perfect Citrine Gem' + | 'Perfect Onyx Gem' + | 'Perfect Peridot Gem' + | 'Bejeweled Handle' + | 'Drill Motor' + | 'Fuel Canister' + | 'Gemstone Mixture' + | 'Glacite Amalgamation' + | 'Golden Plate' + | 'Mithril Plate' + | 'Tungsten Plate' + | 'Umber Plate' + | 'Perfect Plate' + | 'Diamonite' + | 'Pocket Iceberg' + | 'Petrified Starfall' + | 'Pure Mithril' + | 'Dwarven Geode' + | 'Titanium Tesseract' + | 'Gleaming Crystal' + | 'Scorched Topaz' + | 'Amber Material' + | 'Frigid Husk' + | 'Bejeweled Collar' + | '[Lvl 1] Mole' + | '[Lvl 1] Ammonite' + | '[Lvl 1] Penguin' + | '[Lvl 1] T-Rex' + | '[Lvl 1] Spinosaurus' + | '[Lvl 1] Goblin' + | '[Lvl 1] Ankylosaurus' + | '[Lvl 1] Mammoth' + | 'Mithril Drill SX-R226' + | 'Mithril Drill SX-R326' + | 'Ruby Drill TX-15' + | 'Gemstone Drill LT-522' + | 'Topaz Drill KGR-12' + | 'Jasper Drill X' + | 'Topaz Rod' + | 'Titanium Drill DR-X355' + | 'Titanium Drill DR-X455' + | 'Titanium Drill DR-X555' + | 'Titanium Drill DR-X655' + | 'Chisel' + | 'Reinforced Chisel' + | 'Glacite-Plated Chisel' + | 'Perfect Chisel' + | "Divan's Drill" + | 'Starfall Seasoning' + | 'Goblin Omelette' + | 'Blue Cheese Goblin Omelette' + | 'Pesto Goblin Omelette' + | 'Spicy Goblin Omelette' + | 'Sunny Side Goblin Omelette' + | 'Tungsten Regulator' + | 'Mithril-Plated Drill Engine' + | 'Titanium-Plated Drill Engine' + | 'Ruby-Polished Drill Engine' + | 'Sapphire-Polished Drill Engine' + | 'Amber-Polished Drill Engine' + | 'Mithril-Infused Fuel Tank' + | 'Titanium-Infused Fuel Tank' + | 'Gemstone Fuel Tank' + | 'Perfectly-Cut Fuel Tank' + | 'Beacon II' + | 'Beacon III' + | 'Beacon IV' + | 'Beacon V' + | 'Travel Scroll to the Dwarven Forge' + | 'Travel Scroll to the Dwarven Base Camp' + | 'Power Crystal' + | 'Secret Railroad Pass' + | 'Tungsten Key' + | 'Umber Key' + | 'Skeleton Key' + | 'Portable Campfire' + | 'PET'; + +export type MiningForgeItemsData = { + [key in MiningForgeItemId | 'UNKNOWN']: { name: MiningForgeItemName | 'UNKNOWN'; duration: number }; +}; + +export type SkyBlockArea = + | 'dynamic' + | 'hub' + | 'mining_1' + | 'mining_2' + | 'mining_3' + | 'combat_1' + | 'crimson_isle' + | 'combat_3' + | 'farming_1' + | 'foraging_1' + | 'winter' + | 'dungeon' + | 'dungeon_hub' + | 'crystal_hollows' + | 'garden' + | 'rift' + | 'kuudra' + | 'mineshaft' + | 'fishing_1'; + +export type SkyBlockMemberPower = + | 'Fortuitous ' + | 'Pretty' + | 'Protected' + | 'Simple' + | 'Warrior' + | 'Commando' + | 'Disciplined' + | 'Inspired' + | 'Ominous ' + | 'Prepared' + | 'Silky' + | 'Sweet' + | 'Adept' + | 'Bloody' + | 'Forceful' + | 'Itchy' + | 'Mythical' + | 'Shaded' + | 'Sighted' + | 'Bizarre' + | 'Demonic' + | 'Hurtful' + | 'Pleasant' + | 'Sanguisuge' + | 'Frozen' + | 'Healthy' + | 'Slender' + | 'Strong' + | 'Bubba' + | 'Crumbly' + | 'Scorching' + | 'PET'; + +export type JacobCrops = + | 'INK_SACK:3' + | 'POTATO_ITEM' + | 'CARROT_ITEM' + | 'CACTUS' + | 'SUGAR_CANE' + | 'MUSHROOM_COLLECTION' + | 'PUMPKIN' + | 'NETHER_STALKk' + | 'WHEAT' + | 'MELON'; + +export interface CustomPetLevelingDataGoldenDragon { + type: number; + petLevels: number[]; + maxLevel: number; +} + +export interface CustomPetLevelingDataBingo { + rarityOffset: { [key in Rarity | 'UNKNOWN']: number }; +} +export interface CustomPetLevelingDataReindeer { + xpMultiplier: number; +} + +export interface CustomPetLevelingData { + GOLDEN_DRAGON: CustomPetLevelingDataGoldenDragon; + BINGO: CustomPetLevelingDataBingo; + REINDEER: CustomPetLevelingDataReindeer; +} + +export type SkyBlockPetId = + | 'FRACTURED_MONTEZUMA_SOUL' + | 'AMMONITE' + | 'ANKYLOSAURUS' + | 'BAL' + | 'ARMADILLO' + | 'BABY_YETI' + | 'BAT' + | 'BEE' + | 'BINGO' + | 'BLACK_CAT' + | 'BLAZE' + | 'BLUE_WHALE' + | 'CHICKEN' + | 'DOLPHIN' + | 'DROPLET_WISP' + | 'EERIE' + | 'ELEPHANT' + | 'ENDERMAN' + | 'ENDERMITE' + | 'ENDER_DRAGON' + | 'FLYING_FISH' + | 'FROST_WISP' + | 'GHOUL' + | 'GIRAFFE' + | 'GLACITE_GOLEM' + | 'GOBLIN' + | 'GOLEM' + | 'GUARDIAN' + | 'GOLDEN_DRAGON' + | 'GLACIAL_WISP' + | 'HEDGEHOG' + | 'HERMIT_CRAB' + | 'HORSE' + | 'HOUND' + | 'JELLYFISH' + | 'JERRY' + | 'KUUDRA' + | 'LION' + | 'MAGMA_CUBE' + | 'MAMMOTH' + | 'MEGALODON' + | 'MOLE' + | 'MONKEY' + | 'MOOSHROOM_COW' + | 'OCELOT' + | 'OWL' + | 'PARROT' + | 'PENGUIN' + | 'PHOENIX' + | 'PIG' + | 'PIGMAN' + | 'RABBIT' + | 'RIFT_FERRET' + | 'ROCK' + | 'REINDEER' + | 'SHEEP' + | 'SILVERFISH' + | 'SKELETON' + | 'SKELETON_HORSE' + | 'SNOWMAN' + | 'SLUG' + | 'SPIDER' + | 'SPINOSAURUS' + | 'SPIRIT' + | 'SQUID' + | 'SCATHA' + | 'SNAIL' + | 'SUBZERO_WISP' + | 'TYRANNOSAURUS' + | 'TARANTULA' + | 'TIGER' + | 'TURTLE' + | 'WITHER_SKELETON' + | 'WOLF' + | 'ZOMBIE' + | 'GRIFFIN' + | 'MITHRIL_GOLEM' + | 'GRANDMA_WOLF' + | 'RAT'; + +export interface LevelData { + xp: number; + level: number; + xpForNext: number | null; + progress: number; + maxed: boolean; + maxLevel: number; +} + +export interface PetLevelData extends LevelData { + xpMaxLevel: number; + currentXp: number; +} + +export interface SkillLevelData extends LevelData { + currentXp: number; +} + +export type BarnSkin = + | 'default_1' + | 'default_2' + | 'default_3' + | 'default_4' + | 'cabin' + | 'mansion_heights' + | 'cube' + | 'cozy_cottage' + | 'tavern' + | 'windmill' + | 'melon' + | 'lucky' + | 'trading_post' + | 'autumn_hut' + | 'bamboo' + | 'hive' + | 'castle' + | 'frog' + | 'jerry' + | 'pinwheel_house' + | 'mushroom' + | 'end' + | 'town_hall' + | 'winter_homestead' + | 'enchanted_nook' + | 'chocolate_factory' + | 'sand_castle' + | 'pesthunters_lair' + | 'winter_barn' + | 'beach_ball' + | 'main_street'; + +export type BarnPlot = + | 'beginner_1' + | 'beginner_2' + | 'beginner_3' + | 'beginner_4' + | 'intermediate_1' + | 'intermediate_2' + | 'intermediate_3' + | 'intermediate_4' + | 'advanced_1' + | 'advanced_2' + | 'advanced_3' + | 'advanced_4' + | 'advanced_5' + | 'advanced_6' + | 'advanced_7' + | 'advanced_8' + | 'advanced_9' + | 'advanced_10' + | 'advanced_11' + | 'advanced_12' + | 'expert_1' + | 'expert_2' + | 'expert_3' + | 'expert_4'; + +export type RiftVillagePlazaCowboyRabbit = + | 'Aaron' + | 'Abigail' + | 'Able' + | 'Ace' + | 'Achilles' + | 'Acker' + | 'Aladdin' + | 'Alexa' + | 'Alexander' + | 'Alfie' + | 'Alice' + | 'Aloysius' + | 'Alpaca' + | 'Alpine' + | 'Amazon' + | 'Angel' + | 'Angus' + | 'Annabelle' + | 'Apollo' + | 'Appollo' + | 'April' + | 'Archie' + | 'Arnie' + | 'Ashes' + | 'Asterix' + | 'Atlas' + | 'Audi' + | 'Augustus' + | 'Baby' + | 'Badger' + | 'Bagel' + | 'Baldwin' + | 'Baloo' + | 'Bambam' + | 'Bandit' + | 'Barbie' + | 'Barcode' + | 'Barney' + | 'Basket' + | 'Baxter' + | 'Beatrice' + | 'Benji' + | 'Bertha' + | 'Bibsy' + | 'Bilbo' + | 'Billy' + | 'Bindi' + | 'Binky' + | 'Bishop' + | 'Blackberry' + | 'Blackjack' + | 'Blake' + | 'Blossom' + | 'Blueberry' + | 'Bob' + | 'Bramble' + | 'Breeze' + | 'Brian' + | 'Brie' + | 'Bronson' + | 'Brooks' + | 'Bruce' + | 'Bruno' + | 'Brutus' + | 'Bubbles' + | 'Bubles' + | 'Buckwheat' + | 'Bud' + | 'Buffalo' + | 'Bugatti' + | 'Bugs' + | 'Bugster' + | 'Bugsy' + | 'Bumper' + | 'Bun Bun' + | 'Buster' + | 'Butters' + | 'Cadet' + | 'Cajun' + | 'Callie' + | 'Calypso' + | 'Candi' + | 'Caramel' + | 'Carter' + | 'Casanova' + | 'Casper' + | 'Cassidy' + | 'Charmin' + | 'Chase' + | 'Chester' + | 'Chevy' + | 'Chewy' + | 'Chilli' + | 'Chip' + | 'Chomper' + | 'Chompsky' + | 'Chubby' + | 'Cinnamon' + | 'Claude' + | 'Cloudy' + | 'Collin' + | 'Comet' + | 'Cookie' + | 'Cooper' + | 'Copper' + | 'Cotton' + | 'Cotton Puff' + | 'Cottonball' + | 'Cottontail' + | 'Cricket' + | 'Crystal' + | 'Cuddles' + | 'Cupcake' + | 'Dallas' + | 'Dalton' + | 'Dandelion' + | 'Dante' + | 'Darla' + | 'Dash' + | 'Delboy' + | 'Delilah' + | 'Demi' + | 'Destiny' + | 'Digger' + | 'Domino' + | 'Draco' + | 'Duchess' + | 'Dusty' + | 'Dutchess' + | 'Easter' + | 'Eastwood' + | 'Echo' + | 'Einstein' + | 'Ella' + | 'Ellie' + | 'Elvis' + | 'Emerson' + | 'Fergie' + | 'Fievel' + | 'Figaro' + | 'Fitch' + | 'Flip Flop' + | 'Fluffy' + | 'Forrest' + | 'Francine' + | 'Frank' + | 'Frankie' + | 'Frodo' + | 'Fudge' + | 'Fuzzy' + | 'Gadget' + | 'Galaxy' + | 'Gatsby' + | 'Gee-Gee' + | 'General' + | 'George' + | 'Ginger' + | 'Ginny' + | 'Gizmo' + | 'Gloria' + | 'Goofy' + | 'Gouda' + | 'Gracie' + | 'Gremlin' + | 'Guinness' + | 'Gunther' + | 'Hadley' + | 'Harley' + | 'Harmony' + | 'Hefner' + | 'Heidie' + | 'Herbie' + | 'Hershey' + | 'Hondo' + | 'Honey' + | 'Hop-a-long' + | 'Hope' + | 'Hopper' + | 'Houdini' + | 'Huck' + | 'Hugo' + | 'Humphrey' + | 'Hunter' + | 'Hyde' + | 'Iggy' + | 'Indie' + | 'Irena' + | 'Jake' + | 'James' + | 'Jammer' + | 'Jasmine' + | 'Jasper' + | 'Jazmin' + | 'Jazz' + | 'Jedi' + | 'Jeffery' + | 'Jelly Bean' + | 'Joey' + | 'Jonah' + | 'Josephine' + | 'Jynx' + | 'Kiera' + | 'King' + | 'Kobi' + | 'Kodo' + | 'Lenny' + | 'Leopold' + | 'Lilly' + | 'Lily' + | 'Linus' + | 'Lone Ranger' + | 'Lotte' + | 'Louie' + | 'Lulu' + | 'Magic' + | 'Mandy' + | 'Marlow' + | 'Maui' + | 'Max' + | 'Maybelline' + | 'Merlin' + | 'Mickey' + | 'Midnight' + | 'Miles' + | 'Milly' + | 'Milo' + | 'Mochi' + | 'Molly' + | 'Mona' + | 'Monalisa' + | 'Moody' + | 'Mookie' + | 'Mopsy' + | 'Morgan' + | 'Morris' + | 'Murphy' + | 'Mystic' + | 'Napoleon' + | 'Natalie' + | 'Ned' + | 'Neptune' + | 'Nibbles' + | 'Niko' + | 'Niza' + | 'Nova' + | 'Nutmeg' + | 'Oakley' + | 'Obelix' + | 'Oletta' + | 'Oliver' + | 'Olivette' + | 'Olivier' + | 'Ollie' + | 'Olympe' + | 'Onyx' + | 'Oreo' + | 'Orlando' + | 'Otto' + | 'Ozwald' + | 'Paddington' + | 'Paddy' + | 'Pancake' + | 'Patch' + | 'Patches' + | 'Peanut' + | 'Pebbles' + | 'Penelope' + | 'Penny' + | 'Peony' + | 'Pepper' + | 'Pepsi' + | 'Petunia' + | 'Phantom' + | 'Pickles' + | 'Pillsbury' + | 'Pinky' + | 'Polka Dot' + | 'Popcorn' + | 'Poppy' + | 'Porsche' + | 'Porter' + | 'Pretzel' + | 'Pride' + | 'Prince' + | 'Pumpkin' + | 'Punch' + | 'Quentin' + | 'Quincy' + | 'Rambo' + | 'Raven' + | 'Razzie' + | 'Reginald' + | 'Remi' + | 'Ressie' + | 'Ricky' + | 'Riley' + | 'Ringo' + | 'River' + | 'Rolf' + | 'Rosco' + | 'Ross' + | 'Rowdy' + | 'Ruben' + | 'Rupert' + | 'Rusty' + | 'Ryder' + | 'Sage' + | 'Sargent' + | 'Sassy' + | 'Scooter' + | 'Scotch' + | 'Scout' + | 'Scuba' + | 'Seinfield' + | 'Selene' + | 'Shadow' + | 'Simba' + | 'Skippe' + | 'Smokey' + | 'Sniffles' + | 'Snoopy' + | 'Snoppy' + | 'Snowball' + | 'Snuffy' + | 'Solomon' + | 'Sophie' + | 'Sorbet' + | 'Spencer' + | 'Spirit' + | 'Spooky' + | 'Spot' + | 'Sprinkles' + | 'Stanley' + | 'Stewart' + | 'Storm' + | 'Stormy' + | 'Stuart' + | 'Sunny' + | 'Suri' + | 'Sweetpea' + | 'Sylvester' + | 'Tagalong' + | 'Teddy' + | 'Thalai' + | 'Theo' + | 'Theodore' + | 'Thor' + | 'Thumper' + | 'Ticky' + | 'Tobi' + | 'Toby' + | 'Tornado' + | 'Tricky' + | 'Trix' + | 'Trixie' + | 'Turbo' + | 'Una' + | 'Uncle Buck' + | 'Vlad' + | 'Wadsworth' + | 'Waffle' + | 'Wesson' + | 'Widget' + | 'William' + | 'Willow' + | 'Winston' + | 'Zack' + | 'Zero' + | 'Zorro'; + +export type DungeonFloor = + | 'CATACOMBS_FLOOR_ONE' + | 'CATACOMBS_FLOOR_TWO' + | 'CATACOMBS_FLOOR_THREE' + | 'CATACOMBS_FLOOR_FOUR' + | 'CATACOMBS_FLOOR_FIVE' + | 'CATACOMBS_FLOOR_SIX' + | 'CATACOMBS_FLOOR_SEVEN' + | 'MASTER_CATACOMBS_FLOOR_ONE' + | 'MASTER_CATACOMBS_FLOOR_TWO' + | 'MASTER_CATACOMBS_FLOOR_THREE' + | 'MASTER_CATACOMBS_FLOOR_FOUR' + | 'MASTER_CATACOMBS_FLOOR_FIVE' + | 'MASTER_CATACOMBS_FLOOR_SIX' + | 'MASTER_CATACOMBS_FLOOR_SEVEN'; + +export type RiftGalleryTrophy = + | 'wyldly_supreme' + | 'chicken_n_egg' + | 'mirrored' + | 'citizen' + | 'lazy_living' + | 'slime' + | 'vampiric' + | 'mountain'; + +export type MirrorverseRoom = + | 'four levers' + | 'lava maze' + | 'crafting room' + | 'upside-down parkour' + | 'red-green puzzle' + | 'dance room' + | 'tubulator' + | 'reward room'; + +export type MirrorverseChestItem = + | 'TEST_BUCKET_PLEASE_IGNORE' + | 'BIG_BRAIN_TALISMAN' + | 'TINY_DANCER' + | 'MINIATURIZED_TUBULATOR'; + +export type SacrificedPets = + | 'RIFT_FERRET' + | 'SLUG' + | 'SPIRIT' + | 'GIRAFFE' + | 'JELLYFISH' + | 'BAL' + | 'BABY_YETI' + | 'BLACK_CAT' + | 'FROST_WISP' + | 'ENDERMAN'; + +export type CrimsonIsleBoss = 'BLADESOUL' | 'BARBARIAN_DUKE_X' | 'ASHFANG' | 'MAGE_OUTLAW' | 'MAGMA_BOSS'; +export type SkyBlockPotionEffectName = + | 'true_defense' + | 'strength' + | 'regeneration' + | 'enchanting_xp_boost' + | 'stun' + | 'experience' + | 'rabbit' + | 'magic_find' + | 'night_vision' + | 'water_breathing' + | 'combat_xp_boost' + | 'fire_resistance' + | 'jump_boost' + | 'resistance' + | 'fishing_xp_boost' + | 'agility' + | 'archery' + | 'critical' + | 'speed' + | 'farming_xp_boost' + | 'adrenaline' + | 'spelunker' + | 'dodge' + | 'spirit' + | 'pet_luck' + | 'mining_xp_boost' + | 'haste' + | 'burning' + | 'mana' + | 'foraging_xp_boost' + | 'alchemy_xp_boost' + | 'jerry_candy' + | 'burning' + | 'spirit' + | 'jump_boost' + | 'speed' + | 'invisibility'; + +export type WitherCageKilledEye = + | 'fisherman_hut' + | 'dreadfarm' + | 'plaza' + | 'wizard_tower' + | 'colosseum' + | 'castle' + | 'mountaintop'; + +export type SkyBlockMinionName = + | 'ACACIA' + | 'BIRCH' + | 'BLAZE' + | 'CACTUS' + | 'CARROT' + | 'CAVESPIDER' + | 'CHICKEN' + | 'CLAY' + | 'COAL' + | 'COBBLESTONE' + | 'COCOA' + | 'COW' + | 'CREEPER' + | 'DARK_OAK' + | 'DIAMOND' + | 'EMERALD' + | 'ENDERMAN' + | 'ENDER_STONE' + | 'FISHING' + | 'FLOWER' + | 'GHAST' + | 'GLOWSTONE' + | 'GOLD' + | 'GRAVEL' + | 'HARD_STONE' + | 'ICE' + | 'INFERNO' + | 'IRON' + | 'JUNGLE' + | 'LAPIS' + | 'MAGMA_CUBE' + | 'MELON' + | 'MITHRIL' + | 'MUSHROOM' + | 'MYCELIUM' + | 'NETHER_WARTS' + | 'OAK' + | 'OBSIDIAN' + | 'PIG' + | 'POTATO' + | 'PUMPKIN' + | 'QUARTZ' + | 'RABBIT' + | 'REDSTONE' + | 'RED_SAND' + | 'REVENANT' + | 'SAND' + | 'SHEEP' + | 'SKELETON' + | 'SLIME' + | 'SNOW' + | 'SPIDER' + | 'SPRUCE' + | 'SUGAR_CANE' + | 'TARANTULA' + | 'VAMPIRE' + | 'VOIDLING' + | 'WHEAT' + | 'ZOMBIE'; + +export type SkyBlockMinion = + | 'ACACIA_1' + | 'ACACIA_2' + | 'ACACIA_3' + | 'ACACIA_4' + | 'ACACIA_5' + | 'ACACIA_6' + | 'ACACIA_7' + | 'ACACIA_8' + | 'ACACIA_9' + | 'ACACIA_10' + | 'ACACIA_11' + | 'ACACIA_12' + | 'BIRCH_1' + | 'BIRCH_2' + | 'BIRCH_3' + | 'BIRCH_4' + | 'BIRCH_5' + | 'BIRCH_6' + | 'BIRCH_7' + | 'BIRCH_8' + | 'BIRCH_9' + | 'BIRCH_10' + | 'BIRCH_11' + | 'BIRCH_12' + | 'BLAZE_1' + | 'BLAZE_2' + | 'BLAZE_3' + | 'BLAZE_4' + | 'BLAZE_5' + | 'BLAZE_6' + | 'BLAZE_7' + | 'BLAZE_8' + | 'BLAZE_9' + | 'BLAZE_10' + | 'BLAZE_11' + | 'BLAZE_12' + | 'CACTUS_1' + | 'CACTUS_2' + | 'CACTUS_3' + | 'CACTUS_4' + | 'CACTUS_5' + | 'CACTUS_6' + | 'CACTUS_7' + | 'CACTUS_8' + | 'CACTUS_9' + | 'CACTUS_10' + | 'CACTUS_11' + | 'CACTUS_12' + | 'CARROT_1' + | 'CARROT_2' + | 'CARROT_3' + | 'CARROT_4' + | 'CARROT_5' + | 'CARROT_6' + | 'CARROT_7' + | 'CARROT_8' + | 'CARROT_9' + | 'CARROT_10' + | 'CARROT_11' + | 'CARROT_12' + | 'CAVESPIDER_1' + | 'CAVESPIDER_2' + | 'CAVESPIDER_3' + | 'CAVESPIDER_4' + | 'CAVESPIDER_5' + | 'CAVESPIDER_6' + | 'CAVESPIDER_7' + | 'CAVESPIDER_8' + | 'CAVESPIDER_9' + | 'CAVESPIDER_10' + | 'CAVESPIDER_11' + | 'CAVESPIDER_12' + | 'CHICKEN_1' + | 'CHICKEN_2' + | 'CHICKEN_3' + | 'CHICKEN_4' + | 'CHICKEN_5' + | 'CHICKEN_6' + | 'CHICKEN_7' + | 'CHICKEN_8' + | 'CHICKEN_9' + | 'CHICKEN_10' + | 'CHICKEN_11' + | 'CHICKEN_12' + | 'CLAY_1' + | 'CLAY_2' + | 'CLAY_3' + | 'CLAY_4' + | 'CLAY_5' + | 'CLAY_6' + | 'CLAY_7' + | 'CLAY_8' + | 'CLAY_9' + | 'CLAY_10' + | 'CLAY_11' + | 'CLAY_12' + | 'COAL_1' + | 'COAL_2' + | 'COAL_3' + | 'COAL_4' + | 'COAL_5' + | 'COAL_6' + | 'COAL_7' + | 'COAL_8' + | 'COAL_9' + | 'COAL_10' + | 'COAL_11' + | 'COAL_12' + | 'COBBLESTONE_1' + | 'COBBLESTONE_2' + | 'COBBLESTONE_3' + | 'COBBLESTONE_4' + | 'COBBLESTONE_5' + | 'COBBLESTONE_6' + | 'COBBLESTONE_7' + | 'COBBLESTONE_8' + | 'COBBLESTONE_9' + | 'COBBLESTONE_10' + | 'COBBLESTONE_11' + | 'COBBLESTONE_12' + | 'COCOA_1' + | 'COCOA_2' + | 'COCOA_3' + | 'COCOA_4' + | 'COCOA_5' + | 'COCOA_6' + | 'COCOA_7' + | 'COCOA_8' + | 'COCOA_9' + | 'COCOA_10' + | 'COCOA_11' + | 'COCOA_12' + | 'COW_1' + | 'COW_2' + | 'COW_3' + | 'COW_4' + | 'COW_5' + | 'COW_6' + | 'COW_7' + | 'COW_8' + | 'COW_9' + | 'COW_10' + | 'COW_11' + | 'COW_12' + | 'CREEPER_1' + | 'CREEPER_2' + | 'CREEPER_3' + | 'CREEPER_4' + | 'CREEPER_5' + | 'CREEPER_6' + | 'CREEPER_7' + | 'CREEPER_8' + | 'CREEPER_9' + | 'CREEPER_10' + | 'CREEPER_11' + | 'CREEPER_12' + | 'DARK_OAK_1' + | 'DARK_OAK_2' + | 'DARK_OAK_3' + | 'DARK_OAK_4' + | 'DARK_OAK_5' + | 'DARK_OAK_6' + | 'DARK_OAK_7' + | 'DARK_OAK_8' + | 'DARK_OAK_9' + | 'DARK_OAK_10' + | 'DARK_OAK_11' + | 'DARK_OAK_12' + | 'DIAMOND_1' + | 'DIAMOND_2' + | 'DIAMOND_3' + | 'DIAMOND_4' + | 'DIAMOND_5' + | 'DIAMOND_6' + | 'DIAMOND_7' + | 'DIAMOND_8' + | 'DIAMOND_9' + | 'DIAMOND_10' + | 'DIAMOND_11' + | 'DIAMOND_12' + | 'EMERALD_1' + | 'EMERALD_2' + | 'EMERALD_3' + | 'EMERALD_4' + | 'EMERALD_5' + | 'EMERALD_6' + | 'EMERALD_7' + | 'EMERALD_8' + | 'EMERALD_9' + | 'EMERALD_10' + | 'EMERALD_11' + | 'EMERALD_12' + | 'ENDERMAN_1' + | 'ENDERMAN_2' + | 'ENDERMAN_3' + | 'ENDERMAN_4' + | 'ENDERMAN_5' + | 'ENDERMAN_6' + | 'ENDERMAN_7' + | 'ENDERMAN_8' + | 'ENDERMAN_9' + | 'ENDERMAN_10' + | 'ENDERMAN_11' + | 'ENDERMAN_12' + | 'ENDER_STONE_1' + | 'ENDER_STONE_2' + | 'ENDER_STONE_3' + | 'ENDER_STONE_4' + | 'ENDER_STONE_5' + | 'ENDER_STONE_6' + | 'ENDER_STONE_7' + | 'ENDER_STONE_8' + | 'ENDER_STONE_9' + | 'ENDER_STONE_10' + | 'ENDER_STONE_11' + | 'ENDER_STONE_12' + | 'FISHING_1' + | 'FISHING_2' + | 'FISHING_3' + | 'FISHING_4' + | 'FISHING_5' + | 'FISHING_6' + | 'FISHING_7' + | 'FISHING_8' + | 'FISHING_9' + | 'FISHING_10' + | 'FISHING_11' + | 'FISHING_12' + | 'FLOWER_1' + | 'FLOWER_2' + | 'FLOWER_3' + | 'FLOWER_4' + | 'FLOWER_5' + | 'FLOWER_6' + | 'FLOWER_7' + | 'FLOWER_8' + | 'FLOWER_9' + | 'FLOWER_10' + | 'FLOWER_11' + | 'FLOWER_12' + | 'GHAST_1' + | 'GHAST_2' + | 'GHAST_3' + | 'GHAST_4' + | 'GHAST_5' + | 'GHAST_6' + | 'GHAST_7' + | 'GHAST_8' + | 'GHAST_9' + | 'GHAST_10' + | 'GHAST_11' + | 'GHAST_12' + | 'GLOWSTONE_1' + | 'GLOWSTONE_2' + | 'GLOWSTONE_3' + | 'GLOWSTONE_4' + | 'GLOWSTONE_5' + | 'GLOWSTONE_6' + | 'GLOWSTONE_7' + | 'GLOWSTONE_8' + | 'GLOWSTONE_9' + | 'GLOWSTONE_10' + | 'GLOWSTONE_11' + | 'GLOWSTONE_12' + | 'GOLD_1' + | 'GOLD_2' + | 'GOLD_3' + | 'GOLD_4' + | 'GOLD_5' + | 'GOLD_6' + | 'GOLD_7' + | 'GOLD_8' + | 'GOLD_9' + | 'GOLD_10' + | 'GOLD_11' + | 'GOLD_12' + | 'GRAVEL_1' + | 'GRAVEL_2' + | 'GRAVEL_3' + | 'GRAVEL_4' + | 'GRAVEL_5' + | 'GRAVEL_6' + | 'GRAVEL_7' + | 'GRAVEL_8' + | 'GRAVEL_9' + | 'GRAVEL_10' + | 'GRAVEL_11' + | 'GRAVEL_12' + | 'HARD_STONE_1' + | 'HARD_STONE_2' + | 'HARD_STONE_3' + | 'HARD_STONE_4' + | 'HARD_STONE_5' + | 'HARD_STONE_6' + | 'HARD_STONE_7' + | 'HARD_STONE_8' + | 'HARD_STONE_9' + | 'HARD_STONE_10' + | 'HARD_STONE_11' + | 'HARD_STONE_12' + | 'ICE_1' + | 'ICE_2' + | 'ICE_3' + | 'ICE_4' + | 'ICE_5' + | 'ICE_6' + | 'ICE_7' + | 'ICE_8' + | 'ICE_9' + | 'ICE_10' + | 'ICE_11' + | 'ICE_12' + | 'INFERNO_1' + | 'INFERNO_2' + | 'INFERNO_3' + | 'INFERNO_4' + | 'INFERNO_5' + | 'INFERNO_6' + | 'INFERNO_7' + | 'INFERNO_8' + | 'INFERNO_9' + | 'INFERNO_10' + | 'INFERNO_11' + | 'INFERNO_12' + | 'IRON_1' + | 'IRON_2' + | 'IRON_3' + | 'IRON_4' + | 'IRON_5' + | 'IRON_6' + | 'IRON_7' + | 'IRON_8' + | 'IRON_9' + | 'IRON_10' + | 'IRON_11' + | 'IRON_12' + | 'JUNGLE_1' + | 'JUNGLE_2' + | 'JUNGLE_3' + | 'JUNGLE_4' + | 'JUNGLE_5' + | 'JUNGLE_6' + | 'JUNGLE_7' + | 'JUNGLE_8' + | 'JUNGLE_9' + | 'JUNGLE_10' + | 'JUNGLE_11' + | 'JUNGLE_12' + | 'LAPIS_1' + | 'LAPIS_2' + | 'LAPIS_3' + | 'LAPIS_4' + | 'LAPIS_5' + | 'LAPIS_6' + | 'LAPIS_7' + | 'LAPIS_8' + | 'LAPIS_9' + | 'LAPIS_10' + | 'LAPIS_11' + | 'LAPIS_12' + | 'MAGMA_CUBE_1' + | 'MAGMA_CUBE_2' + | 'MAGMA_CUBE_3' + | 'MAGMA_CUBE_4' + | 'MAGMA_CUBE_5' + | 'MAGMA_CUBE_6' + | 'MAGMA_CUBE_7' + | 'MAGMA_CUBE_8' + | 'MAGMA_CUBE_9' + | 'MAGMA_CUBE_10' + | 'MAGMA_CUBE_11' + | 'MAGMA_CUBE_12' + | 'MELON_1' + | 'MELON_2' + | 'MELON_3' + | 'MELON_4' + | 'MELON_5' + | 'MELON_6' + | 'MELON_7' + | 'MELON_8' + | 'MELON_9' + | 'MELON_10' + | 'MELON_11' + | 'MELON_12' + | 'MITHRIL_1' + | 'MITHRIL_2' + | 'MITHRIL_3' + | 'MITHRIL_4' + | 'MITHRIL_5' + | 'MITHRIL_6' + | 'MITHRIL_7' + | 'MITHRIL_8' + | 'MITHRIL_9' + | 'MITHRIL_10' + | 'MITHRIL_11' + | 'MITHRIL_12' + | 'MUSHROOM_1' + | 'MUSHROOM_2' + | 'MUSHROOM_3' + | 'MUSHROOM_4' + | 'MUSHROOM_5' + | 'MUSHROOM_6' + | 'MUSHROOM_7' + | 'MUSHROOM_8' + | 'MUSHROOM_9' + | 'MUSHROOM_10' + | 'MUSHROOM_11' + | 'MUSHROOM_12' + | 'MYCELIUM_1' + | 'MYCELIUM_2' + | 'MYCELIUM_3' + | 'MYCELIUM_4' + | 'MYCELIUM_5' + | 'MYCELIUM_6' + | 'MYCELIUM_7' + | 'MYCELIUM_8' + | 'MYCELIUM_9' + | 'MYCELIUM_10' + | 'MYCELIUM_11' + | 'MYCELIUM_12' + | 'NETHER_WARTS_1' + | 'NETHER_WARTS_2' + | 'NETHER_WARTS_3' + | 'NETHER_WARTS_4' + | 'NETHER_WARTS_5' + | 'NETHER_WARTS_6' + | 'NETHER_WARTS_7' + | 'NETHER_WARTS_8' + | 'NETHER_WARTS_9' + | 'NETHER_WARTS_10' + | 'NETHER_WARTS_11' + | 'NETHER_WARTS_12' + | 'OAK_1' + | 'OAK_2' + | 'OAK_3' + | 'OAK_4' + | 'OAK_5' + | 'OAK_6' + | 'OAK_7' + | 'OAK_8' + | 'OAK_9' + | 'OAK_10' + | 'OAK_11' + | 'OAK_12' + | 'OBSIDIAN_1' + | 'OBSIDIAN_2' + | 'OBSIDIAN_3' + | 'OBSIDIAN_4' + | 'OBSIDIAN_5' + | 'OBSIDIAN_6' + | 'OBSIDIAN_7' + | 'OBSIDIAN_8' + | 'OBSIDIAN_9' + | 'OBSIDIAN_10' + | 'OBSIDIAN_11' + | 'OBSIDIAN_12' + | 'PIG_1' + | 'PIG_2' + | 'PIG_3' + | 'PIG_4' + | 'PIG_5' + | 'PIG_6' + | 'PIG_7' + | 'PIG_8' + | 'PIG_9' + | 'PIG_10' + | 'PIG_11' + | 'PIG_12' + | 'POTATO_1' + | 'POTATO_2' + | 'POTATO_3' + | 'POTATO_4' + | 'POTATO_5' + | 'POTATO_6' + | 'POTATO_7' + | 'POTATO_8' + | 'POTATO_9' + | 'POTATO_10' + | 'POTATO_11' + | 'POTATO_12' + | 'PUMPKIN_1' + | 'PUMPKIN_2' + | 'PUMPKIN_3' + | 'PUMPKIN_4' + | 'PUMPKIN_5' + | 'PUMPKIN_6' + | 'PUMPKIN_7' + | 'PUMPKIN_8' + | 'PUMPKIN_9' + | 'PUMPKIN_10' + | 'PUMPKIN_11' + | 'PUMPKIN_12' + | 'QUARTZ_1' + | 'QUARTZ_2' + | 'QUARTZ_3' + | 'QUARTZ_4' + | 'QUARTZ_5' + | 'QUARTZ_6' + | 'QUARTZ_7' + | 'QUARTZ_8' + | 'QUARTZ_9' + | 'QUARTZ_10' + | 'QUARTZ_11' + | 'QUARTZ_12' + | 'RABBIT_1' + | 'RABBIT_2' + | 'RABBIT_3' + | 'RABBIT_4' + | 'RABBIT_5' + | 'RABBIT_6' + | 'RABBIT_7' + | 'RABBIT_8' + | 'RABBIT_9' + | 'RABBIT_10' + | 'RABBIT_11' + | 'RABBIT_12' + | 'REDSTONE_1' + | 'REDSTONE_2' + | 'REDSTONE_3' + | 'REDSTONE_4' + | 'REDSTONE_5' + | 'REDSTONE_6' + | 'REDSTONE_7' + | 'REDSTONE_8' + | 'REDSTONE_9' + | 'REDSTONE_10' + | 'REDSTONE_11' + | 'REDSTONE_12' + | 'RED_SAND_1' + | 'RED_SAND_2' + | 'RED_SAND_3' + | 'RED_SAND_4' + | 'RED_SAND_5' + | 'RED_SAND_6' + | 'RED_SAND_7' + | 'RED_SAND_8' + | 'RED_SAND_9' + | 'RED_SAND_10' + | 'RED_SAND_11' + | 'RED_SAND_12' + | 'REVENANT_1' + | 'REVENANT_2' + | 'REVENANT_3' + | 'REVENANT_4' + | 'REVENANT_5' + | 'REVENANT_6' + | 'REVENANT_7' + | 'REVENANT_8' + | 'REVENANT_9' + | 'REVENANT_10' + | 'REVENANT_11' + | 'REVENANT_12' + | 'SAND_1' + | 'SAND_2' + | 'SAND_3' + | 'SAND_4' + | 'SAND_5' + | 'SAND_6' + | 'SAND_7' + | 'SAND_8' + | 'SAND_9' + | 'SAND_10' + | 'SAND_11' + | 'SAND_12' + | 'SHEEP_1' + | 'SHEEP_2' + | 'SHEEP_3' + | 'SHEEP_4' + | 'SHEEP_5' + | 'SHEEP_6' + | 'SHEEP_7' + | 'SHEEP_8' + | 'SHEEP_9' + | 'SHEEP_10' + | 'SHEEP_11' + | 'SHEEP_12' + | 'SKELETON_1' + | 'SKELETON_2' + | 'SKELETON_3' + | 'SKELETON_4' + | 'SKELETON_5' + | 'SKELETON_6' + | 'SKELETON_7' + | 'SKELETON_8' + | 'SKELETON_9' + | 'SKELETON_10' + | 'SKELETON_11' + | 'SKELETON_12' + | 'SLIME_1' + | 'SLIME_2' + | 'SLIME_3' + | 'SLIME_4' + | 'SLIME_5' + | 'SLIME_6' + | 'SLIME_7' + | 'SLIME_8' + | 'SLIME_9' + | 'SLIME_10' + | 'SLIME_11' + | 'SLIME_12' + | 'SNOW_1' + | 'SNOW_2' + | 'SNOW_3' + | 'SNOW_4' + | 'SNOW_5' + | 'SNOW_6' + | 'SNOW_7' + | 'SNOW_8' + | 'SNOW_9' + | 'SNOW_10' + | 'SNOW_11' + | 'SNOW_12' + | 'SPIDER_1' + | 'SPIDER_2' + | 'SPIDER_3' + | 'SPIDER_4' + | 'SPIDER_5' + | 'SPIDER_6' + | 'SPIDER_7' + | 'SPIDER_8' + | 'SPIDER_9' + | 'SPIDER_10' + | 'SPIDER_11' + | 'SPIDER_12' + | 'SPRUCE_1' + | 'SPRUCE_2' + | 'SPRUCE_3' + | 'SPRUCE_4' + | 'SPRUCE_5' + | 'SPRUCE_6' + | 'SPRUCE_7' + | 'SPRUCE_8' + | 'SPRUCE_9' + | 'SPRUCE_10' + | 'SPRUCE_11' + | 'SPRUCE_12' + | 'SUGAR_CANE_1' + | 'SUGAR_CANE_2' + | 'SUGAR_CANE_3' + | 'SUGAR_CANE_4' + | 'SUGAR_CANE_5' + | 'SUGAR_CANE_6' + | 'SUGAR_CANE_7' + | 'SUGAR_CANE_8' + | 'SUGAR_CANE_9' + | 'SUGAR_CANE_10' + | 'SUGAR_CANE_11' + | 'SUGAR_CANE_12' + | 'TARANTULA_1' + | 'TARANTULA_2' + | 'TARANTULA_3' + | 'TARANTULA_4' + | 'TARANTULA_5' + | 'TARANTULA_6' + | 'TARANTULA_7' + | 'TARANTULA_8' + | 'TARANTULA_9' + | 'TARANTULA_10' + | 'TARANTULA_11' + | 'TARANTULA_12' + | 'VAMPIRE_1' + | 'VAMPIRE_2' + | 'VAMPIRE_3' + | 'VAMPIRE_4' + | 'VAMPIRE_5' + | 'VAMPIRE_6' + | 'VAMPIRE_7' + | 'VAMPIRE_8' + | 'VAMPIRE_9' + | 'VAMPIRE_10' + | 'VAMPIRE_11' + | 'VAMPIRE_12' + | 'VOIDLING_1' + | 'VOIDLING_2' + | 'VOIDLING_3' + | 'VOIDLING_4' + | 'VOIDLING_5' + | 'VOIDLING_6' + | 'VOIDLING_7' + | 'VOIDLING_8' + | 'VOIDLING_9' + | 'VOIDLING_10' + | 'VOIDLING_11' + | 'VOIDLING_12' + | 'WHEAT_1' + | 'WHEAT_2' + | 'WHEAT_3' + | 'WHEAT_4' + | 'WHEAT_5' + | 'WHEAT_6' + | 'WHEAT_7' + | 'WHEAT_8' + | 'WHEAT_9' + | 'WHEAT_10' + | 'WHEAT_11' + | 'WHEAT_12' + | 'ZOMBIE_1' + | 'ZOMBIE_2' + | 'ZOMBIE_3' + | 'ZOMBIE_4' + | 'ZOMBIE_5' + | 'ZOMBIE_6' + | 'ZOMBIE_7' + | 'ZOMBIE_8' + | 'ZOMBIE_9' + | 'ZOMBIE_10' + | 'ZOMBIE_11' + | 'ZOMBIE_12'; + +export type BazaarProduct = + | 'INK_SACK:3' + | 'CORRUPTED_BAIT' + | 'INK_SACK:4' + | 'TARANTULA_WEB' + | 'ENCHANTMENT_ULTIMATE_NO_PAIN_NO_GAIN_2' + | 'ENCHANTMENT_ULTIMATE_NO_PAIN_NO_GAIN_1' + | 'DUNGEON_TRAP' + | 'DARK_ORB' + | 'ARCHITECT_FIRST_DRAFT' + | 'ENCHANTMENT_PROTECTION_7' + | 'ENCHANTMENT_PROTECTION_6' + | 'ESSENCE_DRAGON' + | 'RITUAL_RESIDUE' + | 'ENCHANTMENT_PROTECTION_1' + | 'GIANT_FRAGMENT_LASER' + | 'ENCHANTMENT_PROTECTION_5' + | 'ENCHANTED_MELON' + | 'ENCHANTMENT_PROTECTION_4' + | 'ENCHANTMENT_PROTECTION_3' + | 'ENCHANTMENT_PROTECTION_2' + | 'ENCHANTMENT_TURBO_COCO_1' + | 'ENCHANTMENT_TURBO_COCO_5' + | 'ENCHANTMENT_TURBO_COCO_4' + | 'ENCHANTMENT_TURBO_COCO_3' + | 'ENCHANTED_BLAZE_ROD' + | 'ENCHANTMENT_TURBO_COCO_2' + | 'FRESHLY_MINTED_COINS' + | 'ENCHANTED_BROWN_MUSHROOM' + | 'GOBLIN_EGG_YELLOW' + | 'PARTY_GIFT' + | 'ENCHANTED_GLISTERING_MELON' + | 'ENCHANTMENT_CORRUPTION_5' + | 'ENCHANTMENT_CORRUPTION_4' + | 'PROTECTOR_FRAGMENT' + | 'ENCHANTMENT_CORRUPTION_3' + | 'ENCHANTMENT_CORRUPTION_2' + | 'MAGMAG' + | 'ENCHANTMENT_CORRUPTION_1' + | 'ENCHANTED_MELON_BLOCK' + | 'ROCK_GEMSTONE' + | 'CONDENSED_FERMENTO' + | 'BEADY_EYES' + | 'DIAMOND' + | 'COBBLESTONE' + | 'ENCHANTED_PUFFERFISH' + | 'PERFECT_RUBY_GEM' + | 'MINION_EXPANDER' + | 'HORN_OF_TAURUS' + | 'END_STONE_SHULKER' + | 'MAGMA_LORD_FRAGMENT' + | 'ENCHANTMENT_CAYENNE_5' + | 'ENCHANTED_HARD_STONE' + | 'ENCHANTMENT_CAYENNE_4' + | 'WINTER_FRAGMENT' + | 'ENDER_MONOCLE' + | 'KELVIN_INVERTER' + | 'REFINED_DIAMOND' + | 'X' + | 'Y' + | 'HAZMAT_ENDERMAN' + | 'Z' + | 'LUXURIOUS_SPOOL' + | 'FLAWED_OPAL_GEM' + | 'ENCHANTMENT_CAYENNE_3' + | 'PORK' + | 'ENCHANTMENT_CAYENNE_2' + | 'ENCHANTMENT_CAYENNE_1' + | 'FLAMES' + | 'ENCHANTMENT_ENDER_SLAYER_1' + | 'ULTIMATE_CARROT_CANDY' + | 'HONEY_JAR' + | 'PET_CAKE' + | 'SOLAR_PANEL' + | 'ENCHANTMENT_LAPIDARY_4' + | 'ENCHANTMENT_LAPIDARY_3' + | 'ENCHANTMENT_LAPIDARY_2' + | 'ENCHANTMENT_LAPIDARY_1' + | 'ENCHANTMENT_FIRE_ASPECT_1' + | 'LOG_2:1' + | 'UNDEAD_CATALYST' + | 'ENCHANTMENT_TURBO_CACTUS_5' + | 'ENCHANTED_SNOW_BLOCK' + | 'ENCHANTMENT_TURBO_CACTUS_4' + | 'ENCHANTMENT_TURBO_CACTUS_3' + | 'OLD_LEATHER_BOOT' + | 'ENCHANTMENT_TURBO_CACTUS_2' + | 'ENCHANTMENT_FIRE_ASPECT_2' + | 'ENCHANTMENT_TURBO_CACTUS_1' + | 'ENCHANTMENT_FIRE_ASPECT_3' + | 'ENCHANTMENT_LAPIDARY_5' + | 'ENCHANTMENT_ENDER_SLAYER_5' + | 'ENCHANTMENT_ENDER_SLAYER_4' + | 'ENCHANTMENT_ENDER_SLAYER_3' + | 'ENCHANTMENT_ENDER_SLAYER_2' + | 'ENCHANTMENT_ENDER_SLAYER_7' + | 'ENCHANTMENT_ENDER_SLAYER_6' + | 'ENCHANTMENT_SHARPNESS_1' + | 'DUNGEON_DECOY' + | 'REFINED_TUNGSTEN' + | 'ENCHANTMENT_SHARPNESS_5' + | 'JERRY_BOX_GOLDEN' + | 'ENCHANTMENT_SHARPNESS_4' + | 'ENCHANTMENT_SHARPNESS_3' + | 'ENCHANTMENT_SHARPNESS_2' + | 'ENCHANTMENT_BIG_BRAIN_4' + | 'ENCHANTMENT_BIG_BRAIN_5' + | 'ENCHANTMENT_BIG_BRAIN_3' + | 'MUTATED_BLAZE_ASHES' + | 'ENCHANTED_CARROT_ON_A_STICK' + | 'ENCHANTMENT_THUNDERLORD_7' + | 'ENCHANTMENT_THUNDERLORD_6' + | 'ENCHANTMENT_TURBO_MELON_5' + | 'FLY_SWATTER' + | 'DERELICT_ASHE' + | 'ENCHANTMENT_THUNDERLORD_3' + | 'ENCHANTMENT_THUNDERLORD_2' + | 'ENCHANTMENT_SHARPNESS_7' + | 'ENCHANTMENT_THUNDERLORD_5' + | 'ENCHANTMENT_SHARPNESS_6' + | 'ENCHANTMENT_THUNDERLORD_4' + | 'ENCHANTED_ACACIA_LOG' + | 'ENCHANTMENT_MANA_STEAL_1' + | 'ENCHANTMENT_MANA_STEAL_2' + | 'ENCHANTMENT_THUNDERLORD_1' + | 'ENCHANTMENT_MANA_STEAL_3' + | 'SAND' + | 'ANCIENT_CLAW' + | 'ENCHANTMENT_TURBO_MELON_3' + | 'PLASMA_BUCKET' + | 'ENCHANTMENT_STRONG_MANA_7' + | 'ENCHANTED_GHAST_TEAR' + | 'ENCHANTMENT_STRONG_MANA_6' + | 'ENCHANTMENT_TURBO_MELON_4' + | 'ENCHANTED_COCOA' + | 'ENCHANTMENT_STRONG_MANA_5' + | 'ENCHANTMENT_TURBO_MELON_1' + | 'ENCHANTMENT_STRONG_MANA_4' + | 'ENCHANTMENT_TURBO_MELON_2' + | 'ENCHANTMENT_STRONG_MANA_3' + | 'AMBER_MATERIAL' + | 'ENCHANTMENT_STRONG_MANA_2' + | 'ENCHANTMENT_STRONG_MANA_1' + | 'CARROT_BAIT' + | 'FINE_TOPAZ_GEM' + | 'FINE_RUBY_GEM' + | 'HYPERGOLIC_IONIZED_CERAMICS' + | 'THUNDER_SHARDS' + | 'HAY_BLOCK' + | 'ENCHANTED_ROTTEN_FLESH' + | 'ENCHANTED_GRILLED_PORK' + | 'WISHING_COMPASS' + | 'ENCHANTED_ANCIENT_CLAW' + | 'BRIMSTONE_HANDLE' + | 'DWARVEN_OS_ORE_OATS' + | 'ENCHANTMENT_HARDENED_MANA_1' + | 'PUMPKIN_BOMB' + | 'OVERGROWN_GRASS' + | 'FULL_CHUM_BUCKET' + | 'ENCHANTMENT_HARDENED_MANA_3' + | 'ENCHANTMENT_HARDENED_MANA_2' + | 'SOULFLOW_ENGINE' + | 'ENCHANTMENT_ULTIMATE_COMBO_1' + | 'ENCHANTMENT_ULTIMATE_COMBO_2' + | 'ENCHANTMENT_ULTIMATE_COMBO_5' + | 'PET_ITEM_TOY_JERRY' + | 'ENCHANTMENT_ULTIMATE_COMBO_3' + | 'ENCHANTED_LAVA_BUCKET' + | 'ENCHANTMENT_ULTIMATE_COMBO_4' + | 'RAW_FISH:3' + | 'BUBBA_BLISTER' + | 'ENCHANTED_UMBER' + | 'ENCHANTMENT_STRONG_MANA_9' + | 'ENCHANTMENT_STRONG_MANA_8' + | 'ROUGH_AQUAMARINE_GEM' + | 'DIAMOND_ATOM' + | 'RAW_FISH:2' + | 'HALF_EATEN_MUSHROOM' + | 'RAW_FISH:1' + | 'PRECURSOR_GEAR' + | 'GOBLIN_EGG_RED' + | 'ENCHANTMENT_TURBO_WARTS_1' + | 'TROUBLED_BUBBLE' + | 'ENCHANTMENT_TURBO_WARTS_2' + | 'ENCHANTMENT_TURBO_WARTS_3' + | 'ENCHANTMENT_TURBO_WARTS_4' + | 'ENCHANTMENT_TURBO_WARTS_5' + | 'WHALE_BAIT' + | 'SPONGE' + | 'ENCHANTED_DARK_OAK_LOG' + | 'FLAWLESS_TOPAZ_GEM' + | 'ENCHANTMENT_HARDENED_MANA_5' + | 'ENCHANTMENT_HARDENED_MANA_4' + | 'CAPSAICIN_EYEDROPS_NO_CHARGES' + | 'ENCHANTMENT_HARDENED_MANA_7' + | 'ENCHANTMENT_HARDENED_MANA_6' + | 'ENCHANTMENT_ULTIMATE_NO_PAIN_NO_GAIN_4' + | 'ENCHANTMENT_HARDENED_MANA_9' + | 'ENCHANTMENT_ULTIMATE_NO_PAIN_NO_GAIN_3' + | 'ENCHANTMENT_HARDENED_MANA_8' + | 'ENCHANTMENT_ULTIMATE_NO_PAIN_NO_GAIN_5' + | 'ENCHANTED_RAW_CHICKEN' + | 'ENCHANTED_WATER_LILY' + | 'RED_SCARF' + | 'LOG:1' + | 'TITANIUM_ORE' + | 'BLUE_SHARK_TOOTH' + | 'ROBOTRON_REFLECTOR' + | 'LOG:3' + | 'CHILI_PEPPER' + | 'LOG:2' + | 'ENCHANTED_HAY_BALE' + | 'SIL_EX' + | 'SALT_CUBE' + | 'ENCHANTED_CACTUS' + | 'ONYX' + | 'ENCHANTED_COOKED_SALMON' + | 'ENCHANTED_SULPHUR' + | 'TITANIUM_TESSERACT' + | 'ENCHANTED_SEEDS' + | 'ENCHANTED_BONE_MEAL' + | 'ENCHANTMENT_EXPERIENCE_5' + | 'ENCHANTED_BONE_BLOCK' + | 'SMALL_ENCHANTED_CHEST' + | 'OMEGA_EGG' + | 'PURPLE_CANDY' + | 'ENCHANTMENT_EXPERIENCE_2' + | 'POLISHED_PUMPKIN' + | 'ENCHANTMENT_EXPERIENCE_1' + | 'ENCHANTMENT_EXPERIENCE_4' + | 'ENCHANTMENT_EXPERIENCE_3' + | 'ENCHANTED_GOLD_BLOCK' + | 'FINE_OPAL_GEM' + | 'ENCHANTED_FLINT' + | 'FAKE_SHURIKEN' + | 'SPOTLITE' + | 'SCORCHED_POWER_CRYSTAL' + | 'SCARF_FRAGMENT' + | 'REHEATED_GUMMY_POLAR_BEAR' + | 'FURBALL' + | 'ESSENCE_SPIDER' + | 'ENCHANTED_CLAY_BALL' + | 'GLOWSTONE_DUST' + | 'FLYCATCHER_UPGRADE' + | 'PERFECT_AMETHYST_GEM' + | 'IMPLOSION_SCROLL' + | 'FTX_3070' + | 'CROPIE' + | 'PET_ITEM_VAMPIRE_FANG' + | 'ENDSTONE_GEODE' + | 'ENCHANTMENT_PALEONTOLOGIST_5' + | 'MILLENIA_OLD_BLAZE_ASHES' + | 'GREAT_CARROT_CANDY' + | 'ENCHANTMENT_MANA_VAMPIRE_10' + | 'OPTICAL_LENS' + | 'ENCHANTED_BONE' + | 'LAVA_WATER_ORB' + | 'ENCHANTMENT_PALEONTOLOGIST_3' + | 'ENCHANTMENT_PALEONTOLOGIST_4' + | 'ENCHANTED_DIAMOND_BLOCK' + | 'ENCHANTMENT_PALEONTOLOGIST_1' + | 'ENCHANTMENT_DELICATE_5' + | 'ENCHANTMENT_PALEONTOLOGIST_2' + | 'GOBLIN_EGG_GREEN' + | 'ENCHANTMENT_PROSECUTE_6' + | 'ENCHANTMENT_CASTER_1' + | 'ENCHANTMENT_PROSECUTE_5' + | 'ENCHANTMENT_CASTER_2' + | 'GIANT_FRAGMENT_BIGFOOT' + | 'LIGHT_BAIT' + | 'HOT_POTATO_BOOK' + | 'CUP_OF_BLOOD' + | 'MAGIC_MUSHROOM_SOUP' + | 'ENCHANTMENT_CASTER_3' + | 'CLAY_BALL' + | 'ENCHANTMENT_CASTER_4' + | 'ENCHANTMENT_CASTER_5' + | 'OLD_FRAGMENT' + | 'ENCHANTMENT_CASTER_6' + | 'BEATING_HEART' + | 'ROUGH_AMBER_GEM' + | 'ENCHANTMENT_PROSECUTE_4' + | 'ENCHANTMENT_PROSECUTE_3' + | 'ENCHANTMENT_PROSECUTE_2' + | 'ENCHANTMENT_PROSECUTE_1' + | 'AMALGAMATED_CRIMSONITE' + | 'FINE_AMBER_GEM' + | 'SUPER_MAGIC_MUSHROOM_SOUP' + | 'ENCHANTED_QUARTZ' + | 'ENDER_PEARL' + | 'ENCHANTED_COAL_BLOCK' + | 'LESSER_SOULFLOW_ENGINE' + | 'ENCHANTED_GLACITE' + | 'LARGE_WALNUT' + | 'FLAWED_JADE_GEM' + | 'TOIL_LOG' + | 'SLUDGE_JUICE' + | 'BONZO_FRAGMENT' + | 'SPECTRE_DUST' + | 'BROKEN_RADAR' + | 'ENCHANTMENT_RESPITE_5' + | 'SUGAR_CANE' + | 'ENCHANTMENT_RESPITE_3' + | 'ENCHANTMENT_RESPITE_4' + | 'ENCHANTMENT_RESPITE_1' + | 'ENCHANTMENT_RESPITE_2' + | 'CORRUPTED_FRAGMENT' + | 'TESSELLATED_ENDER_PEARL' + | 'ENCHANTED_RAW_BEEF' + | 'AOTE_STONE' + | 'RABBIT_HIDE' + | 'INFERNO_FUEL_BLOCK' + | 'ENCHANTMENT_OVERLOAD_5' + | 'ENCHANTMENT_OVERLOAD_4' + | 'ENCHANTMENT_OVERLOAD_3' + | 'ENCHANTMENT_OVERLOAD_2' + | 'ENCHANTMENT_OVERLOAD_1' + | 'DARK_BAIT' + | 'ENCHANTED_PUMPKIN' + | 'ENCHANTED_COOKED_FISH' + | 'OBSIDIAN' + | 'PET_ITEM_EXP_SHARE_DROP' + | 'STARFALL' + | 'ENCHANTMENT_FIRE_PROTECTION_6' + | 'SECOND_MASTER_STAR' + | 'ENCHANTMENT_FIRE_PROTECTION_5' + | 'ROUGH_ONYX_GEM' + | 'ENCHANTMENT_FIRE_PROTECTION_7' + | 'ENCHANTMENT_HARDENED_MANA_10' + | 'FLAWLESS_ONYX_GEM' + | 'ENCHANTMENT_ULTIMATE_REND_3' + | 'ENCHANTMENT_ULTIMATE_JERRY_2' + | 'ENTROPY_SUPPRESSOR' + | 'ENCHANTMENT_ULTIMATE_JERRY_1' + | 'ENCHANTMENT_ULTIMATE_REND_2' + | 'ENCHANTMENT_ULTIMATE_REND_1' + | 'ENCHANTED_POPPY' + | 'GLOWSTONE_DUST_DISTILLATE' + | 'ENCHANTMENT_ULTIMATE_JERRY_5' + | 'ENCHANTMENT_ULTIMATE_JERRY_4' + | 'ENCHANTMENT_ULTIMATE_REND_5' + | 'DWARVEN_OS_GEMSTONE_GRAHAMS' + | 'ENCHANTMENT_ULTIMATE_JERRY_3' + | 'ENCHANTMENT_ULTIMATE_REND_4' + | 'ENCHANTMENT_FIRE_PROTECTION_2' + | 'ENCHANTMENT_FIRE_PROTECTION_1' + | 'BAZAAR_COOKIE' + | 'ENCHANTMENT_FIRE_PROTECTION_4' + | 'ENCHANTMENT_FIRE_PROTECTION_3' + | 'FLAWLESS_PERIDOT_GEM' + | 'BROWN_MUSHROOM' + | 'DISPLACED_LEECH' + | 'ENCHANTMENT_HARVESTING_5' + | 'ENCHANTMENT_HARVESTING_4' + | 'ENCHANTMENT_HARVESTING_3' + | 'CARROT_ITEM' + | 'OVERFLOWING_TRASH_CAN' + | 'ENCHANTMENT_HARVESTING_2' + | 'ENCHANTMENT_HARVESTING_1' + | 'UMBER' + | 'MOLTEN_CUBE' + | 'EXP_BOTTLE' + | 'HEALING_TISSUE' + | 'ENCHANTED_RABBIT_HIDE' + | 'ENCHANTMENT_HARVESTING_6' + | 'SQUEAKY_TOY' + | 'WATER_ORB' + | 'GLACITE_JEWEL' + | 'MATCH_STICKS' + | 'INFERNO_VERTEX' + | 'RUSTY_ANCHOR' + | 'WEAK_WOLF_CATALYST' + | 'FLAWED_AMETHYST_GEM' + | 'PERFECT_JADE_GEM' + | 'ENCHANTED_BIRCH_LOG' + | 'FOURTH_MASTER_STAR' + | 'ENCHANTED_GUNPOWDER' + | 'REFINED_AMBER' + | 'ENCHANTED_SUGAR' + | 'CACTUS' + | 'DUNG' + | 'ENCHANTED_RAW_SALMON' + | 'BOBBIN_SCRIPTURES' + | 'ENCHANTED_EMERALD' + | 'RED_MUSHROOM' + | 'GRAND_EXP_BOTTLE' + | 'MUTTON' + | 'ENCHANTMENT_DEDICATION_2' + | 'ENCHANTMENT_DEDICATION_1' + | 'ENCHANTMENT_DEDICATION_4' + | 'ENCHANTMENT_DEDICATION_3' + | 'ENCHANTMENT_ULTIMATE_WISE_2' + | 'SPIDER_EYE' + | 'ENCHANTMENT_ULTIMATE_WISE_1' + | 'ENCHANTMENT_ULTIMATE_WISE_4' + | 'ENCHANTMENT_ULTIMATE_WISE_3' + | 'BEJEWELED_HANDLE' + | 'LARGE_ENCHANTED_CHEST' + | 'ENCHANTED_NETHERRACK' + | 'JADERALD' + | 'ENCHANTMENT_TRUE_PROTECTION_1' + | 'CORRUPT_SOIL' + | 'PRISMARINE_CRYSTALS' + | 'RARE_DIAMOND' + | 'DWARVEN_OS_BLOCK_BRAN' + | 'COMPACT_OOZE' + | 'GLOSSY_GEMSTONE' + | 'ICE' + | 'TIGER_SHARK_TOOTH' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_4' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_5' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_6' + | 'ENCHANTMENT_SMARTY_PANTS_3' + | 'ENCHANTMENT_ULTIMATE_WISE_5' + | 'ENCHANTMENT_SMARTY_PANTS_2' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_1' + | 'ENCHANTMENT_SMARTY_PANTS_5' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_2' + | 'ENCHANTMENT_SMARTY_PANTS_4' + | 'ENCHANTMENT_LUCK_OF_THE_SEA_3' + | 'GOLDEN_TOOTH' + | 'THE_ART_OF_PEACE' + | 'ENCHANTMENT_SMARTY_PANTS_1' + | 'LUMP_OF_MAGMA' + | 'HYPER_CATALYST' + | 'VOLTA' + | 'RABBIT_FOOT' + | 'SUPERLITE_MOTOR' + | 'REDSTONE' + | 'BRAIDED_GRIFFIN_FEATHER' + | 'SUSPICIOUS_SCRAP' + | 'SPIRIT_WING' + | 'PET_ITEM_CHOCOLATE_SYRINGE' + | 'BLAZEN_SPHERE' + | 'SPOOKY_WATER_ORB' + | 'THE_ART_OF_WAR' + | 'ENCHANTMENT_LURE_2' + | 'ENCHANTMENT_LURE_1' + | 'SLIME_BALL' + | 'ENCHANTMENT_LURE_6' + | 'ENCHANTMENT_LURE_5' + | 'ENCHANTMENT_LURE_4' + | 'ENCHANTMENT_LURE_3' + | 'HOLY_FRAGMENT' + | 'SNOW_BALL' + | 'ENCHANTED_WOOL' + | 'ENCHANTED_EGG' + | 'GLEAMING_CRYSTAL' + | 'RUSTY_COIN' + | 'SUPERB_CARROT_CANDY' + | 'ENCHANTMENT_FEROCIOUS_MANA_8' + | 'ENCHANTMENT_FEROCIOUS_MANA_9' + | 'FINE_JADE_GEM' + | 'ENCHANTMENT_FEROCIOUS_MANA_4' + | 'FLAWED_RUBY_GEM' + | 'ENCHANTMENT_MAGNET_2' + | 'RAW_CHICKEN' + | 'ENCHANTMENT_FEROCIOUS_MANA_5' + | 'ENCHANTMENT_MAGNET_1' + | 'SORROW' + | 'ENCHANTMENT_FEROCIOUS_MANA_6' + | 'ENCHANTMENT_MAGNET_4' + | 'ENCHANTMENT_FEROCIOUS_MANA_7' + | 'ENCHANTMENT_MAGNET_3' + | 'FLAWLESS_JASPER_GEM' + | 'ENCHANTMENT_MAGNET_6' + | 'ENCHANTMENT_FEROCIOUS_MANA_1' + | 'ENCHANTMENT_MAGNET_5' + | 'ENCHANTMENT_FEROCIOUS_MANA_2' + | 'LUSH_BERBERIS' + | 'ENCHANTMENT_FEROCIOUS_MANA_3' + | 'ENCHANTMENT_PESTERMINATOR_1' + | 'ENCHANTMENT_PESTERMINATOR_2' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_7' + | 'ENCHANTMENT_CHAMPION_10' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_6' + | 'ENCHANTMENT_PESTERMINATOR_3' + | 'ENCHANTED_SHARK_FIN' + | 'ENCHANTMENT_PESTERMINATOR_4' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_5' + | 'ENCHANTMENT_PESTERMINATOR_5' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_4' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_3' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_2' + | 'ENCHANTMENT_PROJECTILE_PROTECTION_1' + | 'INK_SACK' + | 'ENCHANTMENT_SMALL_BRAIN_5' + | 'CRYSTAL_FRAGMENT' + | 'ENCHANTED_REDSTONE_BLOCK' + | 'DIVAN_POWDER_COATING' + | 'ENCHANTMENT_SMALL_BRAIN_3' + | 'INFERNO_APEX' + | 'ENCHANTMENT_SMALL_BRAIN_4' + | 'ENCHANTED_REDSTONE_LAMP' + | 'TREASURITE' + | 'PERFECT_OPAL_GEM' + | 'MELON' + | 'DIAMONITE' + | 'GLOWING_MUSHROOM' + | 'ENCHANTMENT_DRAGON_HUNTER_4' + | 'ENCHANTMENT_DRAGON_HUNTER_3' + | 'ENCHANTMENT_DRAGON_HUNTER_5' + | 'ENCHANTED_IRON_BLOCK' + | 'ENCHANTMENT_DRAGON_HUNTER_2' + | 'BONE' + | 'ENCHANTMENT_DRAGON_HUNTER_1' + | 'POISONOUS_POTATO' + | 'KISMET_FEATHER' + | 'REVENANT_FLESH' + | 'VOLCANIC_ROCK' + | 'ENCHANTED_GLOWSTONE' + | 'OBSIDIAN_TABLET' + | 'ESSENCE_WITHER' + | 'GENERATOR_UPGRADE_STONE_CLAY_12' + | 'ENCHANTMENT_CHARM_2' + | 'ENCHANTMENT_CHARM_3' + | 'ENCHANTMENT_CHARM_1' + | 'BLAZE_ROD' + | 'ENCHANTMENT_CHARM_4' + | 'YOUNG_FRAGMENT' + | 'ENCHANTMENT_CHARM_5' + | 'MITHRIL_PLATE' + | 'BLOOD_SOAKED_COINS' + | 'REFINED_MINERAL' + | 'CHYME' + | 'GUARDIAN_LUCKY_BLOCK' + | 'DIVAN_FRAGMENT' + | 'ROUGH_RUBY_GEM' + | 'ENCHANTMENT_IMPALING_3' + | 'ENCHANTMENT_IMPALING_2' + | 'GOBLIN_EGG_BLUE' + | 'ENCHANTMENT_IMPALING_1' + | 'DIGESTED_MUSHROOMS' + | 'CATALYST' + | 'MOBY_DUCK_COLLECTOR_EDITION' + | 'REFINED_DARK_CACAO_TRUFFLE' + | 'ENCHANTED_INK_SACK' + | 'JERRY_STONE' + | 'MOLTEN_POWDER' + | 'FLAWLESS_SAPPHIRE_GEM' + | 'MAGMA_URCHIN' + | 'PERFECT_AQUAMARINE_GEM' + | 'JACOBS_TICKET' + | 'BAT_FIREWORK' + | 'ENCHANTMENT_QUANTUM_4' + | 'ENCHANTMENT_QUANTUM_5' + | 'ABSOLUTE_ENDER_PEARL' + | 'ARACHNE_FRAGMENT' + | 'ENCHANTMENT_QUANTUM_3' + | 'ENCHANTMENT_REPLENISH_1' + | 'ENCHANTED_ENDER_PEARL' + | 'ARROW_BUNDLE_MAGMA' + | 'SPIKED_BAIT' + | 'ENCHANTED_FERMENTED_SPIDER_EYE' + | 'FROZEN_BAIT' + | 'BLESSED_FRUIT' + | 'ENCHANTMENT_ULTIMATE_SWARM_5' + | 'VERY_CRUDE_GABAGOOL' + | 'ENCHANTMENT_TURBO_WHEAT_3' + | 'ENCHANTMENT_TURBO_WHEAT_4' + | 'CHAIN_END_TIMES' + | 'ENCHANTMENT_SILK_TOUCH_1' + | 'ENCHANTMENT_TURBO_WHEAT_1' + | 'ENCHANTMENT_TURBO_WHEAT_2' + | 'ENCHANTMENT_ULTIMATE_SWARM_3' + | 'ENCHANTMENT_ULTIMATE_SWARM_4' + | 'ENCHANTMENT_ULTIMATE_SWARM_1' + | 'ENCHANTMENT_TURBO_WHEAT_5' + | 'EXPORTABLE_CARROTS' + | 'ENCHANTMENT_ULTIMATE_SWARM_2' + | 'NULL_OVOID' + | 'GOLD_INGOT' + | 'ENCHANTMENT_SUGAR_RUSH_3' + | 'ENCHANTMENT_SUGAR_RUSH_2' + | 'FLAWLESS_CITRINE_GEM' + | 'ENCHANTED_IRON' + | 'ENCHANTMENT_SUGAR_RUSH_1' + | 'BEZOS' + | 'ENCHANTED_HAY_BLOCK' + | 'HEMOVIBE' + | 'ENCHANTED_TITANIUM' + | 'DWARVEN_OS_METALLIC_MINIS' + | 'SPOOKY_BAIT' + | 'HEAVY_PEARL' + | 'TWILIGHT_ARROW_POISON' + | 'EMERALD' + | 'ENCHANTED_RABBIT_FOOT' + | 'POTATO_SPREADING' + | 'ENCHANTED_ICE' + | 'ARACHNE_KEEPER_FRAGMENT' + | 'ENCHANTMENT_GROWTH_1' + | 'ENCHANTMENT_GROWTH_2' + | 'GREEN_GIFT' + | 'ENCHANTMENT_GROWTH_3' + | 'ENCHANTMENT_GROWTH_4' + | 'SKELETON_KEY' + | 'ENCHANTMENT_GROWTH_5' + | 'ENCHANTMENT_GROWTH_6' + | 'FLAWLESS_AMETHYST_GEM' + | 'RED_NOSE' + | 'ENCHANTMENT_GROWTH_7' + | 'NULL_EDGE' + | 'THORN_FRAGMENT' + | 'PACKED_ICE' + | 'YELLOW_FLOWER' + | 'CLIPPED_WINGS' + | 'REVENANT_CATALYST' + | 'WITHER_CATALYST' + | 'HAMSTER_WHEEL' + | 'PESTHUNTING_GUIDE' + | 'ENCHANTED_COAL' + | 'MAGMA_FISH_SILVER' + | 'SULPHURIC_COAL' + | 'FLAWLESS_OPAL_GEM' + | 'ESSENCE_UNDEAD' + | 'GENERATOR_UPGRADE_STONE_FISHING_12' + | 'DRAGON_CLAW' + | 'DAEDALUS_STICK' + | 'ENCHANTMENT_ULTIMATE_CHIMERA_1' + | 'ENCHANTMENT_ULTIMATE_LAST_STAND_5' + | 'ENCHANTMENT_ULTIMATE_LAST_STAND_4' + | 'ENCHANTMENT_ULTIMATE_CHIMERA_5' + | 'ENCHANTMENT_ULTIMATE_LAST_STAND_3' + | 'ENCHANTMENT_ULTIMATE_LAST_STAND_2' + | 'ENCHANTMENT_ULTIMATE_CHIMERA_4' + | 'PET_ITEM_PURE_MITHRIL_GEM' + | 'ENCHANTMENT_ULTIMATE_LAST_STAND_1' + | 'ENCHANTMENT_ULTIMATE_CHIMERA_3' + | 'JUNGLE_HEART' + | 'ENCHANTMENT_ULTIMATE_CHIMERA_2' + | 'LUCKY_DICE' + | 'GOLD_BOTTLE_CAP' + | 'FOUL_FLESH' + | 'RAW_BEEF' + | 'ENCHANTED_EYE_OF_ENDER' + | 'ECTOPLASM' + | 'GIANT_BOUNCY_BEACH_BALL' + | 'ORB_OF_ENERGY' + | 'PRECIOUS_PEARL' + | 'ENCHANTED_MYCELIUM' + | 'MAGMA_FISH_DIAMOND' + | 'RABBIT' + | 'ENCHANTED_HOPPER' + | 'FINE_FLOUR' + | 'ENCHANTMENT_QUICK_BITE_4' + | 'GRIFFIN_FEATHER' + | 'HEMOBOMB' + | 'POLARVOID_BOOK' + | 'ENCHANTMENT_QUICK_BITE_3' + | 'ENCHANTMENT_QUICK_BITE_2' + | 'FREE_WILL' + | 'ENCHANTMENT_QUICK_BITE_1' + | 'GIANT_FRAGMENT_DIAMOND' + | 'SOULFLOW' + | 'METAPHYSICAL_SERUM' + | 'AVARICIOUS_CHALICE' + | 'MINNOW_BAIT' + | 'ENCHANTED_MAGMA_CREAM' + | 'ENCHANTED_FIREWORK_ROCKET' + | 'BLAZE_WAX' + | 'WITHER_BLOOD' + | 'ENCHANTMENT_QUICK_BITE_5' + | 'ENCHANTMENT_EFFICIENCY_5' + | 'ENCHANTMENT_EFFICIENCY_4' + | 'CHOCOLATE_CHIP' + | 'ENCHANTMENT_EFFICIENCY_3' + | 'BOUNCY_BEACH_BALL' + | 'ENCHANTMENT_EFFICIENCY_2' + | 'HARD_STONE' + | 'FLAWLESS_JADE_GEM' + | 'ENCHANTMENT_EFFICIENCY_1' + | 'SUPERBOOM_TNT' + | 'ENCHANTED_COOKED_MUTTON' + | 'ENCHANTMENT_EFFICIENCY_9' + | 'ENCHANTMENT_EFFICIENCY_8' + | 'REFINED_TITANIUM' + | 'FLAWED_ONYX_GEM' + | 'ENCHANTMENT_EFFICIENCY_7' + | 'ENCHANTMENT_FEATHER_FALLING_10' + | 'ENCHANTMENT_EFFICIENCY_6' + | 'SHINY_PRISM' + | 'ENCHANTMENT_SMOLDERING_5' + | 'ENCHANTMENT_SMOLDERING_3' + | 'ENCHANTMENT_SMOLDERING_4' + | 'ENCHANTMENT_SMOLDERING_1' + | 'EGG' + | 'FIRST_MASTER_STAR' + | 'ENCHANTMENT_SMOLDERING_2' + | 'UMBER_KEY' + | 'FLOWERING_BOUQUET' + | 'SPIRIT_LEAP' + | 'FINE_JASPER_GEM' + | 'ENCHANTED_CHARCOAL' + | 'BOOK_OF_STATS' + | 'SIMPLE_CARROT_CANDY' + | 'ENCHANTED_DIAMOND' + | 'ENCHANTMENT_FEATHER_FALLING_20' + | 'TITANOBOA_SHED' + | 'OIL_BARREL' + | 'CORRUPTED_NETHER_STAR' + | 'GOLEM_POPPY' + | 'HORNS_OF_TORMENT' + | 'ENCHANTMENT_CRITICAL_6' + | 'JERRY_BOX_GREEN' + | 'FARMING_FOR_DUMMIES' + | 'ENCHANTMENT_CRITICAL_7' + | 'POCKET_ICEBERG' + | 'ENCHANTMENT_TOXOPHILITE_1' + | 'ENCHANTMENT_CRITICAL_4' + | 'ENCHANTMENT_CRITICAL_5' + | 'ENCHANTMENT_CRITICAL_2' + | 'ENCHANTED_GOLDEN_CARROT' + | 'ENCHANTED_TUNGSTEN' + | 'ENCHANTMENT_CRITICAL_3' + | 'ENCHANTMENT_CRITICAL_1' + | 'MANA_DISINTEGRATOR' + | 'ENCHANTMENT_AIMING_1' + | 'ENCHANTMENT_AIMING_2' + | 'ENCHANTMENT_AIMING_3' + | 'ENCHANTMENT_AIMING_4' + | 'ENCHANTMENT_AIMING_5' + | 'SHADOW_WARP_SCROLL' + | 'FLAWED_PERIDOT_GEM' + | 'ENCHANTMENT_ULTIMATE_HABANERO_TACTICS_4' + | 'ENCHANTMENT_FROST_WALKER_2' + | 'ENCHANTMENT_THUNDERBOLT_6' + | 'ENCHANTMENT_THUNDERBOLT_7' + | 'ENCHANTMENT_BLAST_PROTECTION_7' + | 'ENCHANTED_MYCELIUM_CUBE' + | 'ENCHANTMENT_ULTIMATE_HABANERO_TACTICS_5' + | 'FLAWED_JASPER_GEM' + | 'ENCHANTMENT_FROST_WALKER_1' + | 'EXPIRED_PUMPKIN' + | 'ENCHANTMENT_ICE_COLD_4' + | 'ENCHANTMENT_ICE_COLD_3' + | 'ENCHANTMENT_THUNDERBOLT_1' + | 'GLACIAL_FRAGMENT' + | 'ENCHANTED_POISONOUS_POTATO' + | 'ENCHANTMENT_ICE_COLD_5' + | 'TUNGSTEN_PLATE' + | 'FLAWED_AMBER_GEM' + | 'ENCHANTMENT_THUNDERBOLT_4' + | 'ENCHANTMENT_THUNDERBOLT_5' + | 'ENCHANTMENT_ICE_COLD_2' + | 'ENCHANTMENT_THUNDERBOLT_2' + | 'ENCHANTMENT_ICE_COLD_1' + | 'ENCHANTMENT_THUNDERBOLT_3' + | 'ENCHANTMENT_ULTIMATE_REITERATE_1' + | 'ENCHANTMENT_ULTIMATE_REITERATE_4' + | 'ENCHANTMENT_COMPACT_10' + | 'ENCHANTMENT_ULTIMATE_REITERATE_5' + | 'ENCHANTMENT_ULTIMATE_REITERATE_2' + | 'PRISMARINE_SHARD' + | 'ENCHANTMENT_ULTIMATE_REITERATE_3' + | 'PRECURSOR_APPARATUS' + | 'SYNTHETIC_HEART' + | 'ENCHANTED_CLAY_BLOCK' + | 'POWER_CRYSTAL' + | 'WISE_FRAGMENT' + | 'SHARK_FIN' + | 'PERFECT_PERIDOT_GEM' + | 'SCUTTLER_SHELL' + | 'REFINED_MITHRIL' + | 'XXLARGE_ENCHANTED_CHEST' + | 'FUEL_TANK' + | 'UMBER_PLATE' + | 'SINGED_POWDER' + | 'JALAPENO_BOOK' + | 'ENCHANTMENT_VENOMOUS_3' + | 'POTATO_ITEM' + | 'ENCHANTMENT_VENOMOUS_4' + | 'ENCHANTMENT_VENOMOUS_5' + | 'ENCHANTED_HUGE_MUSHROOM_1' + | 'SKYMART_BROCHURE' + | 'ENCHANTMENT_VENOMOUS_6' + | 'PRESUMED_GALLON_OF_RED_PAINT' + | 'HEMOGLASS' + | 'ENCHANTMENT_VENOMOUS_1' + | 'ENCHANTMENT_VENOMOUS_2' + | 'ELECTRON_TRANSMITTER' + | 'ENCHANTED_COBBLESTONE' + | 'ENCHANTMENT_STRONG_MANA_10' + | 'ENCHANTED_HUGE_MUSHROOM_2' + | 'MOOGMA_PELT' + | 'GLOWY_CHUM_BAIT' + | 'GAZING_PEARL' + | 'STUFFED_CHILI_PEPPER' + | 'BUDGET_HOPPER' + | 'REKINDLED_EMBER_FRAGMENT' + | 'ICE_BAIT' + | 'TERRY_SNOWGLOBE' + | 'FINE_ONYX_GEM' + | 'CHEESE_FUEL' + | 'KUUDRA_MANDIBLE' + | 'ENCHANTMENT_FEATHER_FALLING_3' + | 'ENCHANTMENT_FEATHER_FALLING_2' + | 'PUMPKIN_GUTS' + | 'ENCHANTMENT_FEATHER_FALLING_1' + | 'ENCHANTMENT_FEATHER_FALLING_7' + | 'BLAZE_ROD_DISTILLATE' + | 'ENCHANTMENT_FEATHER_FALLING_6' + | 'WITHER_SHIELD_SCROLL' + | 'ENCHANTMENT_FEATHER_FALLING_5' + | 'ENCHANTMENT_FEATHER_FALLING_4' + | 'ACACIA_BIRDHOUSE' + | 'ENCHANTMENT_FEATHER_FALLING_9' + | 'ENCHANTMENT_FEATHER_FALLING_8' + | 'SPIDER_CATALYST' + | 'ENCHANTED_ENDSTONE' + | 'ENCHANTED_LAPIS_LAZULI_BLOCK' + | 'ENCHANTED_SAND' + | 'ESSENCE_ICE' + | 'COLOSSAL_EXP_BOTTLE' + | 'ENCHANTED_STRING' + | 'PERFECT_ONYX_GEM' + | 'MOIL_LOG' + | 'ENCHANTED_DANDELION' + | 'MIMIC_FRAGMENT' + | 'MAGMA_FISH_GOLD' + | 'SOUL_FRAGMENT' + | 'ENCHANTED_LAPIS_LAZULI' + | 'ENDERMAN_CORTEX_REWRITER' + | 'MELON_BLOCK' + | 'CRUDE_GABAGOOL_DISTILLATE' + | 'SEEDS' + | 'ENCHANTED_LEATHER' + | 'ENCHANTED_SPONGE' + | 'WOLF_TOOTH' + | 'ENCHANTED_NETHER_STALK' + | 'ENCHANTMENT_CURSE_OF_VANISHING_0' + | 'ENCHANTED_REDSTONE' + | 'METEOR_SHARD' + | 'ENCHANTMENT_COMPACT_2' + | 'ENCHANTMENT_COMPACT_3' + | 'DWARVEN_COMPACTOR' + | 'ENCHANTMENT_COMPACT_1' + | 'GREAT_WHITE_SHARK_TOOTH' + | 'ESSENCE_GOLD' + | 'LEATHER_CLOTH' + | 'ENCHANTMENT_PRISTINE_1' + | 'ENCHANTMENT_COMPACT_6' + | 'ENCHANTMENT_BLAST_PROTECTION_4' + | 'ENCHANTMENT_PRISTINE_2' + | 'ENCHANTMENT_COMPACT_7' + | 'ENCHANTMENT_BLAST_PROTECTION_3' + | 'RECOMBOBULATOR_3000' + | 'ENCHANTMENT_BLAST_PROTECTION_6' + | 'ENCHANTMENT_COMPACT_4' + | 'ENCHANTMENT_BLAST_PROTECTION_5' + | 'ENCHANTMENT_COMPACT_5' + | 'ENCHANTMENT_PRISTINE_5' + | 'ENCHANTMENT_PRISTINE_3' + | 'ENCHANTMENT_COMPACT_8' + | 'ENCHANTMENT_BLAST_PROTECTION_2' + | 'ENCHANTED_WHEAT' + | 'ENCHANTMENT_PRISTINE_4' + | 'ENCHANTMENT_COMPACT_9' + | 'ENCHANTMENT_BLAST_PROTECTION_1' + | 'ENCHANTMENT_FEROCIOUS_MANA_10' + | 'ENCHANTED_PORK' + | 'NECROMANCER_BROOCH' + | 'PET_ITEM_LUCKY_CLOVER_DROP' + | 'BURROWING_SPORES' + | 'DEEP_SEA_ORB' + | 'ROUGH_JASPER_GEM' + | 'FEATHER' + | 'PETRIFIED_STARFALL' + | 'MAGIC_TOP_HAT' + | 'ENCHANTED_RED_SAND' + | 'ENCHANTED_CLOWNFISH' + | 'REFINED_UMBER' + | 'PITCHIN_KOI' + | 'ENCHANTED_GOLD' + | 'ENCHANTMENT_LIFE_STEAL_1' + | 'ENCHANTMENT_LIFE_STEAL_2' + | 'ENCHANTMENT_SMELTING_TOUCH_1' + | 'ENCHANTMENT_LIFE_STEAL_5' + | 'ROUGH_CITRINE_GEM' + | 'ENCHANTMENT_LIFE_STEAL_3' + | 'ENCHANTMENT_LIFE_STEAL_4' + | 'ENCHANTMENT_PISCARY_1' + | 'GOLDEN_PLATE' + | 'ENCHANTMENT_TURBO_MUSHROOMS_5' + | 'SADAN_BROOCH' + | 'FIFTH_MASTER_STAR' + | 'ENCHANTMENT_PISCARY_3' + | 'ENCHANTMENT_PISCARY_2' + | 'BLUE_ICE_HUNK' + | 'ENCHANTED_GLOWSTONE_DUST' + | 'ENCHANTMENT_PISCARY_5' + | 'ENCHANTMENT_PISCARY_4' + | 'ENCHANTMENT_PISCARY_6' + | 'ENCHANTMENT_TABASCO_1' + | 'ENCHANTMENT_TABASCO_3' + | 'ENCHANTMENT_PUNCH_1' + | 'ENCHANTED_SUGAR_CANE' + | 'ENCHANTMENT_TABASCO_2' + | 'TRANSMISSION_TUNER' + | 'ENCHANTMENT_PUNCH_2' + | 'ENCHANTMENT_TURBO_MUSHROOMS_2' + | 'BUSTED_BELT_BUCKLE' + | 'ENCHANTMENT_TURBO_MUSHROOMS_1' + | 'ENCHANTMENT_TURBO_MUSHROOMS_4' + | 'CONCENTRATED_STONE' + | 'ENCHANTMENT_TURBO_MUSHROOMS_3' + | 'ENCHANTMENT_MANA_VAMPIRE_2' + | 'ENCHANTMENT_MANA_VAMPIRE_1' + | 'ENCHANTMENT_MANA_VAMPIRE_4' + | 'ENCHANTMENT_MANA_VAMPIRE_3' + | 'ENCHANTMENT_MANA_VAMPIRE_6' + | 'ENCHANTMENT_MANA_VAMPIRE_5' + | 'SHARK_WATER_ORB' + | 'ENCHANTMENT_MANA_VAMPIRE_8' + | 'ENCHANTMENT_MANA_VAMPIRE_7' + | 'GHAST_TEAR' + | 'ENCHANTMENT_MANA_VAMPIRE_9' + | 'UNSTABLE_FRAGMENT' + | 'KUUDRA_TEETH' + | 'MAGMA_CREAM_DISTILLATE' + | 'CORLEONITE' + | 'ENCHANTED_EMERALD_BLOCK' + | 'SUBZERO_INVERTER' + | 'GIANT_TOOTH' + | 'ENCHANTMENT_PIERCING_1' + | 'ENCHANTMENT_ULTIMATE_THE_ONE_5' + | 'ENCHANTED_MUTTON' + | 'ENCHANTMENT_TITAN_KILLER_7' + | 'SLEEPY_HOLLOW' + | 'ENCHANTMENT_TITAN_KILLER_6' + | 'NULL_SPHERE' + | 'ENCHANTMENT_TITAN_KILLER_5' + | 'ENCHANTMENT_TITAN_KILLER_4' + | 'ENCHANTMENT_TITAN_KILLER_3' + | 'ENCHANTMENT_TITAN_KILLER_2' + | 'ENCHANTMENT_TITAN_KILLER_1' + | 'STOCK_OF_STONKS' + | 'BRONZE_BOWL' + | 'SUPERIOR_FRAGMENT' + | 'MAGMA_BUCKET' + | 'ENCHANTMENT_ULTIMATE_THE_ONE_4' + | 'ALLIGATOR_SKIN' + | 'ENCHANTMENT_POWER_1' + | 'HOT_BAIT' + | 'NULL_BLADE' + | 'WITHER_SOUL' + | 'ENCHANTMENT_POWER_7' + | 'ENCHANTMENT_POWER_6' + | 'ENCHANTMENT_ANGLER_1' + | 'ENCHANTMENT_ANGLER_2' + | 'WORM_MEMBRANE' + | 'GLACITE_SHARD' + | 'ENCHANTMENT_ANGLER_3' + | 'ENCHANTMENT_POWER_3' + | 'ENCHANTMENT_ANGLER_4' + | 'BLACK_WOOLEN_YARN' + | 'ENCHANTMENT_ANGLER_5' + | 'ENCHANTMENT_POWER_2' + | 'ENCHANTMENT_ANGLER_6' + | 'ENCHANTMENT_POWER_5' + | 'ENCHANTMENT_POWER_4' + | 'WATER_LILY' + | 'ENCHANTMENT_THORNS_3' + | 'BOB_OMB' + | 'LOG_2' + | 'MITHRIL_INFUSION' + | 'COAL' + | 'ENCHANTMENT_ULTIMATE_BOBBIN_TIME_3' + | 'ENCHANTMENT_ULTIMATE_BOBBIN_TIME_4' + | 'ENCHANTMENT_ULTIMATE_BOBBIN_TIME_5' + | 'ENCHANTMENT_THORNS_1' + | 'GOLDEN_BOUNTY' + | 'ENCHANTMENT_THORNS_2' + | 'ENCHANTMENT_VAMPIRISM_5' + | 'GOBLIN_EGG' + | 'ENCHANTMENT_VAMPIRISM_6' + | 'ENCHANTED_PRISMARINE_CRYSTALS' + | 'PERFECT_TOPAZ_GEM' + | 'LIVID_FRAGMENT' + | 'ENCHANTMENT_VAMPIRISM_3' + | 'PLASMA' + | 'ENCHANTMENT_VAMPIRISM_4' + | 'ENCHANTED_WET_SPONGE' + | 'ENCHANTMENT_CULTIVATING_9' + | 'ENCHANTMENT_EXPERTISE_7' + | 'ENCHANTMENT_EXPERTISE_6' + | 'ENCHANTMENT_EXPERTISE_9' + | 'ENCHANTMENT_CULTIVATING_7' + | 'ENCHANTMENT_EXPERTISE_8' + | 'ENCHANTMENT_CULTIVATING_8' + | 'ENCHANTMENT_CULTIVATING_5' + | 'PERFECT_PLATE' + | 'ESSENCE_CRIMSON' + | 'ENDER_STONE' + | 'ENCHANTMENT_CULTIVATING_6' + | 'GOLDEN_BAIT' + | 'ENCHANTMENT_CULTIVATING_3' + | 'ENCHANTMENT_CULTIVATING_4' + | 'ENCHANTMENT_CULTIVATING_1' + | 'ENCHANTMENT_VAMPIRISM_1' + | 'ENCHANTMENT_VAMPIRISM_2' + | 'ENCHANTMENT_CULTIVATING_2' + | 'QUARTZ' + | 'JERRY_BOX_PURPLE' + | 'SALMON_OPAL' + | 'ENCHANTMENT_ULTIMATE_SOUL_EATER_1' + | 'CHUM' + | 'ENCHANTMENT_ULTIMATE_SOUL_EATER_3' + | 'HALLOWED_SKULL' + | 'ENCHANTMENT_ULTIMATE_SOUL_EATER_2' + | 'ENCHANTMENT_ULTIMATE_SOUL_EATER_5' + | 'ENCHANTMENT_ULTIMATE_SOUL_EATER_4' + | 'MAGMA_CREAM' + | 'ENCHANTED_COMPOST' + | 'ENCHANTMENT_CHANCE_2' + | 'RED_GIFT' + | 'ENCHANTED_MITHRIL' + | 'ENCHANTMENT_CHANCE_1' + | 'ROUGH_PERIDOT_GEM' + | 'ENCHANTMENT_CHANCE_5' + | 'FEL_PEARL' + | 'ENCHANTED_FEATHER' + | 'ENCHANTMENT_CHANCE_4' + | 'ENCHANTED_OAK_LOG' + | 'ENCHANTMENT_CHANCE_3' + | 'ENCHANTMENT_GREEN_THUMB_5' + | 'ENCHANTMENT_KNOCKBACK_2' + | 'WHITE_GIFT' + | 'FLAWLESS_AQUAMARINE_GEM' + | 'ENCHANTMENT_KNOCKBACK_1' + | 'ENCHANTMENT_GREEN_THUMB_1' + | 'ENCHANTMENT_ULTIMATE_FLASH_2' + | 'ENCHANTMENT_ULTIMATE_FLASH_1' + | 'ENCHANTMENT_GREEN_THUMB_2' + | 'NETHER_STALK' + | 'ENCHANTMENT_GREEN_THUMB_3' + | 'ENCHANTMENT_ULTIMATE_FLASH_4' + | 'ENCHANTMENT_GREEN_THUMB_4' + | 'ENCHANTMENT_ULTIMATE_FLASH_3' + | 'ENCHANTMENT_FIRST_STRIKE_1' + | 'HORSEMAN_CANDLE' + | 'ENCHANTMENT_FIRST_STRIKE_5' + | 'RED_ROSE' + | 'ENCHANTMENT_ULTIMATE_FLASH_5' + | 'ENCHANTMENT_FIRST_STRIKE_4' + | 'ENCHANTMENT_FIRST_STRIKE_3' + | 'ENCHANTMENT_FIRST_STRIKE_2' + | 'GOLDEN_BALL' + | 'BURNING_EYE' + | 'WRIGGLING_LARVA' + | 'ENCHANTMENT_TURBO_PUMPKIN_1' + | 'ENCHANTMENT_TURBO_PUMPKIN_2' + | 'ENCHANTMENT_TURBO_PUMPKIN_3' + | 'ENCHANTMENT_TURBO_PUMPKIN_4' + | 'ENCHANTMENT_TURBO_PUMPKIN_5' + | 'EMPTY_CHUM_BUCKET' + | 'HOTSPOT_BAIT' + | 'LEATHER' + | 'GIANT_FRAGMENT_BOULDER' + | 'MAGMA_FISH' + | 'LAVA_SHELL' + | 'SOUL_STRING' + | 'ENCHANTMENT_EXPERTISE_3' + | 'ENCHANTMENT_EXPERTISE_2' + | 'ENCHANTMENT_EXPERTISE_5' + | 'ENCHANTMENT_EXPERTISE_4' + | 'ENCHANTED_BREAD' + | 'ENCHANTMENT_EXPERTISE_1' + | 'FUMING_POTATO_BOOK' + | 'ENCHANTMENT_ULTIMATE_FATAL_TEMPO_5' + | 'ENCHANTMENT_ULTIMATE_FATAL_TEMPO_3' + | 'ENCHANTMENT_DEPTH_STRIDER_2' + | 'ENCHANTMENT_BLESSING_2' + | 'SULPHUR_ORE' + | 'FLAWED_SAPPHIRE_GEM' + | 'ENCHANTMENT_ULTIMATE_FATAL_TEMPO_4' + | 'ENCHANTMENT_DEPTH_STRIDER_3' + | 'ENCHANTMENT_BLESSING_3' + | 'ENCHANTMENT_ULTIMATE_FATAL_TEMPO_1' + | 'ENCHANTMENT_ULTIMATE_FATAL_TEMPO_2' + | 'ENCHANTMENT_BLESSING_1' + | 'ENCHANTMENT_BLESSING_6' + | 'PERFECT_SAPPHIRE_GEM' + | 'ENCHANTMENT_BLESSING_4' + | 'SNOW_BLOCK' + | 'ENCHANTMENT_BLESSING_5' + | 'ENCHANTED_BAKED_POTATO' + | 'AGARIMOO_TONGUE' + | 'COMPACTOR' + | 'FROZEN_BAUBLE' + | 'MANDRAA' + | 'PYROCLASTIC_SCALE' + | 'ENCHANTMENT_DEPTH_STRIDER_1' + | 'SPOOKY_SHARD' + | 'ENCHANTMENT_CHAMPION_1' + | 'ENCHANTMENT_CHAMPION_3' + | 'SEVERED_PINCER' + | 'ENCHANTMENT_CHAMPION_2' + | 'ENCHANTMENT_CHAMPION_5' + | 'ENCHANTED_LUSH_BERBERIS' + | 'ENCHANTED_POTATO' + | 'ENCHANTMENT_CHAMPION_4' + | 'RADIOACTIVE_VIAL' + | 'ENCHANTMENT_CHAMPION_7' + | 'ENCHANTED_SLIME_BALL' + | 'ENCHANTMENT_CHAMPION_6' + | 'ENCHANTMENT_CHAMPION_9' + | 'ENCHANTMENT_CHAMPION_8' + | 'BULKY_STONE' + | 'ENCHANTMENT_SNIPE_3' + | 'ENCHANTED_RED_MUSHROOM' + | 'ENCHANTMENT_SNIPE_2' + | 'ENCHANTMENT_SNIPE_1' + | 'ENCHANTMENT_RESPIRATION_3' + | 'ENCHANTMENT_ULTIMATE_ONE_FOR_ALL_0' + | 'ENCHANTMENT_ULTIMATE_ONE_FOR_ALL_1' + | 'ENCHANTMENT_SNIPE_4' + | 'TUNGSTEN_KEY' + | 'FINE_CITRINE_GEM' + | 'GREAT_WHITE_TOOTH_MEAL' + | 'ENCHANTMENT_RESPIRATION_1' + | 'ENCHANTMENT_RESPIRATION_2' + | 'BOOKWORM_BOOK' + | 'CALCIFIED_HEART' + | 'FULL_JAW_FANGING_KIT' + | 'ENCHANTED_CAKE' + | 'PUMPKIN' + | 'WHEAT' + | 'NURSE_SHARK_TOOTH' + | 'ENCHANTMENT_REFLECTION_5' + | 'ENCHANTMENT_REFLECTION_4' + | 'TENTACLE_MEAT' + | 'ENCHANTMENT_ULTIMATE_BANK_5' + | 'SCORCHED_CRAB_STICK' + | 'ENCHANTMENT_ULTIMATE_LEGION_1' + | 'ENCHANTMENT_ULTIMATE_BANK_2' + | 'ENCHANTMENT_ULTIMATE_BANK_1' + | 'ENCHANTMENT_ULTIMATE_LEGION_2' + | 'ENCHANTED_SPIDER_EYE' + | 'ENCHANTMENT_ULTIMATE_BANK_4' + | 'ENCHANTMENT_ULTIMATE_BANK_3' + | 'ENCHANTMENT_ULTIMATE_LEGION_5' + | 'ENCHANTMENT_REFLECTION_1' + | 'ENCHANTMENT_REFLECTION_3' + | 'ENCHANTMENT_ULTIMATE_LEGION_3' + | 'ENCHANTMENT_REFLECTION_2' + | 'ENCHANTMENT_ULTIMATE_LEGION_4' + | 'RAW_SOULFLOW' + | 'ENCHANTMENT_TRIPLE_STRIKE_1' + | 'ENCHANTMENT_TRIPLE_STRIKE_3' + | 'ENCHANTMENT_TRIPLE_STRIKE_2' + | 'ENCHANTMENT_PROSPERITY_1' + | 'RAW_FISH' + | 'ENCHANTMENT_PROSPERITY_3' + | 'YOGGIE' + | 'ENCHANTMENT_PROSPERITY_2' + | 'PERFECT_JASPER_GEM' + | 'ICE_HUNK' + | 'ENCHANTMENT_PROSPERITY_5' + | 'ENCHANTMENT_HECATOMB_10' + | 'ENCHANTMENT_PROSPERITY_4' + | 'OCTOPUS_TENDRIL' + | 'CONTROL_SWITCH' + | 'ENCHANTMENT_COUNTER_STRIKE_3' + | 'DIAMOND_SPREADING' + | 'ENCHANTMENT_COUNTER_STRIKE_4' + | 'ENCHANTMENT_COUNTER_STRIKE_5' + | 'TIGHTLY_TIED_HAY_BALE' + | 'NETHER_STALK_DISTILLATE' + | 'DIVER_FRAGMENT' + | 'DARK_CANDY' + | 'ENCHANTMENT_WITHER_HUNTER_0' + | 'ENCHANTMENT_SPIKED_HOOK_5' + | 'KADA_LEAD' + | 'ENCHANTMENT_SPIKED_HOOK_6' + | 'ENCHANTMENT_SPIKED_HOOK_3' + | 'ENCHANTMENT_SPIKED_HOOK_4' + | 'ENCHANTMENT_ULTIMATE_FLOWSTATE_1' + | 'ESSENCE_DIAMOND' + | 'ENCHANTMENT_LETHALITY_1' + | 'ENCHANTMENT_LETHALITY_2' + | 'ENCHANTMENT_LETHALITY_3' + | 'ENCHANTMENT_LETHALITY_4' + | 'ENCHANTMENT_LETHALITY_5' + | 'ENCHANTMENT_LETHALITY_6' + | 'GLACITE' + | 'PLANT_MATTER' + | 'ENCHANTMENT_CLEAVE_2' + | 'BLOOD_STAINED_COINS' + | 'ENCHANTMENT_CLEAVE_1' + | 'HUGE_MUSHROOM_1' + | 'ENCHANTMENT_REJUVENATE_1' + | 'ENCHANTMENT_CLEAVE_4' + | 'HUGE_MUSHROOM_2' + | 'ENCHANTMENT_CLEAVE_3' + | 'ENCHANTMENT_CLEAVE_6' + | 'ENCHANTMENT_CLEAVE_5' + | 'ENCHANTMENT_REJUVENATE_5' + | 'ENCHANTMENT_VICIOUS_3' + | 'ENCHANTMENT_REJUVENATE_4' + | 'ENCHANTMENT_VICIOUS_4' + | 'ENCHANTMENT_REJUVENATE_3' + | 'ENCHANTMENT_VICIOUS_5' + | 'ENCHANTMENT_REJUVENATE_2' + | 'STRING' + | 'ENCHANTMENT_ULTIMATE_FLOWSTATE_3' + | 'CRUDE_GABAGOOL' + | 'ENCHANTMENT_ULTIMATE_FLOWSTATE_2' + | 'DRAGON_SCALE' + | 'ENCHANTMENT_SPIKED_HOOK_1' + | 'ENCHANTMENT_SPIKED_HOOK_2' + | 'BAYOU_WATER_ORB' + | 'ENCHANTED_CACTUS_GREEN' + | 'FRIGID_HUSK' + | 'POISON_SAMPLE' + | 'BOOSTER_COOKIE' + | 'ENCHANTED_COOKIE' + | 'AMALGAMATED_CRIMSONITE_NEW' + | 'BLAZE_ASHES' + | 'STRONG_FRAGMENT' + | 'MYCEL' + | 'AUTO_SMELTER' + | 'WOOL' + | 'ENCHANTMENT_TURBO_CARROT_2' + | 'ENCHANTMENT_TURBO_CARROT_1' + | 'SPELL_POWDER' + | 'ENCHANTMENT_ULTIMATE_REFRIGERATE_5' + | 'ENCHANTMENT_GIANT_KILLER_4' + | 'WHIPPED_MAGMA_CREAM' + | 'ENCHANTMENT_GIANT_KILLER_5' + | 'ENCHANTMENT_GIANT_KILLER_2' + | 'DRAGON_HORN' + | 'PERFECT_AMBER_GEM' + | 'ENCHANTMENT_GIANT_KILLER_3' + | 'ENCHANTMENT_GIANT_KILLER_6' + | 'FLINT' + | 'ENCHANTMENT_GIANT_KILLER_7' + | 'MAGMA_CORE' + | 'ENCHANTMENT_TRIPLE_STRIKE_5' + | 'DWARVEN_TREASURE' + | 'ENCHANTED_SPRUCE_LOG' + | 'HARDENED_WOOD' + | 'TUNGSTEN' + | 'ENCHANTMENT_TRIPLE_STRIKE_4' + | 'ENCHANTMENT_ULTIMATE_INFERNO_1' + | 'LUMINO_FIBER' + | 'ENCHANTMENT_ULTIMATE_REFRIGERATE_1' + | 'ENCHANTMENT_ULTIMATE_INFERNO_3' + | 'ENCHANTED_QUARTZ_BLOCK' + | 'ENCHANTMENT_ULTIMATE_INFERNO_2' + | 'ENCHANTMENT_ULTIMATE_REFRIGERATE_2' + | 'HEAVY_GABAGOOL' + | 'ENCHANTMENT_ULTIMATE_REFRIGERATE_3' + | 'ENCHANTMENT_ULTIMATE_INFERNO_5' + | 'ENCHANTMENT_ULTIMATE_INFERNO_4' + | 'MIXED_MITE_GEL' + | 'ENCHANTMENT_ULTIMATE_REFRIGERATE_4' + | 'GREEN_CANDY' + | 'ECCENTRIC_PAINTING' + | 'REAPER_PEPPER' + | 'ENCHANTMENT_AQUA_AFFINITY_1' + | 'GRAVEL' + | 'ENCHANTED_PACKED_ICE' + | 'HOTSPOT_WATER_ORB' + | 'FLAMING_HEART' + | 'ENCHANTED_PRISMARINE_SHARD' + | 'SPIRIT_DECOY' + | 'ENCHANTMENT_TURBO_CARROT_4' + | 'HYPERGOLIC_GABAGOOL' + | 'ENCHANTMENT_TURBO_CARROT_3' + | 'ENCHANTED_CARROT_STICK' + | 'ENCHANTMENT_TURBO_CARROT_5' + | 'TORN_CLOTH' + | 'ENCHANTMENT_TURBO_CANE_4' + | 'DRILL_ENGINE' + | 'ENCHANTMENT_TURBO_CANE_3' + | 'ENCHANTMENT_TURBO_CANE_2' + | 'ENCHANTMENT_TURBO_CANE_1' + | 'ENCHANTMENT_TURBO_CANE_5' + | 'PERFECT_CITRINE_GEM' + | 'BOX_OF_SEEDS' + | 'THIRD_MASTER_STAR' + | 'XLARGE_ENCHANTED_CHEST' + | 'VITAMIN_DEATH' + | 'PET_ITEM_TIER_BOOST_DROP' + | 'NETHERRACK' + | 'COMPOST' + | 'DARK_QUEENS_SOUL_DROP' + | 'FERMENTO' + | 'MIDAS_JEWEL' + | 'CANDY_CORN' + | 'ASCENSION_ROPE' + | 'PREMIUM_FLESH' + | 'BLUE_RING' + | 'SQUASH' + | 'ROUGH_AMETHYST_GEM' + | 'FLAWLESS_RUBY_GEM' + | 'NULL_ATOM' + | 'BLESSED_BAIT' + | 'PURE_MITHRIL' + | 'ROCK_CANDY' + | 'GLACITE_AMALGAMATION' + | 'ENCHANTMENT_FORTUNE_1' + | 'ENCHANTMENT_FORTUNE_2' + | 'LOG' + | 'ENCHANTMENT_FORTUNE_3' + | 'ENCHANTMENT_FORTUNE_4' + | 'SEARING_STONE' + | 'ENCHANTMENT_FLAME_2' + | 'ENCHANTMENT_FLAME_1' + | 'ROUGH_JADE_GEM' + | 'ENCHANTED_JUNGLE_LOG' + | 'WOOD_SINGULARITY' + | 'IRON_INGOT' + | 'CAN_OF_WORMS' + | 'GEMSTONE_MIXTURE' + | 'ENCHANTMENT_DIVINE_GIFT_3' + | 'ENCHANTMENT_DIVINE_GIFT_2' + | 'ENCHANTMENT_DIVINE_GIFT_1' + | 'SPIRIT_BONE' + | 'ROUGH_SAPPHIRE_GEM' + | 'FRIED_FEATHER' + | 'REVENANT_VISCERA' + | 'MITE_GEL' + | 'ENCHANTMENT_GIANT_KILLER_1' + | 'TARANTULA_SILK' + | 'TITANIC_EXP_BOTTLE' + | 'ENCHANTMENT_FRAIL_2' + | 'ENCHANTMENT_FRAIL_1' + | 'ENCHANTMENT_FRAIL_4' + | 'SUPER_EGG' + | 'SUPER_COMPACTOR_3000' + | 'ENCHANTMENT_FRAIL_3' + | 'ENCHANTMENT_FRAIL_6' + | 'ENCHANTMENT_FRAIL_5' + | 'MITHRIL_ORE' + | 'ENCHANTED_PAPER' + | 'HOT_STUFF' + | 'FLAWED_AQUAMARINE_GEM' + | 'WORM_BAIT' + | 'HIGHLITE' + | 'SUSPICIOUS_VIAL' + | 'DIRT_BOTTLE' + | 'ENCHANTMENT_TIDAL_3' + | 'ENCHANTMENT_TIDAL_2' + | 'ENCHANTMENT_TIDAL_1' + | 'ARACHNE_FANG' + | 'ROUGH_TOPAZ_GEM' + | 'ENCHANTED_OBSIDIAN' + | 'ROUGH_OPAL_GEM' + | 'ENCHANTMENT_EFFICIENCY_10' + | 'WEREWOLF_SKIN' + | 'ENCHANTMENT_SYPHON_3' + | 'ENCHANTMENT_SYPHON_2' + | 'ENCHANTMENT_SYPHON_5' + | 'ENCHANTMENT_SYPHON_4' + | 'ENCHANTED_RED_SAND_CUBE' + | 'ENCHANTED_RAW_FISH' + | 'BERBERIS_FUEL_INJECTOR' + | 'ENCHANTMENT_EXECUTE_6' + | 'ENCHANTMENT_INFINITE_QUIVER_10' + | 'ENCHANTMENT_EXECUTE_3' + | 'MAGMA_CHUNK' + | 'ENCHANTMENT_EXECUTE_2' + | 'ENCHANTMENT_EXECUTE_5' + | 'ENCHANTMENT_SYPHON_1' + | 'ENCHANTMENT_EXECUTE_4' + | 'ENCHANTMENT_LOOTING_4' + | 'ENCHANTMENT_SMITE_7' + | 'ENCHANTMENT_SCAVENGER_3' + | 'ENCHANTMENT_SCAVENGER_4' + | 'ENCHANTMENT_LOOTING_3' + | 'ENCHANTMENT_SCAVENGER_1' + | 'ENCHANTMENT_LOOTING_2' + | 'ENCHANTMENT_EXECUTE_1' + | 'FUEL_GABAGOOL' + | 'ENCHANTMENT_SCAVENGER_2' + | 'ENCHANTMENT_LOOTING_1' + | 'ENCHANTMENT_CUBISM_2' + | 'ENCHANTMENT_CUBISM_3' + | 'ENCHANTMENT_SCAVENGER_5' + | 'ENCHANTMENT_CUBISM_1' + | 'SHARK_BAIT' + | 'ENCHANTMENT_LOOTING_5' + | 'JUNGLE_KEY' + | 'FLAWED_CITRINE_GEM' + | 'JERRY_BOX_BLUE' + | 'ENCHANTED_SLIME_BLOCK' + | 'ENCHANTMENT_CUBISM_6' + | 'SCORCHED_BOOKS' + | 'SULPHUR' + | 'FINE_SAPPHIRE_GEM' + | 'ENCHANTMENT_CUBISM_4' + | 'ENCHANTMENT_SMITE_1' + | 'ENCHANTMENT_CUBISM_5' + | 'ENCHANTMENT_SMITE_2' + | 'GOLDEN_POWDER' + | 'ENCHANTMENT_EXPERTISE_10' + | 'ENCHANTMENT_SMITE_3' + | 'ENCHANTMENT_SMITE_4' + | 'ENCHANTED_CARROT' + | 'ENCHANTMENT_SMITE_5' + | 'ENCHANTMENT_SMITE_6' + | 'FINE_AQUAMARINE_GEM' + | 'ROTTEN_FLESH' + | 'FINE_PERIDOT_GEM' + | 'TREASURE_BAIT' + | 'ENCHANTMENT_HECATOMB_2' + | 'ENCHANTMENT_HECATOMB_3' + | 'ENCHANTMENT_HECATOMB_1' + | 'ENCHANTMENT_HECATOMB_6' + | 'ENCHANTMENT_HECATOMB_7' + | 'ENCHANTMENT_HECATOMB_4' + | 'DUNGEON_CHEST_KEY' + | 'ENCHANTMENT_HECATOMB_5' + | 'ENCHANTMENT_HECATOMB_8' + | 'ENCHANTMENT_HECATOMB_9' + | 'GOLDEN_FRAGMENT' + | 'INFLATABLE_JERRY' + | 'FLAWED_TOPAZ_GEM' + | 'ENCHANTMENT_SUNDER_1' + | 'LAPIS_CRYSTAL' + | 'FINE_AMETHYST_GEM' + | 'ENCHANTMENT_TRANSYLVANIAN_5' + | 'SAND:1' + | 'ENCHANTED_RABBIT' + | 'SUPREME_CHOCOLATE_BAR' + | 'MEDIUM_ENCHANTED_CHEST' + | 'TOXIC_ARROW_POISON' + | 'ENCHANTMENT_TRANSYLVANIAN_4' + | 'ENCHANTMENT_SUNDER_4' + | 'ENCHANTMENT_SUNDER_5' + | 'ENCHANTMENT_SUNDER_2' + | 'MUTANT_NETHER_STALK' + | 'ENCHANTMENT_SUNDER_3' + | 'ENCHANTMENT_LUCK_6' + | 'ENCHANTMENT_LUCK_7' + | 'ENCHANTMENT_SUNDER_6' + | 'ENCHANTMENT_LUCK_2' + | 'FLAWLESS_AMBER_GEM' + | 'REFINED_BOTTLE_OF_JYRRE' + | 'ENCHANTMENT_LUCK_3' + | 'ENCHANTED_BLAZE_POWDER' + | 'ENCHANTMENT_LUCK_4' + | 'ENCHANTMENT_LUCK_5' + | 'ENCHANTED_SULPHUR_CUBE' + | 'SUMMONING_EYE' + | 'ENCHANTMENT_INFINITE_QUIVER_8' + | 'ENCHANTMENT_INFINITE_QUIVER_9' + | 'ENCHANTMENT_INFINITE_QUIVER_6' + | 'FISH_BAIT' + | 'ENCHANTMENT_INFINITE_QUIVER_7' + | 'ENCHANTMENT_LUCK_1' + | 'ENCHANTMENT_ULTIMATE_WISDOM_4' + | 'ENCHANTMENT_TURBO_POTATO_3' + | 'ENCHANTMENT_INFINITE_QUIVER_4' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_2' + | 'ENCHANTMENT_TURBO_POTATO_4' + | 'ENCHANTMENT_ULTIMATE_WISDOM_5' + | 'ENCHANTMENT_INFINITE_QUIVER_5' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_3' + | 'ENCHANTMENT_TURBO_POTATO_5' + | 'ENCHANTMENT_INFINITE_QUIVER_2' + | 'ENCHANTMENT_INFINITE_QUIVER_3' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_1' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_6' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_7' + | 'ENCHANTMENT_ULTIMATE_WISDOM_1' + | 'WINTER_WATER_ORB' + | 'ENCHANTMENT_INFINITE_QUIVER_1' + | 'ENCHANTMENT_TURBO_POTATO_1' + | 'ENCHANTMENT_ULTIMATE_WISDOM_2' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_4' + | 'ENCHANTMENT_TURBO_POTATO_2' + | 'ENCHANTMENT_ULTIMATE_WISDOM_3' + | 'ENCHANTMENT_BANE_OF_ARTHROPODS_5'; + +export type SkyBlockBingoGoalType = 'ONE_TIME' | 'ONE_TIER' | 'TIERED'; + +export type SkyBlockMayor = + | 'Aatrox' + | 'Cole' + | 'Diana' + | 'Diaz' + | 'Finnegan' + | 'Foxy' + | 'Marina' + | 'Paul' + | 'Jerry' + | 'Derpy' + | 'Scorpius'; + +export type SkyBlockCandidateKeyBenefit = + | 'slayer' + | 'mining' + | 'pets' + | 'economist' + | 'farming' + | 'fishing' + | 'dungeons'; + +export type BestiaryMob = { + name: string; + kills: number; + nextTierKills: number | null; + maxKills: number; + tier: number; + maxTier: number; +}; + +export type BestiaryCategory = { name: string; mobs: BestiaryMob[]; mobsUnlocked: number; mobsMaxed: number }; + +export type BestiaryStats = { + level: number; + maxLevel: number; + familiesUnlocked: number; + familiesCompleted: number; + totalFamilies: number; + familyTiers: number; + maxFamilyTiers: number; + categories: Record; +}; + +export interface RawBestiaryMob { + name: string; + cap: number; + mobs: string[]; + bracket: number; +} + +export interface RawBestiaryIsland { + name: string; + mobs: RawBestiaryMob[]; +} + +export interface BestiaryMobsData { + dynamic: RawBestiaryIsland; + hub: RawBestiaryIsland; + farming_1: RawBestiaryIsland; + combat_1: RawBestiaryIsland; + combat_3: RawBestiaryIsland; + crimson_isle: RawBestiaryIsland; + mining_2: RawBestiaryIsland; + mining_3: RawBestiaryIsland; + crystal_hollows: RawBestiaryIsland; + foraging_1: RawBestiaryIsland; + foraging_2: RawBestiaryIsland; + spooky_festival: RawBestiaryIsland; + mythological_creatures: RawBestiaryIsland; + jerry: RawBestiaryIsland; + kuudra: RawBestiaryIsland; + fishing: RawBestiaryIsland; + lava: RawBestiaryIsland; + spooky_festival_fishing: RawBestiaryIsland; + fishing_festival: RawBestiaryIsland; + winter: RawBestiaryIsland; + backwater_bayou: RawBestiaryIsland; + catacombs: RawBestiaryIsland; + garden: RawBestiaryIsland; +} + +export interface SkyHelperNetWorthProfileCurrenciesEssenceEssence { + current: number; +} + +export interface SkyHelperNetWorthProfileCurrenciesEssence { + WITHER: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + DRAGON: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + SPIDER: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + UNDEAD: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + DIAMOND: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + GOLD: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + ICE: SkyHelperNetWorthProfileCurrenciesEssenceEssence; + CRIMSON: SkyHelperNetWorthProfileCurrenciesEssenceEssence; +} + +export interface SkyHelperNetWorthProfileCurrencies { + coin_purse: number; + essence: SkyHelperNetWorthProfileCurrenciesEssence; +} + +export interface SkyHelperNetWorthProfileProfile { + bank_account: number; +} + +export interface SkyHelperNetWorthProfileInventoryInventory { + data: string; +} + +export interface SkyHelperNetWorthProfileInventoryBackpack { + '0': SkyHelperNetWorthProfileInventoryInventory; + '1': SkyHelperNetWorthProfileInventoryInventory; + '2': SkyHelperNetWorthProfileInventoryInventory; + '3': SkyHelperNetWorthProfileInventoryInventory; + '4': SkyHelperNetWorthProfileInventoryInventory; + '5': SkyHelperNetWorthProfileInventoryInventory; + '6': SkyHelperNetWorthProfileInventoryInventory; + '7': SkyHelperNetWorthProfileInventoryInventory; + '8': SkyHelperNetWorthProfileInventoryInventory; + '9': SkyHelperNetWorthProfileInventoryInventory; + '10': SkyHelperNetWorthProfileInventoryInventory; + '11': SkyHelperNetWorthProfileInventoryInventory; + '12': SkyHelperNetWorthProfileInventoryInventory; + '13': SkyHelperNetWorthProfileInventoryInventory; + '14': SkyHelperNetWorthProfileInventoryInventory; + '15': SkyHelperNetWorthProfileInventoryInventory; + '16': SkyHelperNetWorthProfileInventoryInventory; + '17': SkyHelperNetWorthProfileInventoryInventory; +} + +export interface SkyHelperNetWorthProfileInventoryBagContents { + talisman_bag: SkyHelperNetWorthProfileInventoryInventory; + fishing_bag: SkyHelperNetWorthProfileInventoryInventory; + potion_bag: SkyHelperNetWorthProfileInventoryInventory; + sacks_bag: SkyHelperNetWorthProfileInventoryInventory; + quiver: SkyHelperNetWorthProfileInventoryInventory; +} + +export interface SkyHelperNetWorthProfileInventory { + inv_armor: SkyHelperNetWorthProfileInventoryInventory; + equipment_contents: SkyHelperNetWorthProfileInventoryInventory; + wardrobe_contents: SkyHelperNetWorthProfileInventoryInventory; + inv_contents: SkyHelperNetWorthProfileInventoryInventory; + ender_chest_contents: SkyHelperNetWorthProfileInventoryInventory; + personal_vault_contents: SkyHelperNetWorthProfileInventoryInventory; + backpack_contents: SkyHelperNetWorthProfileInventoryBackpack; + backpack_icons: SkyHelperNetWorthProfileInventoryBackpack; + bag_contents: SkyHelperNetWorthProfileInventoryBagContents; + sacks_counts: Record; +} + +export interface SkyHelperNetWorthProfileSharedInventory { + candy_inventory_contents: SkyHelperNetWorthProfileInventoryInventory; + carnival_mask_inventory_contents: SkyHelperNetWorthProfileInventoryInventory; +} + +export interface SkyHelperNetWorthProfilePetsDataPet { + type: SkyBlockPetId | 'UNKNOWN'; + tier: 'UNKNOWN' | Rarity; + exp: number; + heldItem: string | null; + skin: string | null; +} + +export interface SkyHelperNetWorthProfilePetsData { + pets: SkyHelperNetWorthProfilePetsDataPet[]; +} + +export interface SkyHelperNetWorthProfile { + currencies: SkyHelperNetWorthProfileCurrencies; + profile: SkyHelperNetWorthProfileProfile; + player_data: SkyBlockMemberPlayerData; + leveling: SkyBlockMemberLeveling; + inventory: SkyHelperNetWorthProfileInventory; + shared_inventory: SkyHelperNetWorthProfileSharedInventory; + pets_data: SkyHelperNetWorthProfilePetsData; + sacks_counts: Record; +} + +export type SkyblockProfileWithMe = SkyBlockProfile & { me: NonNullable }; diff --git a/src/Types/Static.ts b/src/Types/Static.ts new file mode 100644 index 000000000..3a7720677 --- /dev/null +++ b/src/Types/Static.ts @@ -0,0 +1,18 @@ +export type QuestObjectiveType = 'Integer' | 'Boolean'; +export type QuestType = 'Daily' | 'Weekly'; + +export interface QuestReward { + type: string; + amount: number; +} + +export interface ChallengeReward { + type: 'MultipliedExperienceReward'; + amount: number; +} + +export interface AchievementTier { + tier: number; + points?: number; + amount: number; +} diff --git a/src/Utils/Constants.ts b/src/Utils/Constants.ts new file mode 100644 index 000000000..4656b752f --- /dev/null +++ b/src/Utils/Constants.ts @@ -0,0 +1,2693 @@ +import type { BedWarsPrestige, BuildBattleTitle, DuelsBaseDivision } from '../Types/Player.js'; +import type { + BestiaryMobsData, + CustomPetLevelingData, + MiningForgeItemsData, + Rarity, + SkyBlockSlayer, + SkyBlockXPTables +} from '../Types/SkyBlock.js'; +import type { GameCode, GameID, GameString } from '../Types/Game.js'; + +export const games: { id: GameID; code: GameCode; name: GameString }[] = [ + { id: 2, code: 'QUAKECRAFT', name: 'Quake' }, + { id: 3, code: 'WALLS', name: 'Walls' }, + { id: 4, code: 'PAINTBALL', name: 'Paintball' }, + { id: 5, code: 'SURVIVAL_GAMES', name: 'Blitz Survival Games' }, + { id: 6, code: 'TNTGAMES', name: 'TNT Games' }, + { id: 7, code: 'VAMPIREZ', name: 'VampireZ' }, + { id: 13, code: 'WALLS3', name: 'Mega Walls' }, + { id: 14, code: 'ARCADE', name: 'Arcade' }, + { id: 17, code: 'ARENA', name: 'Arena' }, + { id: 20, code: 'UHC', name: 'UHC Champions' }, + { id: 21, code: 'MCGO', name: 'Cops and Crims' }, + { id: 23, code: 'BATTLEGROUND', name: 'Warlords' }, + { id: 24, code: 'SUPER_SMASH', name: 'Smash Heroes' }, + { id: 25, code: 'GINGERBREAD', name: 'Turbo Kart Racers' }, + { id: 26, code: 'HOUSING', name: 'Housing' }, + { id: 51, code: 'SKYWARS', name: 'SkyWars' }, + { id: 52, code: 'TRUE_COMBAT', name: 'Crazy Walls' }, + { id: 54, code: 'SPEED_UHC', name: 'Speed UHC' }, + { id: 55, code: 'SKYCLASH', name: 'SkyClash' }, + { id: 56, code: 'LEGACY', name: 'Classic Games' }, + { id: 57, code: 'PROTOTYPE', name: 'Prototype' }, + { id: 58, code: 'BEDWARS', name: 'Bed Wars' }, + { id: 59, code: 'MURDER_MYSTERY', name: 'Murder Mystery' }, + { id: 60, code: 'BUILD_BATTLE', name: 'Build Battle' }, + { id: 61, code: 'DUELS', name: 'Duels' }, + { id: 63, code: 'SKYBLOCK', name: 'SkyBlock' }, + { id: 64, code: 'PIT', name: 'Pit' }, + { id: 65, code: 'REPLAY', name: 'Replay' }, + { id: 67, code: 'SMP', name: 'SMP' }, + { id: 68, code: 'WOOL_GAMES', name: 'Wool Wars' } +]; + +export const duelsDivisions: { name: DuelsBaseDivision; key: string }[] = [ + { name: 'Rookie', key: 'rookie' }, + { name: 'Iron', key: 'iron' }, + { name: 'Gold', key: 'gold' }, + { name: 'Diamond', key: 'diamond' }, + { name: 'Master', key: 'master' }, + { name: 'Legend', key: 'legend' }, + { name: 'Grandmaster', key: 'grandmaster' }, + { name: 'Godlike', key: 'godlike' }, + { name: 'Celestial', key: 'celestial' }, + { name: 'Divine', key: 'divine' }, + { name: 'Ascended', key: 'ascended' } +]; + +export const MiniGamesString: { [key: string]: string } = { + QUAKECRAFT: 'Quakecraft', + WALLS: 'Walls', + PAINTBALL: 'Paintball', + SURVIVAL_GAMES: 'Blitz Survival Games', + TNTGAMES: 'The TNT Games', + VAMPIREZ: 'VampireZ', + WALLS3: 'Mega Walls', + ARCADE: 'Arcade', + ARENA: 'Arena Brawl', + MCGO: 'Cops and Crims', + UHC: 'UHC Champions', + BATTLEGROUND: 'Warlords', + SUPER_SMASH: 'Smash Heroes', + GINGERBREAD: 'Turbo Kart Racers', + HOUSING: 'Housing', + SKYWARS: 'SkyWars', + TRUE_COMBAT: 'Crazy Walls', + SPEED_UHC: 'Speed UHC', + SKYCLASH: 'SkyClash', + LEGACY: 'Classic Games', + PROTOTYPE: 'Prototype', + BEDWARS: 'BedWars', + MURDER_MYSTERY: 'Murder Mystery', + BUILD_BATTLE: 'Build Battle', + DUELS: 'Duels', + PIT: 'The Pit', + SKYBLOCK: 'SkyBlock', + REPLAY: 'Replay', + LIMBO: 'Limbo', + IDLE: 'Idle', + QUEUE: 'Queue', + MAIN_LOBBY: 'Main Lobby', + TOURNAMENT_LOBBY: 'Tournament Lobby', + WOOL_GAMES: 'Wool Wars' +}; + +// Credits (pit) https://github.com/PitPanda/PitPandaProduction/blob/b1971f56ea1aa8c829b722cbb33247c96591c0cb/structures/Pit.js +interface PitPrestigeData { + Multiplier: number; + TotalXp: number; + SumXp: number; + GoldReq: number; + Renown: number; +} +interface PitLevelData { + Xp: number; +} + +export const pit: { Prestiges: PitPrestigeData[]; Levels: PitLevelData[] } = { + Prestiges: [ + { Multiplier: 1, TotalXp: 65950, SumXp: 65950, GoldReq: 10000, Renown: 0 }, + { Multiplier: 1.1, TotalXp: 72560, SumXp: 138510, GoldReq: 20000, Renown: 10 }, + { Multiplier: 1.2, TotalXp: 79170, SumXp: 217680, GoldReq: 20000, Renown: 10 }, + { Multiplier: 1.3, TotalXp: 85750, SumXp: 303430, GoldReq: 20000, Renown: 10 }, + { Multiplier: 1.4, TotalXp: 92330, SumXp: 395760, GoldReq: 30000, Renown: 10 }, + { Multiplier: 1.5, TotalXp: 98940, SumXp: 494700, GoldReq: 35000, Renown: 10 }, + { Multiplier: 1.75, TotalXp: 115440, SumXp: 610140, GoldReq: 40000, Renown: 20 }, + { Multiplier: 2, TotalXp: 131900, SumXp: 742040, GoldReq: 45000, Renown: 20 }, + { Multiplier: 2.5, TotalXp: 164890, SumXp: 906930, GoldReq: 50000, Renown: 20 }, + { Multiplier: 3, TotalXp: 197850, SumXp: 1104780, GoldReq: 60000, Renown: 20 }, + { Multiplier: 4, TotalXp: 263800, SumXp: 1368580, GoldReq: 70000, Renown: 20 }, + { Multiplier: 5, TotalXp: 329750, SumXp: 1698330, GoldReq: 80000, Renown: 30 }, + { Multiplier: 6, TotalXp: 395700, SumXp: 2094030, GoldReq: 90000, Renown: 30 }, + { Multiplier: 7, TotalXp: 461650, SumXp: 2555680, GoldReq: 100000, Renown: 30 }, + { Multiplier: 8, TotalXp: 527600, SumXp: 3083280, GoldReq: 125000, Renown: 30 }, + { Multiplier: 9, TotalXp: 593550, SumXp: 3676830, GoldReq: 150000, Renown: 30 }, + { Multiplier: 10, TotalXp: 659500, SumXp: 4336330, GoldReq: 175000, Renown: 40 }, + { Multiplier: 12, TotalXp: 791400, SumXp: 5127730, GoldReq: 200000, Renown: 40 }, + { Multiplier: 14, TotalXp: 923300, SumXp: 6051030, GoldReq: 250000, Renown: 40 }, + { Multiplier: 16, TotalXp: 1055200, SumXp: 7106230, GoldReq: 300000, Renown: 40 }, + { Multiplier: 18, TotalXp: 1187100, SumXp: 8293330, GoldReq: 350000, Renown: 40 }, + { Multiplier: 20, TotalXp: 1319000, SumXp: 9612330, GoldReq: 400000, Renown: 50 }, + { Multiplier: 24, TotalXp: 1582800, SumXp: 11195130, GoldReq: 500000, Renown: 50 }, + { Multiplier: 28, TotalXp: 1846600, SumXp: 13041730, GoldReq: 600000, Renown: 50 }, + { Multiplier: 32, TotalXp: 2110400, SumXp: 15152130, GoldReq: 700000, Renown: 50 }, + { Multiplier: 36, TotalXp: 2374200, SumXp: 17526330, GoldReq: 800000, Renown: 50 }, + { Multiplier: 40, TotalXp: 2638000, SumXp: 20164330, GoldReq: 900000, Renown: 75 }, + { Multiplier: 45, TotalXp: 2967750, SumXp: 23132080, GoldReq: 1000000, Renown: 75 }, + { Multiplier: 50, TotalXp: 3297500, SumXp: 26429580, GoldReq: 1000000, Renown: 75 }, + { Multiplier: 75, TotalXp: 4946250, SumXp: 31375830, GoldReq: 1000000, Renown: 75 }, + { Multiplier: 100, TotalXp: 6595000, SumXp: 37970830, GoldReq: 1000000, Renown: 250 }, + { Multiplier: 101, TotalXp: 6660950, SumXp: 44631780, GoldReq: 1000000, Renown: 100 }, + { Multiplier: 101, TotalXp: 6660950, SumXp: 51292730, GoldReq: 1000000, Renown: 100 }, + { Multiplier: 101, TotalXp: 6660950, SumXp: 57953680, GoldReq: 1000000, Renown: 100 }, + { Multiplier: 101, TotalXp: 6660950, SumXp: 64614630, GoldReq: 1000000, Renown: 100 }, + { Multiplier: 101, TotalXp: 6660950, SumXp: 71275580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 200, TotalXp: 13190000, SumXp: 84465580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 300, TotalXp: 19785000, SumXp: 104250580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 400, TotalXp: 26380000, SumXp: 130630580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 500, TotalXp: 32975000, SumXp: 163605580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 750, TotalXp: 49462500, SumXp: 213068080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 1000, TotalXp: 65950000, SumXp: 279018080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 1250, TotalXp: 82437500, SumXp: 361455580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 1500, TotalXp: 98925000, SumXp: 460380580, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 1750, TotalXp: 115412500, SumXp: 575793080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 2000, TotalXp: 131900000, SumXp: 707693080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 3000, TotalXp: 197850000, SumXp: 905543080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 5000, TotalXp: 329750000, SumXp: 1235293080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 10000, TotalXp: 659500000, SumXp: 1894793080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 50000, TotalXp: 3297500000, SumXp: 5192293080, GoldReq: 2000000, Renown: 100 }, + { Multiplier: 100000, TotalXp: 6595000000, SumXp: 11787293080, GoldReq: 0, Renown: 100 } + ], + Levels: [ + { Xp: 15 }, + { Xp: 30 }, + { Xp: 50 }, + { Xp: 75 }, + { Xp: 125 }, + { Xp: 300 }, + { Xp: 600 }, + { Xp: 800 }, + { Xp: 900 }, + { Xp: 1000 }, + { Xp: 1200 }, + { Xp: 1500 }, + { Xp: 0 } + ] +}; + +// credit: https://github.com/SkyCryptWebsite/SkyCrypt/blob/b9842bea6f1494fa2d2fd005b64f57d84646c188/src/constants/forge.js#L1 (Modified) +// Times in milliseconds +export const MiningForgeItems: MiningForgeItemsData = { + REFINED_DIAMOND: { name: 'Refined Diamond', duration: 28800000 }, + REFINED_MITHRIL: { name: 'Refined Mithril', duration: 21600000 }, + REFINED_TITANIUM: { name: 'Refined Titanium', duration: 43200000 }, + REFINED_TUNGSTEN: { name: 'Refined Tungsten', duration: 3600000 }, + REFINED_UMBER: { name: 'Refined Umber', duration: 3600000 }, + MITHRIL_NECKLACE: { name: 'Mithril Necklace', duration: 3600000 }, + MITHRIL_CLOAK: { name: 'Mithril Cloak', duration: 3600000 }, + MITHRIL_BELT: { name: 'Mithril Belt', duration: 3600000 }, + MITHRIL_GAUNTLET: { name: 'Mithril Gauntlet', duration: 3600000 }, + TITANIUM_NECKLACE: { name: 'Titanium Necklace', duration: 16200000 }, + TITANIUM_CLOAK: { name: 'Titanium Cloak', duration: 16200000 }, + TITANIUM_BELT: { name: 'Titanium Belt', duration: 16200000 }, + TITANIUM_GAUNTLET: { name: 'Titanium Gauntlet', duration: 16200000 }, + TITANIUM_TALISMAN: { name: 'Titanium Talisman', duration: 50400000 }, + TITANIUM_RING: { name: 'Titanium Ring', duration: 72000000 }, + TITANIUM_ARTIFACT: { name: 'Titanium Artifact', duration: 129600000 }, + TITANIUM_RELIC: { name: 'Titanium Relic', duration: 259200000 }, + DIVAN_POWDER_COATING: { name: 'Divan Powder Coating', duration: 129600000 }, + DIVAN_HELMET: { name: 'Helmet Of Divan', duration: 86400000 }, + DIVAN_CHESTPLATE: { name: 'Chestplate Of Divan', duration: 86400000 }, + DIVAN_LEGGINGS: { name: 'Leggings Of Divan', duration: 86400000 }, + DIVAN_BOOTS: { name: 'Boots Of Divan', duration: 86400000 }, + AMBER_NECKLACE: { name: 'Amber Necklace', duration: 86400000 }, + SAPPHIRE_CLOAK: { name: 'Sapphire Cloak', duration: 86400000 }, + JADE_BELT: { name: 'Jade Belt', duration: 86400000 }, + AMETHYST_GAUNTLET: { name: 'Amethyst Gauntlet', duration: 86400000 }, + GEMSTONE_CHAMBER: { name: 'Gemstone Chamber', duration: 14400000 }, + DWARVEN_HANDWARMERS: { name: 'Dwarven Handwarmers', duration: 14400000 }, + DWARVEN_METAL: { name: 'Dwarven Metal Talisman', duration: 86400000 }, + DIVAN_PENDANT: { name: 'Pendant of Divan', duration: 604800000 }, + POWER_RELIC: { name: 'Relic of Power', duration: 28800000 }, + PERFECT_AMBER_GEM: { name: 'Perfect Amber Gemstone', duration: 72000000 }, + PERFECT_AMETHYST_GEM: { name: 'Perfect Amethyst Gemstone', duration: 72000000 }, + PERFECT_JADE_GEM: { name: 'Perfect Jade Gemstone', duration: 72000000 }, + PERFECT_JASPER_GEM: { name: 'Perfect Jasper Gemstone', duration: 72000000 }, + PERFECT_OPAL_GEM: { name: 'Perfect Opal Gemstone', duration: 72000000 }, + PERFECT_RUBY_GEM: { name: 'Perfect Ruby Gemstone', duration: 72000000 }, + PERFECT_SAPPHIRE_GEM: { name: 'Perfect Sapphire Gemstone', duration: 72000000 }, + PERFECT_TOPAZ_GEM: { name: 'Perfect Topaz Gemstone', duration: 72000000 }, + PERFECT_AQUAMARINE_GEM: { name: 'Perfect Aquamarine Gem', duration: 72000000 }, + PERFECT_CITRINE_GEM: { name: 'Perfect Citrine Gem', duration: 72000000 }, + PERFECT_ONYX_GEM: { name: 'Perfect Onyx Gem', duration: 72000000 }, + PERFECT_PERIDOT_GEM: { name: 'Perfect Peridot Gem', duration: 72000000 }, + BEJEWELED_HANDLE: { name: 'Bejeweled Handle', duration: 30000 }, + DRILL_ENGINE: { name: 'Drill Motor', duration: 108000000 }, + FUEL_TANK: { name: 'Fuel Canister', duration: 36000000 }, + GEMSTONE_MIXTURE: { name: 'Gemstone Mixture', duration: 14400000 }, + GLACITE_AMALGAMATION: { name: 'Glacite Amalgamation', duration: 14400000 }, + GOLDEN_PLATE: { name: 'Golden Plate', duration: 21600000 }, + MITHRIL_PLATE: { name: 'Mithril Plate', duration: 64800000 }, + TUNGSTEN_PLATE: { name: 'Tungsten Plate', duration: 10800000 }, + UMBER_PLATE: { name: 'Umber Plate', duration: 10800000 }, + PERFECT_PLATE: { name: 'Perfect Plate', duration: 1800000 }, + DIAMONITE: { name: 'Diamonite', duration: 21600000 }, + POCKET_ICEBERG: { name: 'Pocket Iceberg', duration: 21600000 }, + PETRIFIED_STARFALL: { name: 'Petrified Starfall', duration: 21600000 }, + PURE_MITHRIL: { name: 'Pure Mithril', duration: 21600000 }, + ROCK_GEMSTONE: { name: 'Dwarven Geode', duration: 21600000 }, + TITANIUM_TESSERACT: { name: 'Titanium Tesseract', duration: 21600000 }, + GLEAMING_CRYSTAL: { name: 'Gleaming Crystal', duration: 21600000 }, + HOT_STUFF: { name: 'Scorched Topaz', duration: 21600000 }, + AMBER_MATERIAL: { name: 'Amber Material', duration: 21600000 }, + FRIGID_HUSK: { name: 'Frigid Husk', duration: 21600000 }, + BEJEWELED_COLLAR: { name: 'Bejeweled Collar', duration: 7200000 }, + MOLE: { name: '[Lvl 1] Mole', duration: 259200000 }, + AMMONITE: { name: '[Lvl 1] Ammonite', duration: 259200000 }, + PENGUIN: { name: '[Lvl 1] Penguin', duration: 604800000 }, + TYRANNOSAURUS: { name: '[Lvl 1] T-Rex', duration: 604800000 }, + SPINOSAURUS: { name: '[Lvl 1] Spinosaurus', duration: 604800000 }, + GOBLIN: { name: '[Lvl 1] Goblin', duration: 604800000 }, + ANKYLOSAURUS: { name: '[Lvl 1] Ankylosaurus', duration: 604800000 }, + MAMMOTH: { name: '[Lvl 1] Mammoth', duration: 604800000 }, + MITHRIL_DRILL_1: { name: 'Mithril Drill SX-R226', duration: 14400000 }, + MITHRIL_DRILL_2: { name: 'Mithril Drill SX-R326', duration: 30000 }, + GEMSTONE_DRILL_1: { name: 'Ruby Drill TX-15', duration: 14400000 }, + GEMSTONE_DRILL_2: { name: 'Gemstone Drill LT-522', duration: 30000 }, + GEMSTONE_DRILL_3: { name: 'Topaz Drill KGR-12', duration: 30000 }, + GEMSTONE_DRILL_4: { name: 'Jasper Drill X', duration: 30000 }, + TOPAZ_ROD: { name: 'Topaz Rod', duration: 43200000 }, + TITANIUM_DRILL_1: { name: 'Titanium Drill DR-X355', duration: 14400000 }, + TITANIUM_DRILL_2: { name: 'Titanium Drill DR-X455', duration: 30000 }, + TITANIUM_DRILL_3: { name: 'Titanium Drill DR-X555', duration: 30000 }, + TITANIUM_DRILL_4: { name: 'Titanium Drill DR-X655', duration: 30000 }, + CHISEL: { name: 'Chisel', duration: 14400000 }, + REINFORCED_CHISEL: { name: 'Reinforced Chisel', duration: 30000 }, + GLACITE_CHISEL: { name: 'Glacite-Plated Chisel', duration: 30000 }, + PERFECT_CHISEL: { name: 'Perfect Chisel', duration: 30000 }, + DIVAN_DRILL: { name: "Divan's Drill", duration: 30000 }, + STARFALL_SEASONING: { name: 'Starfall Seasoning', duration: 64800000 }, + GOBLIN_OMELETTE: { name: 'Goblin Omelette', duration: 64800000 }, + GOBLIN_OMELETTE_BLUE_CHEESE: { name: 'Blue Cheese Goblin Omelette', duration: 64800000 }, + GOBLIN_OMELETTE_PESTO: { name: 'Pesto Goblin Omelette', duration: 64800000 }, + GOBLIN_OMELETTE_SPICY: { name: 'Spicy Goblin Omelette', duration: 64800000 }, + GOBLIN_OMELETTE_SUNNY_SIDE: { name: 'Sunny Side Goblin Omelette', duration: 64800000 }, + TUNGSTEN_KEYCHAIN: { name: 'Tungsten Regulator', duration: 64800000 }, + MITHRIL_DRILL_ENGINE: { name: 'Mithril-Plated Drill Engine', duration: 86400000 }, + TITANIUM_DRILL_ENGINE: { name: 'Titanium-Plated Drill Engine', duration: 30000 }, + RUBY_POLISHED_DRILL_ENGINE: { name: 'Ruby-Polished Drill Engine', duration: 30000 }, + SAPPHIRE_POLISHED_DRILL_ENGINE: { name: 'Sapphire-Polished Drill Engine', duration: 30000 }, + AMBER_POLISHED_DRILL_ENGINE: { name: 'Amber-Polished Drill Engine', duration: 30000 }, + MITHRIL_FUEL_TANK: { name: 'Mithril-Infused Fuel Tank', duration: 86400000 }, + TITANIUM_FUEL_TANK: { name: 'Titanium-Infused Fuel Tank', duration: 30000 }, + GEMSTONE_FUEL_TANK: { name: 'Gemstone Fuel Tank', duration: 30000 }, + PERFECTLY_CUT_FUEL_TANK: { name: 'Perfectly-Cut Fuel Tank', duration: 30000 }, + BEACON_2: { name: 'Beacon II', duration: 72000000 }, + BEACON_3: { name: 'Beacon III', duration: 108000000 }, + BEACON_4: { name: 'Beacon IV', duration: 144000000 }, + BEACON_5: { name: 'Beacon V', duration: 180000000 }, + FORGE_TRAVEL_SCROLL: { name: 'Travel Scroll to the Dwarven Forge', duration: 18000000 }, + BASE_CAMP_TRAVEL_SCROLL: { name: 'Travel Scroll to the Dwarven Base Camp', duration: 36000000 }, + POWER_CRYSTAL: { name: 'Power Crystal', duration: 7200000 }, + SECRET_RAILROAD_PASS: { name: 'Secret Railroad Pass', duration: 30000 }, + TUNGSTEN_KEY: { name: 'Tungsten Key', duration: 1800000 }, + UMBER_KEY: { name: 'Umber Key', duration: 1800000 }, + SKELETON_KEY: { name: 'Skeleton Key', duration: 1800000 }, + PORTABLE_CAMPFIRE: { name: 'Portable Campfire', duration: 1800000 }, + PET: { name: 'PET', duration: 0 }, + UNKNOWN: { name: 'UNKNOWN', duration: 0 } +}; + +export const MiningForgeQuickForgeMultiplier: { [key: number]: number } = { + 0: 1, + 1: 0.895, + 2: 0.89, + 3: 0.885, + 4: 0.88, + 5: 0.875, + 6: 0.87, + 7: 0.865, + 8: 0.86, + 9: 0.855, + 10: 0.85, + 11: 0.845, + 12: 0.84, + 13: 0.835, + 14: 0.83, + 15: 0.825, + 16: 0.82, + 17: 0.815, + 18: 0.81, + 19: 0.805, + 20: 0.7 +}; + +export const magicalPowerValues: { [key in Rarity | 'UNKNOWN']: number } = { + COMMON: 3, + UNCOMMON: 5, + RARE: 8, + EPIC: 12, + LEGENDARY: 16, + MYTHIC: 22, + SPECIAL: 3, + VERY_SPECIAL: 5, + DIVINE: 0, + UNKNOWN: 0 +}; + +export const petScore: { [key in Rarity | 'UNKNOWN']: number } = { + COMMON: 1, + UNCOMMON: 2, + RARE: 3, + EPIC: 4, + LEGENDARY: 5, + MYTHIC: 6, + VERY_SPECIAL: 6, + DIVINE: 0, + SPECIAL: 0, + UNKNOWN: 0 +}; + +export const petRarityOffset: { [key in Rarity | 'UNKNOWN']: number } = { + COMMON: 0, + UNCOMMON: 6, + RARE: 11, + EPIC: 16, + LEGENDARY: 20, + MYTHIC: 20, + DIVINE: 0, + SPECIAL: 0, + VERY_SPECIAL: 0, + UNKNOWN: 0 +}; + +export const PetLevels: number[] = [ + 100, 110, 120, 130, 145, 160, 175, 190, 210, 230, 250, 275, 300, 330, 360, 400, 440, 490, 540, 600, 660, 730, 800, + 880, 960, 1050, 1150, 1260, 1380, 1510, 1650, 1800, 1960, 2130, 2310, 2500, 2700, 2920, 3160, 3420, 3700, 4000, 4350, + 4750, 5200, 5700, 6300, 7000, 7800, 8700, 9700, 10800, 12000, 13300, 14700, 16200, 17800, 19500, 21300, 23200, 25200, + 27400, 29800, 32400, 35200, 38200, 41400, 44800, 48400, 52200, 56200, 60400, 64800, 69400, 74200, 79200, 84700, 90700, + 97200, 104200, 111700, 119700, 128200, 137200, 146700, 156700, 167700, 179700, 192700, 206700, 221700, 237700, 254700, + 272700, 291700, 311700, 333700, 357700, 383700, 411700, 441700, 476700, 516700, 561700, 611700, 666700, 726700, + 791700, 861700, 936700, 1016700, 1101700, 1191700, 1286700, 1386700, 1496700, 1616700, 1746700, 1886700 +]; + +export const CustomPetLeveling: CustomPetLevelingData = { + GOLDEN_DRAGON: { + type: 1, + petLevels: [ + 0, 5555, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, + 1886700, 1886700, 1886700 + ], + maxLevel: 200 + }, + BINGO: { + rarityOffset: { + UNKNOWN: 0, + COMMON: 0, + UNCOMMON: 0, + RARE: 0, + EPIC: 0, + LEGENDARY: 0, + MYTHIC: 0, + DIVINE: 0, + SPECIAL: 0, + VERY_SPECIAL: 0 + } + }, + REINDEER: { xpMultiplier: 2 } +}; + +export const SLAYER_XP: { [key in SkyBlockSlayer]: Record } = { + zombie: { 1: 5, 2: 15, 3: 200, 4: 1000, 5: 5000, 6: 20000, 7: 100000, 8: 400000, 9: 1000000 }, + spider: { 1: 5, 2: 25, 3: 200, 4: 1000, 5: 5000, 6: 20000, 7: 100000, 8: 400000, 9: 1000000 }, + wolf: { 1: 10, 2: 30, 3: 250, 4: 1500, 5: 5000, 6: 20000, 7: 100000, 8: 400000, 9: 1000000 }, + enderman: { 1: 10, 2: 30, 3: 250, 4: 1500, 5: 5000, 6: 20000, 7: 100000, 8: 400000, 9: 1000000 }, + blaze: { 1: 10, 2: 30, 3: 250, 4: 1500, 5: 5000, 6: 20000, 7: 100000, 8: 400000, 9: 1000000 }, + vampire: { 1: 20, 2: 75, 3: 240, 4: 840, 5: 2400 } +}; + +export const DEFAULT_SKILL_CAPS: { [key in SkyBlockXPTables]: number } = { + farming: 50, + mining: 60, + combat: 60, + foraging: 50, + fishing: 50, + enchanting: 60, + alchemy: 50, + taming: 50, + carpentry: 50, + runecrafting: 25, + social: 25, + dungeoneering: 50, + default: 0, + hotm: 10, + wheat: 46, + carrot: 46, + sugarCane: 46, + potato: 46, + pumpkin: 46, + melon: 46, + cactus: 46, + cocoaBeans: 46, + mushroom: 46, + netherWart: 46, + moonFlower: 46, + sunFlower: 46, + wildRose: 46, + garden: 15 +}; + +export const NON_RUNECRAFTING_LEVEL_CAP = 3; + +export const RUNECRAFTING_XP: Record = { + 1: 50, + 2: 100, + 3: 125, + 4: 160, + 5: 200, + 6: 250, + 7: 315, + 8: 400, + 9: 500, + 10: 625, + 11: 785, + 12: 1000, + 13: 1250, + 14: 1600, + 15: 2000, + 16: 2465, + 17: 3125, + 18: 4000, + 19: 5000, + 20: 6200, + 21: 7800, + 22: 9800, + 23: 12200, + 24: 15300, + 25: 19050 +}; + +export const DUNGEONEERING_XP: Record = { + 1: 50, + 2: 75, + 3: 110, + 4: 160, + 5: 230, + 6: 330, + 7: 470, + 8: 670, + 9: 950, + 10: 1340, + 11: 1890, + 12: 2665, + 13: 3760, + 14: 5260, + 15: 7380, + 16: 10300, + 17: 14400, + 18: 20000, + 19: 27600, + 20: 38000, + 21: 52500, + 22: 71500, + 23: 97000, + 24: 132000, + 25: 180000, + 26: 243000, + 27: 328000, + 28: 445000, + 29: 600000, + 30: 800000, + 31: 1065000, + 32: 1410000, + 33: 1900000, + 34: 2500000, + 35: 3300000, + 36: 4300000, + 37: 5600000, + 38: 7200000, + 39: 9200000, + 40: 12000000, + 41: 15000000, + 42: 19000000, + 43: 24000000, + 44: 30000000, + 45: 38000000, + 46: 48000000, + 47: 60000000, + 48: 75000000, + 49: 93000000, + 50: 116250000, + 51: 200000000 +}; + +export const SOCIAL_XP: Record = { + 1: 50, + 2: 100, + 3: 150, + 4: 250, + 5: 500, + 6: 750, + 7: 1000, + 8: 1250, + 9: 1500, + 10: 2000, + 11: 2500, + 12: 3000, + 13: 3750, + 14: 4500, + 15: 6000, + 16: 8000, + 17: 10000, + 18: 12500, + 19: 15000, + 20: 20000, + 21: 25000, + 22: 30000, + 23: 35000, + 24: 40000, + 25: 50000 +}; + +export const DEFAULT_LEVELING_XP: Record = { + 1: 50, + 2: 125, + 3: 200, + 4: 300, + 5: 500, + 6: 750, + 7: 1000, + 8: 1500, + 9: 2000, + 10: 3500, + 11: 5000, + 12: 7500, + 13: 10000, + 14: 15000, + 15: 20000, + 16: 30000, + 17: 50000, + 18: 75000, + 19: 100000, + 20: 200000, + 21: 300000, + 22: 400000, + 23: 500000, + 24: 600000, + 25: 700000, + 26: 800000, + 27: 900000, + 28: 1000000, + 29: 1100000, + 30: 1200000, + 31: 1300000, + 32: 1400000, + 33: 1500000, + 34: 1600000, + 35: 1700000, + 36: 1800000, + 37: 1900000, + 38: 2000000, + 39: 2100000, + 40: 2200000, + 41: 2300000, + 42: 2400000, + 43: 2500000, + 44: 2600000, + 45: 2750000, + 46: 2900000, + 47: 3100000, + 48: 3400000, + 49: 3700000, + 50: 4000000, + 51: 4300000, + 52: 4600000, + 53: 4900000, + 54: 5200000, + 55: 5500000, + 56: 5800000, + 57: 6100000, + 58: 6400000, + 59: 6700000, + 60: 7000000 +}; + +export const HOTM_XP: Record = { + 1: 0, + 2: 3000, + 3: 9000, + 4: 25000, + 5: 60000, + 6: 100000, + 7: 150000, + 8: 210000, + 9: 290000, + 10: 400000 +}; + +export const COSMETIC_SKILLS = ['runecrafting', 'social']; + +export const INFINITE = ['dungeoneering', 'skyblock_level']; + +export const GARDEN_XP = { + 1: 0, + 2: 70, + 3: 70, + 4: 140, + 5: 240, + 6: 600, + 7: 1500, + 8: 2000, + 9: 2500, + 10: 3000, + 11: 10000, + 12: 10000, + 13: 10000, + 14: 10000, + 15: 10000 +}; + +export const WHEAT = { + 1: 30, + 2: 50, + 3: 80, + 4: 200, + 5: 350, + 6: 700, + 7: 1500, + 8: 2500, + 9: 3500, + 10: 5000, + 11: 6500, + 12: 8000, + 13: 10000, + 14: 20000, + 15: 35000, + 16: 50000, + 17: 75000, + 18: 100000, + 19: 175000, + 20: 250000, + 21: 375000, + 22: 400000, + 23: 450000, + 24: 650000, + 25: 800000, + 26: 800000, + 27: 800000, + 28: 800000, + 29: 800000, + 30: 800000, + 31: 800000, + 32: 800000, + 33: 800000, + 34: 800000, + 35: 800000, + 36: 800000, + 37: 800000, + 38: 800000, + 39: 800000, + 40: 800000, + 41: 800000, + 42: 800000, + 43: 800000, + 44: 800000, + 45: 800000, + 46: 800000 +}; + +export const CARROT = { + 1: 100, + 2: 150, + 3: 250, + 4: 500, + 5: 1000, + 6: 2000, + 7: 4500, + 8: 9000, + 9: 12000, + 10: 15000, + 11: 20000, + 12: 25000, + 13: 35000, + 14: 70000, + 15: 120000, + 16: 180000, + 17: 250000, + 18: 350000, + 19: 600000, + 20: 850000, + 21: 1100000, + 22: 1400000, + 23: 1800000, + 24: 2200000, + 25: 2600000, + 26: 2600000, + 27: 2600000, + 28: 2600000, + 29: 2600000, + 30: 2600000, + 31: 2600000, + 32: 2600000, + 33: 2600000, + 34: 2600000, + 35: 2600000, + 36: 2600000, + 37: 2600000, + 38: 2600000, + 39: 2600000, + 40: 2600000, + 41: 2600000, + 42: 2600000, + 43: 2600000, + 44: 2600000, + 45: 2600000, + 46: 2600000 +}; + +export const POTATO = { + 1: 100, + 2: 150, + 3: 250, + 4: 500, + 5: 1000, + 6: 2000, + 7: 4500, + 8: 9000, + 9: 12000, + 10: 15000, + 11: 20000, + 12: 25000, + 13: 35000, + 14: 70000, + 15: 120000, + 16: 180000, + 17: 250000, + 18: 350000, + 19: 600000, + 20: 850000, + 21: 1100000, + 22: 1400000, + 23: 1800000, + 24: 2200000, + 25: 2600000, + 26: 2600000, + 27: 2600000, + 28: 2600000, + 29: 2600000, + 30: 2600000, + 31: 2600000, + 32: 2600000, + 33: 2600000, + 34: 2600000, + 35: 2600000, + 36: 2600000, + 37: 2600000, + 38: 2600000, + 39: 2600000, + 40: 2600000, + 41: 2600000, + 42: 2600000, + 43: 2600000, + 44: 2600000, + 45: 2600000, + 46: 2600000 +}; + +export const MELON = { + 1: 150, + 2: 250, + 3: 400, + 4: 1000, + 5: 1750, + 6: 3500, + 7: 7500, + 8: 12500, + 9: 17500, + 10: 25000, + 11: 32500, + 12: 40000, + 13: 50000, + 14: 100000, + 15: 175000, + 16: 250000, + 17: 375000, + 18: 500000, + 19: 875000, + 20: 1250000, + 21: 1875000, + 22: 2000000, + 23: 2250000, + 24: 3250000, + 25: 4000000, + 26: 4000000, + 27: 4000000, + 28: 4000000, + 29: 4000000, + 30: 4000000, + 31: 4000000, + 32: 4000000, + 33: 4000000, + 34: 4000000, + 35: 4000000, + 36: 4000000, + 37: 4000000, + 38: 4000000, + 39: 4000000, + 40: 4000000, + 41: 4000000, + 42: 4000000, + 43: 4000000, + 44: 4000000, + 45: 4000000, + 46: 4000000 +}; + +export const PUMPKIN = { + 1: 30, + 2: 50, + 3: 80, + 4: 200, + 5: 350, + 6: 700, + 7: 1500, + 8: 2500, + 9: 3500, + 10: 5000, + 11: 6500, + 12: 8000, + 13: 10000, + 14: 20000, + 15: 35000, + 16: 50000, + 17: 75000, + 18: 100000, + 19: 175000, + 20: 250000, + 21: 375000, + 22: 400000, + 23: 450000, + 24: 650000, + 25: 800000, + 26: 800000, + 27: 800000, + 28: 800000, + 29: 800000, + 30: 800000, + 31: 800000, + 32: 800000, + 33: 800000, + 34: 800000, + 35: 800000, + 36: 800000, + 37: 800000, + 38: 800000, + 39: 800000, + 40: 800000, + 41: 800000, + 42: 800000, + 43: 800000, + 44: 800000, + 45: 800000, + 46: 800000 +}; + +export const SUGAR_CANE = { + 1: 60, + 2: 100, + 3: 160, + 4: 400, + 5: 700, + 6: 1400, + 7: 3000, + 8: 5000, + 9: 7000, + 10: 10000, + 11: 13000, + 12: 16000, + 13: 20000, + 14: 40000, + 15: 70000, + 16: 100000, + 17: 150000, + 18: 200000, + 19: 350000, + 20: 500000, + 21: 750000, + 22: 800000, + 23: 900000, + 24: 1300000, + 25: 1600000, + 26: 1600000, + 27: 1600000, + 28: 1600000, + 29: 1600000, + 30: 1600000, + 31: 1600000, + 32: 1600000, + 33: 1600000, + 34: 1600000, + 35: 1600000, + 36: 1600000, + 37: 1600000, + 38: 1600000, + 39: 1600000, + 40: 1600000, + 41: 1600000, + 42: 1600000, + 43: 1600000, + 44: 1600000, + 45: 1600000, + 46: 1600000 +}; + +export const COCOA_BEANS = { + 1: 90, + 2: 150, + 3: 240, + 4: 600, + 5: 1050, + 6: 2100, + 7: 4500, + 8: 7500, + 9: 10500, + 10: 15000, + 11: 19500, + 12: 24000, + 13: 30000, + 14: 60000, + 15: 105000, + 16: 150000, + 17: 225000, + 18: 300000, + 19: 525000, + 20: 750000, + 21: 1125000, + 22: 1200000, + 23: 1350000, + 24: 1950000, + 25: 2400000, + 26: 2400000, + 27: 2400000, + 28: 2400000, + 29: 2400000, + 30: 2400000, + 31: 2400000, + 32: 2400000, + 33: 2400000, + 34: 2400000, + 35: 2400000, + 36: 2400000, + 37: 2400000, + 38: 2400000, + 39: 2400000, + 40: 2400000, + 41: 2400000, + 42: 2400000, + 43: 2400000, + 44: 2400000, + 45: 2400000, + 46: 2400000 +}; + +export const CACTUS = { + 1: 60, + 2: 100, + 3: 160, + 4: 400, + 5: 700, + 6: 1400, + 7: 3000, + 8: 5000, + 9: 7000, + 10: 10000, + 11: 13000, + 12: 16000, + 13: 20000, + 14: 40000, + 15: 70000, + 16: 100000, + 17: 150000, + 18: 200000, + 19: 350000, + 20: 500000, + 21: 750000, + 22: 800000, + 23: 900000, + 24: 1300000, + 25: 1600000, + 26: 1600000, + 27: 1600000, + 28: 1600000, + 29: 1600000, + 30: 1600000, + 31: 1600000, + 32: 1600000, + 33: 1600000, + 34: 1600000, + 35: 1600000, + 36: 1600000, + 37: 1600000, + 38: 1600000, + 39: 1600000, + 40: 1600000, + 41: 1600000, + 42: 1600000, + 43: 1600000, + 44: 1600000, + 45: 1600000, + 46: 1600000 +}; + +export const MUSHROOM = { + 1: 30, + 2: 50, + 3: 80, + 4: 200, + 5: 350, + 6: 700, + 7: 1500, + 8: 2500, + 9: 3500, + 10: 5000, + 11: 6500, + 12: 8000, + 13: 10000, + 14: 20000, + 15: 35000, + 16: 50000, + 17: 75000, + 18: 100000, + 19: 175000, + 20: 250000, + 21: 375000, + 22: 400000, + 23: 450000, + 24: 650000, + 25: 800000, + 26: 800000, + 27: 800000, + 28: 800000, + 29: 800000, + 30: 800000, + 31: 800000, + 32: 800000, + 33: 800000, + 34: 800000, + 35: 800000, + 36: 800000, + 37: 800000, + 38: 800000, + 39: 800000, + 40: 800000, + 41: 800000, + 42: 800000, + 43: 800000, + 44: 800000, + 45: 800000, + 46: 800000 +}; + +export const NETHER_WART = { + 1: 90, + 2: 150, + 3: 240, + 4: 600, + 5: 1050, + 6: 2100, + 7: 4500, + 8: 7500, + 9: 10500, + 10: 15000, + 11: 19500, + 12: 24000, + 13: 30000, + 14: 60000, + 15: 105000, + 16: 150000, + 17: 225000, + 18: 300000, + 19: 525000, + 20: 750000, + 21: 1125000, + 22: 1200000, + 23: 1350000, + 24: 1950000, + 25: 2400000, + 26: 2400000, + 27: 2400000, + 28: 2400000, + 29: 2400000, + 30: 2400000, + 31: 2400000, + 32: 2400000, + 33: 2400000, + 34: 2400000, + 35: 2400000, + 36: 2400000, + 37: 2400000, + 38: 2400000, + 39: 2400000, + 40: 2400000, + 41: 2400000, + 42: 2400000, + 43: 2400000, + 44: 2400000, + 45: 2400000, + 46: 2400000 +}; + +export const MOONFLOWER = { + 1: 30, + 2: 50, + 3: 80, + 4: 200, + 5: 700, + 6: 700, + 7: 1500, + 8: 2500, + 9: 3500, + 10: 5000, + 11: 6500, + 12: 8000, + 13: 10000, + 14: 20000, + 15: 35000, + 16: 50000, + 17: 75000, + 18: 100000, + 19: 175000, + 20: 250000, + 21: 375000, + 22: 400000, + 23: 450000, + 24: 650000, + 25: 800000, + 26: 800000, + 27: 800000, + 28: 800000, + 29: 800000, + 30: 800000, + 31: 800000, + 32: 800000, + 33: 800000, + 34: 800000, + 35: 800000, + 36: 800000, + 37: 800000, + 38: 800000, + 39: 800000, + 40: 800000, + 41: 800000, + 42: 800000, + 43: 800000, + 44: 800000, + 45: 800000, + 46: 800000 +}; + +export const SUNFLOWER = { + 1: 30, + 2: 50, + 3: 80, + 4: 200, + 5: 350, + 6: 700, + 7: 1500, + 8: 2500, + 9: 3500, + 10: 5000, + 11: 6500, + 12: 8000, + 13: 10000, + 14: 20000, + 15: 35000, + 16: 50000, + 17: 75000, + 18: 100000, + 19: 175000, + 20: 250000, + 21: 375000, + 22: 400000, + 23: 450000, + 24: 650000, + 25: 800000, + 26: 800000, + 27: 800000, + 28: 800000, + 29: 800000, + 30: 800000, + 31: 800000, + 32: 800000, + 33: 800000, + 34: 800000, + 35: 800000, + 36: 800000, + 37: 800000, + 38: 800000, + 39: 800000, + 40: 800000, + 41: 800000, + 42: 800000, + 43: 800000, + 44: 800000, + 45: 800000, + 46: 800000 +}; + +export const WILD_ROSE = { + 1: 60, + 2: 100, + 3: 160, + 4: 400, + 5: 700, + 6: 1400, + 7: 3000, + 8: 5000, + 9: 7000, + 10: 10000, + 11: 13000, + 12: 16000, + 13: 20000, + 14: 40000, + 15: 70000, + 16: 100000, + 17: 150000, + 18: 200000, + 19: 350000, + 20: 500000, + 21: 750000, + 22: 800000, + 23: 900000, + 24: 1300000, + 25: 1600000, + 26: 1600000, + 27: 1600000, + 28: 1600000, + 29: 1600000, + 30: 1600000, + 31: 1600000, + 32: 1600000, + 33: 1600000, + 34: 1600000, + 35: 1600000, + 36: 1600000, + 37: 1600000, + 38: 1600000, + 39: 1600000, + 40: 1600000, + 41: 1600000, + 42: 1600000, + 43: 1600000, + 44: 1600000, + 45: 1600000, + 46: 1600000 +}; + +/* eslint-disable camelcase */ + +export const BestiaryBrackets: { [key: number]: number[] } = { + 1: [ + 20, 40, 60, 100, 200, 400, 800, 1400, 2000, 3000, 6000, 12000, 20000, 30000, 40000, 50000, 60000, 72000, 86000, + 100000, 200000, 400000, 600000, 800000, 1000000 + ], + 2: [ + 5, 10, 15, 25, 50, 100, 200, 350, 500, 750, 1500, 3000, 5000, 7500, 10000, 12500, 15000, 18000, 21500, 25000, 50000, + 100000, 150000, 200000, 250000 + ], + 3: [ + 4, 8, 12, 16, 20, 40, 80, 140, 200, 300, 600, 1200, 2000, 3000, 4000, 5000, 6000, 7200, 8600, 10000, 20000, 40000, + 60000, 80000, 100000 + ], + 4: [ + 2, 4, 6, 10, 15, 20, 25, 35, 50, 75, 150, 300, 500, 750, 1000, 1350, 1650, 2000, 2500, 3000, 5000, 10000, 15000, + 20000, 25000 + ], + 5: [ + 1, 2, 3, 5, 7, 10, 15, 20, 25, 30, 60, 120, 200, 300, 400, 500, 600, 720, 860, 1000, 2000, 4000, 6000, 8000, 10000 + ], + 6: [1, 2, 3, 5, 7, 9, 14, 17, 21, 25, 50, 80, 125, 175, 250, 325, 425, 525, 625, 750, 1500, 3000, 4500, 6000, 7500], + 7: [1, 2, 3, 5, 7, 9, 11, 14, 17, 20, 30, 40, 55, 75, 100, 150, 200, 275, 375, 500, 1000, 1500, 2000, 2500, 3000] +}; + +export const BestiaryMobs: BestiaryMobsData = { + dynamic: { + name: 'Private Island', + mobs: [ + { name: '§aBat', cap: 200, mobs: ['forest_island_bat_3'], bracket: 1 }, + { name: '§aCreeper', cap: 200, mobs: ['creeper_1'], bracket: 1 }, + { + name: '§aEnderman', + cap: 200, + mobs: [ + 'enderman_1', + 'enderman_2', + 'enderman_3', + 'enderman_4', + 'enderman_5', + 'enderman_6', + 'enderman_7', + 'enderman_8', + 'enderman_9', + 'enderman_10', + 'enderman_11', + 'enderman_12', + 'enderman_13', + 'enderman_14', + 'enderman_15' + ], + bracket: 1 + }, + { + name: '§aSkeleton', + cap: 200, + mobs: [ + 'skeleton_1', + 'skeleton_2', + 'skeleton_3', + 'skeleton_4', + 'skeleton_5', + 'skeleton_6', + 'skeleton_7', + 'skeleton_8', + 'skeleton_9', + 'skeleton_10', + 'skeleton_11', + 'skeleton_12', + 'skeleton_13', + 'skeleton_14', + 'skeleton_15' + ], + bracket: 1 + }, + { + name: '§aSlime', + cap: 200, + mobs: [ + 'slime_1', + 'slime_2', + 'slime_3', + 'slime_4', + 'slime_5', + 'slime_6', + 'slime_7', + 'slime_8', + 'slime_9', + 'slime_10', + 'slime_11', + 'slime_12', + 'slime_13', + 'slime_14', + 'slime_15' + ], + bracket: 1 + }, + { + name: '§aSpider', + cap: 200, + mobs: [ + 'spider_1', + 'spider_2', + 'spider_3', + 'spider_4', + 'spider_5', + 'spider_6', + 'spider_7', + 'spider_8', + 'spider_9', + 'spider_10', + 'spider_11', + 'spider_12', + 'spider_13', + 'spider_14', + 'spider_15' + ], + bracket: 1 + }, + { + name: '§aWitch', + cap: 200, + mobs: [ + 'witch_1', + 'witch_2', + 'witch_3', + 'witch_4', + 'witch_5', + 'witch_6', + 'witch_7', + 'witch_8', + 'witch_9', + 'witch_10', + 'witch_11', + 'witch_12', + 'witch_13', + 'witch_14', + 'witch_15' + ], + bracket: 1 + }, + { + name: '§aZombie', + cap: 200, + mobs: [ + 'zombie_1', + 'zombie_2', + 'zombie_3', + 'zombie_4', + 'zombie_5', + 'zombie_6', + 'zombie_7', + 'zombie_8', + 'zombie_9', + 'zombie_10', + 'zombie_11', + 'zombie_12', + 'zombie_13', + 'zombie_14', + 'zombie_15' + ], + bracket: 1 + } + ] + }, + hub: { + name: 'Hub', + mobs: [ + { name: '§aCrypt Ghoul', cap: 40000, mobs: ['unburried_zombie_30'], bracket: 1 }, + { name: '§6Golden Ghoul', cap: 4000, mobs: ['unburried_zombie_60'], bracket: 3 }, + { name: '§aGraveyard Zombie', cap: 200, mobs: ['graveyard_zombie_1'], bracket: 1 }, + { name: '§aOld Wolf', cap: 4000, mobs: ['old_wolf_50'], bracket: 3 }, + { name: '§aWolf', cap: 40000, mobs: ['ruin_wolf_15'], bracket: 1 }, + { name: '§aZombie Villager', cap: 1000, mobs: ['zombie_villager_1'], bracket: 4 } + ] + }, + farming_1: { + name: 'The Farming Islands', + mobs: [ + { name: '§aChicken', cap: 200, mobs: ['farming_chicken_1'], bracket: 1 }, + { name: '§aCow', cap: 200, mobs: ['farming_cow_1'], bracket: 1 }, + { name: '§aMushroom Cow', cap: 200, mobs: ['mushroom_cow_1'], bracket: 1 }, + { name: '§aPig', cap: 200, mobs: ['farming_pig_1'], bracket: 1 }, + { name: '§aRabbit', cap: 200, mobs: ['farming_rabbit_1'], bracket: 1 }, + { name: '§aSheep', cap: 200, mobs: ['farming_sheep_1'], bracket: 1 } + ] + }, + combat_1: { + name: "Spider's Den", + mobs: [ + { name: '§aArachne', cap: 500, mobs: ['arachne_500', 'arachne_300'], bracket: 7 }, + { name: "§aArachne's Brood", cap: 1000, mobs: ['arachne_brood_200', 'arachne_brood_100'], bracket: 4 }, + { name: "§aArachne's Keeper", cap: 400, mobs: ['arachne_keeper_100'], bracket: 5 }, + { name: '§aBroodmother', cap: 400, mobs: ['brood_mother_spider_12'], bracket: 5 }, + { + name: '§aDasher Spider', + cap: 10000, + mobs: ['dasher_spider_50', 'dasher_spider_45', 'dasher_spider_42', 'dasher_spider_4', 'dasher_spider_6'], + bracket: 2 + }, + { name: '§aGravel Skeleton', cap: 4000, mobs: ['respawning_skeleton_2'], bracket: 3 }, + { name: '§aRain Slime', cap: 1000, mobs: ['random_slime_8', 'random_slime_20'], bracket: 4 }, + { + name: '§aSilverfish', + cap: 10000, + mobs: [ + 'jockey_shot_silverfish_3', + 'splitter_spider_silverfish_2', + 'splitter_spider_silverfish_45', + 'splitter_spider_silverfish_42', + 'splitter_spider_silverfish_50', + 'jockey_shot_silverfish_42' + ], + bracket: 2 + }, + { + name: '§aSpider Jockey', + cap: 4000, + mobs: ['spider_jockey_3', 'spider_jockey_42', 'spider_jockey_5'], + bracket: 3 + }, + { + name: '§aSplitter Spider', + cap: 10000, + mobs: [ + 'splitter_spider_2', + 'splitter_spider_45', + 'splitter_spider_42', + 'splitter_spider_50', + 'splitter_spider_4', + 'splitter_spider_6' + ], + bracket: 2 + }, + { + name: '§aVoracious Spider', + cap: 10000, + mobs: ['voracious_spider_50', 'voracious_spider_42', 'voracious_spider_45', 'voracious_spider_10'], + bracket: 2 + }, + { + name: '§aWeaver Spider', + cap: 10000, + mobs: [ + 'weaver_spider_3', + 'weaver_spider_4', + 'weaver_spider_5', + 'weaver_spider_6', + 'weaver_spider_42', + 'weaver_spider_45', + 'weaver_spider_50' + ], + bracket: 2 + } + ] + }, + combat_3: { + name: 'The End', + mobs: [ + { + name: '§aDragon', + cap: 1000, + mobs: [ + 'protector_dragon_100', + 'old_dragon_100', + 'young_dragon_100', + 'wise_dragon_100', + 'superior_dragon_100', + 'strong_dragon_100', + 'unstable_dragon_100' + ], + bracket: 5 + }, + { name: '§aEnderman', cap: 25000, mobs: ['enderman_50', 'enderman_45', 'enderman_42'], bracket: 4 }, + { name: '§aEndermite', cap: 10000, mobs: ['nest_endermite_50', 'endermite_37', 'endermite_40'], bracket: 5 }, + { name: '§aEnd Stone Protector', cap: 500, mobs: ['corrupted_protector_100'], bracket: 7 }, + { name: '§aObsidian Defender', cap: 10000, mobs: ['obsidian_wither_55'], bracket: 5 }, + { name: '§a§dVoidling Extremist', cap: 4000, mobs: ['voidling_extremist_100'], bracket: 3 }, + { name: '§aVoidling Fanatic', cap: 25000, mobs: ['voidling_fanatic_85'], bracket: 4 }, + { name: '§aWatcher', cap: 10000, mobs: ['watcher_55'], bracket: 5 }, + { name: '§aZealot', cap: 25000, mobs: ['zealot_bruiser_100', 'zealot_enderman_55'], bracket: 4 } + ] + }, + crimson_isle: { + name: 'Crimson Isle', + mobs: [ + { name: '§aAshfang', cap: 500, mobs: ['ashfang_200'], bracket: 7 }, + { name: '§aBarbarian Duke X', cap: 500, mobs: ['barbarian_duke_x_200'], bracket: 7 }, + { name: '§aBladesoul', cap: 500, mobs: ['bladesoul_200'], bracket: 7 }, + { name: '§aBlaze', cap: 3000, mobs: ['blaze_25', 'blaze_70', 'bezal_80', 'mutated_blaze_70'], bracket: 4 }, + { name: '§aFlaming Spider', cap: 10000, mobs: ['flaming_spider_80'], bracket: 3 }, + { name: '§aFlare', cap: 10000, mobs: ['flare_90'], bracket: 3 }, + { name: '§aGhast', cap: 3000, mobs: ['ghast_85', 'dive_ghast_90'], bracket: 4 }, + { name: '§aKada Knight', cap: 3000, mobs: ['kada_knight_90'], bracket: 4 }, + { name: '§5§lMage Outlaw', cap: 500, mobs: ['mage_outlaw_200'], bracket: 7 }, + { name: '§a§4§lMagma Boss', cap: 500, mobs: ['magma_boss_500'], bracket: 7 }, + { + name: '§aMagma Cube', + cap: 10000, + mobs: ['pack_magma_cube_90', 'magma_cube_75', 'fireball_magma_cube_75'], + bracket: 3 + }, + { name: '§aMagma Cube Rider', cap: 3000, mobs: ['magma_cube_rider_90'], bracket: 4 }, + { name: '§aMatcho', cap: 400, mobs: ['matcho_100'], bracket: 5 }, + { name: '§4Millennia-Aged Blaze', cap: 4000, mobs: ['old_blaze_110'], bracket: 3 }, + { name: '§aMushroom Bull', cap: 10000, mobs: ['charging_mushroom_cow_80'], bracket: 3 }, + { name: '§aSmoldering Blaze', cap: 25000, mobs: ['smoldering_blaze_95'], bracket: 2 }, + { name: '§aTentacle', cap: 1000, mobs: ['hellwisp_100'], bracket: 5 }, + { name: '§5Vanquisher', cap: 1000, mobs: ['vanquisher_100'], bracket: 5 }, + { name: '§aWither Skeleton', cap: 3000, mobs: ['wither_skeleton_70'], bracket: 4 }, + { name: '§aWither Spectre', cap: 10000, mobs: ['wither_spectre_70'], bracket: 3 } + ] + }, + mining_2: { + name: 'Deep Caverns', + mobs: [ + { name: '§aEmerald Slime', cap: 3000, mobs: ['emerald_slime_5', 'emerald_slime_10'], bracket: 1 }, + { name: '§aLapis Zombie', cap: 3000, mobs: ['lapis_zombie_7'], bracket: 1 }, + { name: '§aMiner Skeleton', cap: 3000, mobs: ['diamond_skeleton_15', 'diamond_skeleton_20'], bracket: 1 }, + { name: '§aMiner Zombie', cap: 3000, mobs: ['diamond_zombie_15', 'diamond_zombie_20'], bracket: 1 }, + { name: '§aRedstone Pigman', cap: 3000, mobs: ['redstone_pigman_10'], bracket: 1 }, + { name: '§aSneaky Creeper', cap: 300, mobs: ['invisible_creeper_3'], bracket: 3 } + ] + }, + mining_3: { + name: 'Dwarven Mines', + mobs: [ + { name: '§aDiamond Goblin', cap: 100, mobs: ['goblin_500'], bracket: 7 }, + { name: '§aGhost', cap: 100000, mobs: ['caverns_ghost_250'], bracket: 3 }, + { name: '§aGlacite Bowman', cap: 1000, mobs: ['glacite_bowman_165'], bracket: 4 }, + { name: '§aGlacite Caver', cap: 1000, mobs: ['glacite_caver_200'], bracket: 4 }, + { name: '§aGlacite Mage', cap: 1000, mobs: ['glacite_mage_155'], bracket: 4 }, + { name: '§aGlacite Mutt', cap: 1000, mobs: ['glacite_mutt_180'], bracket: 4 }, + { name: '§aGlacite Walker', cap: 10000, mobs: ['ice_walker_45'], bracket: 2 }, + { + name: '§aGoblin', + cap: 25000, + mobs: [ + 'goblin_weakling_melee_25', + 'goblin_weakling_melee_40', + 'goblin_weakling_bow_25', + 'goblin_weakling_bow_40', + 'goblin_creepertamer_100', + 'goblin_pitfighter_70', + 'goblin_knife_thrower_25', + 'goblin_knife_thrower_40', + 'goblin_flamethrower_100', + 'goblin_murderlover_200' + ], + bracket: 2 + }, + { + name: '§aGoblin Raiders', + cap: 1000, + mobs: [ + 'goblin_weakling_melee_5', + 'goblin_weakling_bow_5', + 'goblin_creepertamer_90', + 'goblin_creeper_20', + 'goblin_battler_60', + 'goblin_murderlover_150', + 'goblin_golem_150' + ], + bracket: 4 + }, + { name: '§aGolden Goblin', cap: 400, mobs: ['goblin_50'], bracket: 5 }, + { name: '§aPowder Ghast', cap: 200, mobs: ['powder_ghast_1'], bracket: 1 }, + { name: '§5Star Sentry', cap: 1000, mobs: ['crystal_sentry_50'], bracket: 4 }, + { name: '§aTreasure Hoarder', cap: 1000, mobs: ['treasure_hoarder_70'], bracket: 4 } + ] + }, + crystal_hollows: { + name: 'Crystal Hollows', + mobs: [ + { name: '§aAutomaton', cap: 10000, mobs: ['automaton_100', 'automaton_150'], bracket: 2 }, + { name: '§c§lBal', cap: 250, mobs: ['bal_boss_100'], bracket: 6 }, + { name: '§aBoss Corleone', cap: 100, mobs: ['team_treasurite_corleone_200'], bracket: 7 }, + { name: '§eButterfly', cap: 1000, mobs: ['butterfly_100'], bracket: 4 }, + { + name: '§aGrunt', + cap: 4000, + mobs: [ + 'team_treasurite_grunt_50', + 'team_treasurite_viper_100', + 'team_treasurite_wendy_100', + 'team_treasurite_sebastian_100' + ], + bracket: 3 + }, + { name: '§aKey Guardian', cap: 250, mobs: ['key_guardian_100'], bracket: 6 }, + { name: '§aSludge', cap: 10000, mobs: ['sludge_5', 'sludge_10', 'sludge_100'], bracket: 2 }, + { name: '§aThyst', cap: 4000, mobs: ['thyst_20'], bracket: 3 }, + { name: '§aWorm', cap: 400, mobs: ['worm_5', 'scatha_10'], bracket: 5 }, + { name: '§aYog', cap: 4000, mobs: ['yog_100'], bracket: 3 } + ] + }, + foraging_1: { + name: 'The Park', + mobs: [ + { name: '§bHowling Spirit', cap: 10000, mobs: ['howling_spirit_35'], bracket: 2 }, + { name: '§bPack Spirit', cap: 10000, mobs: ['pack_spirit_30'], bracket: 2 }, + { name: '§bSoul of the Alpha', cap: 1000, mobs: ['soul_of_the_alpha_55'], bracket: 4 } + ] + }, + foraging_2: { + name: 'Galatea', + mobs: [ + { name: '§aBogged', cap: 3000, mobs: ['bogged_10'], bracket: 4 }, + { name: '§aChill', cap: 1000, mobs: ['chillblade_31', 'chillshot_31'], bracket: 4 }, + { name: '§aEnt', cap: 1000, mobs: ['ent_14'], bracket: 4 }, + { name: '§aStridersurfer', cap: 1000, mobs: ['strider_20', 'strider_21'], bracket: 4 }, + { name: '§aTadgang', cap: 1000, mobs: ['tadgang_frog_8', 'tadgang_frog_10'], bracket: 4 }, + { name: '§aThe Loch Emperor', cap: 400, mobs: ['skeleton_emperor_150', 'guardian_emperor_150'], bracket: 5 }, + { name: '§aTidetot', cap: 1000, mobs: ['tidetot_10', 'seacurse_15', 'hydrospear_25'], bracket: 4 } + ] + }, + spooky_festival: { + name: 'Spooky Festival', + mobs: [ + { name: '§8Crazy Witch', cap: 750, mobs: ['batty_witch_60'], bracket: 2 }, + { name: '§6Headless Horseman', cap: 500, mobs: ['horseman_horse_100'], bracket: 7 }, + { name: '§cPhantom Spirit', cap: 750, mobs: ['phantom_spirit_35'], bracket: 2 }, + { name: '§6Scary Jerry', cap: 750, mobs: ['scary_jerry_30'], bracket: 2 }, + { name: '§eTrick or Treater', cap: 750, mobs: ['trick_or_treater_30'], bracket: 2 }, + { name: '§6Wither Gourd', cap: 750, mobs: ['wither_gourd_40'], bracket: 2 }, + { name: '§8Wraith', cap: 750, mobs: ['wraith_50'], bracket: 2 } + ] + }, + mythological_creatures: { + name: 'Mythological Creatures', + mobs: [ + { name: '§aGaia Construct', cap: 3000, mobs: ['gaia_construct_140', 'gaia_construct_260'], bracket: 4 }, + { name: '§aMinos Champion', cap: 1000, mobs: ['minos_champion_175', 'minos_champion_310'], bracket: 5 }, + { + name: '§aMinos Hunter', + cap: 1000, + mobs: ['minos_hunter_125', 'minos_hunter_15', 'minos_hunter_60'], + bracket: 5 + }, + { name: '§aMinos Inquisitor', cap: 500, mobs: ['minos_inquisitor_750'], bracket: 7 }, + { name: '§aMinotaur', cap: 3000, mobs: ['minotaur_45', 'minotaur_120', 'minotaur_210'], bracket: 4 }, + { + name: '§aSiamese Lynx', + cap: 3000, + mobs: ['siamese_lynx_25', 'siamese_lynx_85', 'siamese_lynx_155'], + bracket: 4 + } + ] + }, + jerry: { + name: 'Jerry', + mobs: [ + { name: '§9Blue Jerry', cap: 30, mobs: ['mayor_jerry_blue_2'], bracket: 5 }, + { name: '§6Golden Jerry', cap: 20, mobs: ['mayor_jerry_golden_5'], bracket: 7 }, + { name: '§aGreen Jerry', cap: 75, mobs: ['mayor_jerry_green_1'], bracket: 4 }, + { name: '§5Purple Jerry', cap: 25, mobs: ['mayor_jerry_purple_3'], bracket: 6 } + ] + }, + kuudra: { + name: 'Kuudra', + mobs: [ + { + name: '§aBlazing Golem', + cap: 300, + mobs: ['blazing_golem_100', 'blazing_golem_200', 'blazing_golem_300', 'blazing_golem_400', 'blazing_golem_500'], + bracket: 3 + }, + { + name: '§aBlight', + cap: 10000, + mobs: ['blight_100', 'blight_200', 'blight_300', 'blight_400', 'blight_500'], + bracket: 3 + }, + { + name: '§aDropship', + cap: 300, + mobs: ['dropship_100', 'dropship_200', 'dropship_300', 'dropship_400', 'dropship_500'], + bracket: 3 + }, + { + name: '§aExplosive Imp', + cap: 3000, + mobs: ['explosive_imp_100', 'explosive_imp_200', 'explosive_imp_300', 'explosive_imp_400', 'explosive_imp_500'], + bracket: 4 + }, + { + name: '§aInferno Magma Cube', + cap: 10000, + mobs: [ + 'inferno_magma_cube_100', + 'inferno_magma_cube_200', + 'inferno_magma_cube_300', + 'inferno_magma_cube_400', + 'inferno_magma_cube_500' + ], + bracket: 3 + }, + { + name: '§aKuudra Berserker', + cap: 10000, + mobs: [ + 'kuudra_berserker_100', + 'kuudra_berserker_200', + 'kuudra_berserker_300', + 'kuudra_berserker_400', + 'kuudra_berserker_500' + ], + bracket: 3 + }, + { + name: '§aKuudra Follower', + cap: 25000, + mobs: [ + 'kuudra_follower_100', + 'kuudra_follower_200', + 'kuudra_follower_300', + 'kuudra_follower_400', + 'kuudra_follower_500' + ], + bracket: 2 + }, + { + name: '§aKuudra Knocker', + cap: 10000, + mobs: [ + 'kuudra_knocker_100', + 'kuudra_knocker_200', + 'kuudra_knocker_300', + 'kuudra_knocker_400', + 'kuudra_knocker_500' + ], + bracket: 3 + }, + { + name: '§aKuudra Landmine', + cap: 10000, + mobs: [ + 'kuudra_landmine_100', + 'kuudra_landmine_200', + 'kuudra_landmine_300', + 'kuudra_landmine_400', + 'kuudra_landmine_500' + ], + bracket: 3 + }, + { + name: '§aKuudra Slasher', + cap: 30, + mobs: [ + 'kuudra_slasher_100', + 'kuudra_slasher_200', + 'kuudra_slasher_300', + 'kuudra_slasher_400', + 'kuudra_slasher_500' + ], + bracket: 5 + }, + { + name: '§aMagma Follower', + cap: 30, + mobs: [ + 'magma_follower_100', + 'magma_follower_200', + 'magma_follower_300', + 'magma_follower_400', + 'magma_follower_500' + ], + bracket: 5 + }, + { + name: '§aWandering Blaze', + cap: 3000, + mobs: [ + 'wandering_blaze_100', + 'wandering_blaze_200', + 'wandering_blaze_300', + 'wandering_blaze_400', + 'wandering_blaze_500' + ], + bracket: 4 + }, + { + name: '§aWither Sentry', + cap: 75, + mobs: ['wither_sentry_100', 'wither_sentry_200', 'wither_sentry_300', 'wither_sentry_400', 'wither_sentry_500'], + bracket: 4 + } + ] + }, + fishing: { + name: 'Fishing', + mobs: [ + { name: '§aAbyssal Miner', cap: 250, mobs: ['zombie_miner_150'], bracket: 6 }, + { name: '§aAgarimoo', cap: 4000, mobs: ['agarimoo_35'], bracket: 3 }, + { name: '§aBlue Ringed Octopus', cap: 400, mobs: ['blue_ringed_octopus_275'], bracket: 5 }, + { name: '§aCarrot King', cap: 400, mobs: ['carrot_king_25'], bracket: 5 }, + { name: '§aCatfish', cap: 1000, mobs: ['catfish_23'], bracket: 4 }, + { name: '§aDeep Sea Protector', cap: 1000, mobs: ['deep_sea_protector_60'], bracket: 4 }, + { name: '§aFrog Man', cap: 3000, mobs: ['frog_man_10'], bracket: 4 }, + { name: '§aGuardian Defender', cap: 1000, mobs: ['guardian_defender_45'], bracket: 4 }, + { + name: '§aMithril Grubber', + cap: 300, + mobs: [ + 'small_mithril_grubber_15', + 'medium_mithril_grubber_15', + 'large_mithril_grubber_15', + 'bloated_mithril_grubber_15' + ], + bracket: 3 + }, + { name: '§aNight Squid', cap: 1000, mobs: ['night_squid_6'], bracket: 4 }, + { name: '§aOasis Rabbit', cap: 300, mobs: ['oasis_rabbit_10'], bracket: 3 }, + { name: '§aOasis Sheep', cap: 300, mobs: ['oasis_sheep_10'], bracket: 3 }, + { name: '§aPoisoned Water Worm', cap: 1000, mobs: ['poisoned_water_worm_25'], bracket: 4 }, + { name: '§aRider of the Deep', cap: 4000, mobs: ['zombie_deep_20', 'chicken_deep_20'], bracket: 3 }, + { name: '§aSea Archer', cap: 4000, mobs: ['sea_archer_15'], bracket: 3 }, + { name: '§aSea Guardian', cap: 4000, mobs: ['sea_guardian_10'], bracket: 3 }, + { name: '§aSea Leech', cap: 1000, mobs: ['sea_leech_30'], bracket: 4 }, + { name: '§aSea Walker', cap: 4000, mobs: ['sea_walker_4'], bracket: 3 }, + { name: '§aSea Witch', cap: 4000, mobs: ['sea_witch_15'], bracket: 3 }, + { name: '§aSnapping Turtle', cap: 1000, mobs: ['snapping_turtle_30'], bracket: 4 }, + { name: '§aSquid', cap: 10000, mobs: ['pond_squid_1'], bracket: 2 }, + { name: '§aWater Hydra', cap: 400, mobs: ['water_hydra_100'], bracket: 5 }, + { name: '§aWater Worm', cap: 1000, mobs: ['water_worm_20'], bracket: 4 }, + { name: '§aWetwing', cap: 1000, mobs: ['wetwing_chicken_18'], bracket: 4 }, + { name: '§aWiki Tiki', cap: 100, mobs: ['wiki_tiki_400'], bracket: 7 } + ] + }, + lava: { + name: 'Lava', + mobs: [ + { name: '§aFiery Scuttler', cap: 400, mobs: ['fiery_scuttler_475'], bracket: 5 }, + { name: '§aFire Eel', cap: 1000, mobs: ['fire_eel_240'], bracket: 4 }, + { name: '§aFireproof Witch', cap: 1000, mobs: ['fireproof_witch_75'], bracket: 4 }, + { name: '§aFlaming Worm', cap: 4000, mobs: ['flaming_worm_50'], bracket: 3 }, + { name: '§aFried Chicken', cap: 3000, mobs: ['fried_chicken_30'], bracket: 4 }, + { name: '§aLava Blaze', cap: 1000, mobs: ['lava_blaze_100'], bracket: 4 }, + { name: '§aLava Flame', cap: 1000, mobs: ['lava_flame_230'], bracket: 4 }, + { name: '§aLava Leech', cap: 4000, mobs: ['lava_leech_220'], bracket: 3 }, + { name: '§aLava Pigman', cap: 1000, mobs: ['lava_pigman_100'], bracket: 4 }, + { name: '§aLord Jawbus', cap: 100, mobs: ['lord_jawbus_600'], bracket: 7 }, + { name: '§aMagma Slug', cap: 10000, mobs: ['magma_slug_200'], bracket: 2 }, + { name: '§aMoogma', cap: 4000, mobs: ['moogma_210'], bracket: 3 }, + { name: '§aPlhlegblast', cap: 7, mobs: ['pond_squid_300'], bracket: 7 }, + { name: '§aPyroclastic Worm', cap: 1000, mobs: ['pyroclastic_worm_240'], bracket: 4 }, + { name: '§aRagnarok', cap: 100, mobs: ['ragnarok_666'], bracket: 7 }, + { name: '§aTaurus', cap: 1000, mobs: ['pig_rider_250'], bracket: 4 }, + { name: '§aThunder', cap: 400, mobs: ['thunder_400'], bracket: 5 } + ] + }, + spooky_festival_fishing: { + name: 'Spooky Festival Fishing', + mobs: [ + { name: '§aGrim Reaper', cap: 100, mobs: ['grim_reaper_190'], bracket: 7 }, + { name: '§aNightmare', cap: 1000, mobs: ['nightmare_24'], bracket: 4 }, + { name: '§aPhantom Fisher', cap: 250, mobs: ['phantom_fisherman_160'], bracket: 6 }, + { name: '§aScarecrow', cap: 4000, mobs: ['scarecrow_9'], bracket: 3 }, + { name: '§aWerewolf', cap: 1000, mobs: ['werewolf_50'], bracket: 4 } + ] + }, + fishing_festival: { + name: 'Fishing Festival', + mobs: [ + { name: '§aBlue Shark', cap: 1000, mobs: ['blue_shark_20'], bracket: 4 }, + { name: '§aGreat White Shark', cap: 400, mobs: ['great_white_shark_180'], bracket: 5 }, + { name: '§aNurse Shark', cap: 4000, mobs: ['nurse_shark_6'], bracket: 3 }, + { name: '§aTiger Shark', cap: 1000, mobs: ['tiger_shark_50'], bracket: 4 } + ] + }, + winter: { + name: 'Winter', + mobs: [ + { name: '§aFrosty', cap: 4000, mobs: ['frosty_the_snowman_13'], bracket: 3 }, + { name: '§aFrozen Steve', cap: 4000, mobs: ['frozen_steve_7'], bracket: 3 }, + { name: '§aGrinch', cap: 250, mobs: ['grinch_21'], bracket: 6 }, + { name: '§aNutcracker', cap: 400, mobs: ['nutcracker_50'], bracket: 5 }, + { name: '§aReindrake', cap: 100, mobs: ['reindrake_100'], bracket: 7 }, + { name: '§aYeti', cap: 250, mobs: ['yeti_175'], bracket: 6 } + ] + }, + backwater_bayou: { + name: 'Backwater Bayou', + mobs: [ + { name: '§aAlligator', cap: 400, mobs: ['alligator_120'], bracket: 5 }, + { name: '§aBanshee', cap: 1000, mobs: ['banshee_10'], bracket: 4 }, + { name: '§aBayou Sludge', cap: 1000, mobs: ['bayou_sludge_25'], bracket: 4 }, + { name: '§aDumpster Diver', cap: 1000, mobs: ['dumpster_diver_15'], bracket: 4 }, + { name: '§aTitanoboa', cap: 100, mobs: ['titanoboa_240'], bracket: 7 }, + { name: '§aTrash Gobbler', cap: 1000, mobs: ['trash_gobbler_8'], bracket: 4 } + ] + }, + catacombs: { + name: 'Catacombs', + mobs: [ + { + name: '§a§d§lAngry Archaeologist', + cap: 3000, + mobs: [ + 'diamond_guy_80', + 'diamond_guy_90', + 'diamond_guy_100', + 'diamond_guy_110', + 'diamond_guy_120', + 'diamond_guy_130', + 'diamond_guy_140', + 'diamond_guy_150', + 'diamond_guy_160', + 'diamond_guy_170', + 'master_diamond_guy_80', + 'master_diamond_guy_90', + 'master_diamond_guy_100', + 'master_diamond_guy_110', + 'master_diamond_guy_120', + 'master_diamond_guy_130', + 'master_diamond_guy_140', + 'master_diamond_guy_150', + 'master_diamond_guy_160', + 'master_diamond_guy_170' + ], + bracket: 7 + }, + { name: '§aBat', cap: 1000, mobs: ['dungeon_secret_bat_1'], bracket: 4 }, + { + name: '§aCellar Spider', + cap: 1000, + mobs: [ + 'cellar_spider_45', + 'cellar_spider_65', + 'cellar_spider_75', + 'cellar_spider_85', + 'cellar_spider_95', + 'cellar_spider_105', + 'cellar_spider_115', + 'cellar_spider_125', + 'master_cellar_spider_45', + 'master_cellar_spider_65', + 'master_cellar_spider_75', + 'master_cellar_spider_85', + 'master_cellar_spider_95', + 'master_cellar_spider_105', + 'master_cellar_spider_115', + 'master_cellar_spider_125' + ], + bracket: 4 + }, + { + name: '§aLonely Spider', + cap: 25000, + mobs: [ + 'lonely_spider_35', + 'lonely_spider_55', + 'lonely_spider_65', + 'lonely_spider_75', + 'lonely_spider_85', + 'lonely_spider_95', + 'lonely_spider_105', + 'lonely_spider_115', + 'master_lonely_spider_35', + 'master_lonely_spider_55', + 'master_lonely_spider_65', + 'master_lonely_spider_75', + 'master_lonely_spider_85', + 'master_lonely_spider_95', + 'master_lonely_spider_105', + 'master_lonely_spider_115' + ], + bracket: 4 + }, + { + name: '§aCrypt Dreadlord', + cap: 25000, + mobs: [ + 'crypt_dreadlord_47', + 'crypt_dreadlord_67', + 'crypt_dreadlord_77', + 'crypt_dreadlord_87', + 'crypt_dreadlord_97', + 'crypt_dreadlord_107', + 'crypt_dreadlord_117', + 'crypt_dreadlord_127', + 'master_crypt_dreadlord_47', + 'master_crypt_dreadlord_67', + 'master_crypt_dreadlord_77', + 'master_crypt_dreadlord_87', + 'master_crypt_dreadlord_97', + 'master_crypt_dreadlord_107', + 'master_crypt_dreadlord_117', + 'master_crypt_dreadlord_127' + ], + bracket: 4 + }, + { + name: '§aCrypt Lurker', + cap: 25000, + mobs: [ + 'crypt_lurker_41', + 'crypt_lurker_61', + 'crypt_lurker_71', + 'crypt_lurker_81', + 'crypt_lurker_91', + 'crypt_lurker_101', + 'crypt_lurker_111', + 'crypt_lurker_121', + 'master_crypt_lurker_41', + 'master_crypt_lurker_61', + 'master_crypt_lurker_71', + 'master_crypt_lurker_81', + 'master_crypt_lurker_91', + 'master_crypt_lurker_101', + 'master_crypt_lurker_111', + 'master_crypt_lurker_121' + ], + bracket: 4 + }, + { + name: '§aCrypt Souleater', + cap: 25000, + mobs: [ + 'crypt_souleater_45', + 'crypt_souleater_65', + 'crypt_souleater_75', + 'crypt_souleater_85', + 'crypt_souleater_95', + 'crypt_souleater_105', + 'crypt_souleater_115', + 'crypt_souleater_125', + 'master_crypt_souleater_45', + 'master_crypt_souleater_65', + 'master_crypt_souleater_75', + 'master_crypt_souleater_85', + 'master_crypt_souleater_95', + 'master_crypt_souleater_105', + 'master_crypt_souleater_115', + 'master_crypt_souleater_125' + ], + bracket: 4 + }, + { + name: '§aFels', + cap: 10000, + mobs: [ + 'tentaclees_90', + 'tentaclees_100', + 'tentaclees_110', + 'master_tentaclees_90', + 'master_tentaclees_100', + 'master_tentaclees_110' + ], + bracket: 5 + }, + { name: '§aGolem', cap: 1000, mobs: ['sadan_golem_1', 'master_sadan_golem_1'], bracket: 4 }, + { + name: '§a§d§lKing Midas', + cap: 750, + mobs: [ + 'king_midas_130', + 'king_midas_140', + 'king_midas_150', + 'king_midas_160', + 'king_midas_170', + 'master_king_midas_130', + 'master_king_midas_140', + 'master_king_midas_150', + 'master_king_midas_160', + 'master_king_midas_170' + ], + bracket: 6 + }, + { + name: '§a§d§lLost Adventurer', + cap: 3000, + mobs: [ + 'lost_adventurer_80', + 'lost_adventurer_81', + 'lost_adventurer_82', + 'lost_adventurer_83', + 'lost_adventurer_85', + 'lost_adventurer_86', + 'lost_adventurer_87', + 'lost_adventurer_88', + 'lost_adventurer_90', + 'lost_adventurer_91', + 'lost_adventurer_92', + 'lost_adventurer_93', + 'lost_adventurer_100', + 'lost_adventurer_101', + 'lost_adventurer_102', + 'lost_adventurer_103', + 'lost_adventurer_110', + 'lost_adventurer_111', + 'lost_adventurer_112', + 'lost_adventurer_113', + 'lost_adventurer_120', + 'lost_adventurer_121', + 'lost_adventurer_122', + 'lost_adventurer_123', + 'lost_adventurer_130', + 'lost_adventurer_131', + 'lost_adventurer_132', + 'lost_adventurer_133', + 'lost_adventurer_134', + 'lost_adventurer_135', + 'lost_adventurer_140', + 'lost_adventurer_141', + 'lost_adventurer_142', + 'lost_adventurer_143', + 'lost_adventurer_144', + 'lost_adventurer_150', + 'lost_adventurer_151', + 'lost_adventurer_152', + 'lost_adventurer_153', + 'lost_adventurer_154', + 'lost_adventurer_160', + 'lost_adventurer_161', + 'lost_adventurer_162', + 'lost_adventurer_163', + 'lost_adventurer_164', + 'master_lost_adventurer_80', + 'master_lost_adventurer_81', + 'master_lost_adventurer_82', + 'master_lost_adventurer_83', + 'master_lost_adventurer_85', + 'master_lost_adventurer_86', + 'master_lost_adventurer_87', + 'master_lost_adventurer_88', + 'master_lost_adventurer_90', + 'master_lost_adventurer_91', + 'master_lost_adventurer_92', + 'master_lost_adventurer_93', + 'master_lost_adventurer_100', + 'master_lost_adventurer_101', + 'master_lost_adventurer_102', + 'master_lost_adventurer_103', + 'master_lost_adventurer_110', + 'master_lost_adventurer_111', + 'master_lost_adventurer_112', + 'master_lost_adventurer_113', + 'master_lost_adventurer_120', + 'master_lost_adventurer_121', + 'master_lost_adventurer_122', + 'master_lost_adventurer_123', + 'master_lost_adventurer_130', + 'master_lost_adventurer_131', + 'master_lost_adventurer_132', + 'master_lost_adventurer_133', + 'master_lost_adventurer_134', + 'master_lost_adventurer_135', + 'master_lost_adventurer_140', + 'master_lost_adventurer_141', + 'master_lost_adventurer_142', + 'master_lost_adventurer_143', + 'master_lost_adventurer_144', + 'master_lost_adventurer_150', + 'master_lost_adventurer_151', + 'master_lost_adventurer_152', + 'master_lost_adventurer_153', + 'master_lost_adventurer_154', + 'master_lost_adventurer_160', + 'master_lost_adventurer_161', + 'master_lost_adventurer_162', + 'master_lost_adventurer_163', + 'master_lost_adventurer_164' + ], + bracket: 7 + }, + { + name: '§aMimic', + cap: 1000, + mobs: ['mimic_115', 'mimic_125', 'master_mimic_115', 'master_mimic_125'], + bracket: 4 + }, + { + name: '§aScared Skeleton', + cap: 4000, + mobs: [ + 'scared_skeleton_42', + 'scared_skeleton_62', + 'scared_skeleton_72', + 'master_scared_skeleton_42', + 'master_scared_skeleton_62', + 'master_scared_skeleton_72' + ], + bracket: 3 + }, + { + name: '§a§d§lShadow Assassin', + cap: 3000, + mobs: [ + 'shadow_assassin_120', + 'shadow_assassin_130', + 'shadow_assassin_140', + 'shadow_assassin_150', + 'shadow_assassin_160', + 'shadow_assassin_170', + 'shadow_assassin_171', + 'master_shadow_assassin_120', + 'master_shadow_assassin_130', + 'master_shadow_assassin_140', + 'master_shadow_assassin_150', + 'master_shadow_assassin_160', + 'master_shadow_assassin_170', + 'master_shadow_assassin_171' + ], + bracket: 7 + }, + { + name: '§aSkeleton Grunt', + cap: 4000, + mobs: [ + 'skeleton_grunt_40', + 'skeleton_grunt_60', + 'skeleton_grunt_70', + 'skeleton_grunt_80', + 'master_skeleton_grunt_40', + 'master_skeleton_grunt_60', + 'master_skeleton_grunt_70', + 'master_skeleton_grunt_80' + ], + bracket: 3 + }, + { name: '§aSkeleton Lord', cap: 1000, mobs: ['skeleton_lord_150', 'master_skeleton_lord_150'], bracket: 5 }, + { + name: '§aSkeleton Master', + cap: 25000, + mobs: [ + 'skeleton_master_48', + 'skeleton_master_68', + 'skeleton_master_78', + 'skeleton_master_88', + 'skeleton_master_98', + 'skeleton_master_108', + 'skeleton_master_118', + 'skeleton_master_128', + 'master_skeleton_master_48', + 'master_skeleton_master_68', + 'master_skeleton_master_78', + 'master_skeleton_master_88', + 'master_skeleton_master_98', + 'master_skeleton_master_108', + 'master_skeleton_master_118', + 'master_skeleton_master_128' + ], + bracket: 4 + }, + { + name: '§aSkeleton Soldier', + cap: 40000, + mobs: [ + 'skeleton_soldier_46', + 'skeleton_soldier_66', + 'skeleton_soldier_76', + 'skeleton_soldier_86', + 'skeleton_soldier_96', + 'skeleton_soldier_106', + 'skeleton_soldier_116', + 'skeleton_soldier_126', + 'master_skeleton_soldier_46', + 'master_skeleton_soldier_66', + 'master_skeleton_soldier_76', + 'master_skeleton_soldier_86', + 'master_skeleton_soldier_96', + 'master_skeleton_soldier_106', + 'master_skeleton_soldier_116', + 'master_skeleton_soldier_126' + ], + bracket: 1 + }, + { + name: '§aSkeletor', + cap: 10000, + mobs: [ + 'skeletor_80', + 'skeletor_90', + 'skeletor_100', + 'skeletor_101', + 'skeletor_110', + 'skeletor_120', + 'skeletor_prime_100', + 'skeletor_prime_110', + 'skeletor_prime_120', + 'master_skeletor_80', + 'master_skeletor_90', + 'master_skeletor_100', + 'master_skeletor_101', + 'master_skeletor_110', + 'master_skeletor_120', + 'master_skeletor_prime_100', + 'master_skeletor_prime_110', + 'master_skeletor_prime_120' + ], + bracket: 5 + }, + { + name: '§aSniper', + cap: 4000, + mobs: [ + 'sniper_skeleton_43', + 'sniper_skeleton_63', + 'sniper_skeleton_73', + 'sniper_skeleton_83', + 'sniper_skeleton_93', + 'sniper_skeleton_103', + 'sniper_skeleton_113', + 'sniper_skeleton_123', + 'master_sniper_skeleton_43', + 'master_sniper_skeleton_63', + 'master_sniper_skeleton_73', + 'master_sniper_skeleton_83', + 'master_sniper_skeleton_93', + 'master_sniper_skeleton_103', + 'master_sniper_skeleton_113', + 'master_sniper_skeleton_123' + ], + bracket: 3 + }, + { + name: '§aSuper Archer', + cap: 10000, + mobs: [ + 'super_archer_90', + 'super_archer_100', + 'super_archer_110', + 'super_archer_120', + 'master_super_archer_90', + 'master_super_archer_100', + 'master_super_archer_110', + 'master_super_archer_120' + ], + bracket: 5 + }, + { + name: '§aSuper Tank Zombie', + cap: 25000, + mobs: [ + 'super_tank_zombie_90', + 'super_tank_zombie_100', + 'super_tank_zombie_110', + 'super_tank_zombie_120', + 'master_super_tank_zombie_90', + 'master_super_tank_zombie_100', + 'master_super_tank_zombie_110', + 'master_super_tank_zombie_120' + ], + bracket: 4 + }, + { + name: '§aTank Zombie', + cap: 4000, + mobs: [ + 'crypt_tank_zombie_40', + 'crypt_tank_zombie_60', + 'crypt_tank_zombie_70', + 'crypt_tank_zombie_80', + 'crypt_tank_zombie_90', + 'master_crypt_tank_zombie_40', + 'master_crypt_tank_zombie_60', + 'master_crypt_tank_zombie_70', + 'master_crypt_tank_zombie_80', + 'master_crypt_tank_zombie_90' + ], + bracket: 3 + }, + { name: '§aTerracotta', cap: 40000, mobs: ['sadan_statue_1', 'master_sadan_statue_1'], bracket: 1 }, + { + name: '§a§4§lUndead', + cap: 10000, + mobs: [ + 'watcher_summon_undead_1', + 'watcher_summon_undead_2', + 'watcher_summon_undead_3', + 'watcher_summon_undead_4', + 'watcher_summon_undead_5', + 'watcher_summon_undead_6', + 'watcher_summon_undead_7', + 'watcher_summon_undead_8', + 'master_watcher_summon_undead_1', + 'master_watcher_summon_undead_2', + 'master_watcher_summon_undead_3', + 'master_watcher_summon_undead_4', + 'master_watcher_summon_undead_5', + 'master_watcher_summon_undead_6', + 'master_watcher_summon_undead_7', + 'master_watcher_summon_undead_8' + ], + bracket: 2 + }, + { + name: '§aUndead Skeleton', + cap: 25000, + mobs: [ + 'dungeon_respawning_skeleton_40', + 'dungeon_respawning_skeleton_skull_40', + 'dungeon_respawning_skeleton_60', + 'dungeon_respawning_skeleton_70', + 'dungeon_respawning_skeleton_80', + 'dungeon_respawning_skeleton_90', + 'dungeon_respawning_skeleton_100', + 'dungeon_respawning_skeleton_110', + 'dungeon_respawning_skeleton_120', + 'master_dungeon_respawning_skeleton_40', + 'master_dungeon_respawning_skeleton_60', + 'master_dungeon_respawning_skeleton_70', + 'master_dungeon_respawning_skeleton_80', + 'master_dungeon_respawning_skeleton_90', + 'master_dungeon_respawning_skeleton_100', + 'master_dungeon_respawning_skeleton_110', + 'master_dungeon_respawning_skeleton_120' + ], + bracket: 4 + }, + { name: '§aWither Guard', cap: 10000, mobs: ['wither_guard_100', 'master_wither_guard_100'], bracket: 5 }, + { name: '§aWither Husk', cap: 10000, mobs: ['master_wither_husk_100'], bracket: 5 }, + { name: '§aWither Miner', cap: 25000, mobs: ['wither_miner_100', 'master_wither_miner_100'], bracket: 4 }, + { + name: '§aWithermancer', + cap: 25000, + mobs: [ + 'crypt_witherskeleton_90', + 'crypt_witherskeleton_100', + 'crypt_witherskeleton_110', + 'crypt_witherskeleton_120', + 'master_crypt_witherskeleton_90', + 'master_crypt_witherskeleton_100', + 'master_crypt_witherskeleton_110', + 'master_crypt_witherskeleton_120' + ], + bracket: 4 + }, + { + name: '§aZombie Commander', + cap: 3000, + mobs: [ + 'zombie_commander_110', + 'zombie_commander_120', + 'master_zombie_commander_110', + 'master_zombie_commander_120' + ], + bracket: 4 + }, + { + name: '§aZombie Grunt', + cap: 4000, + mobs: [ + 'zombie_grunt_40', + 'zombie_grunt_60', + 'zombie_grunt_70', + 'zombie_grunt_80', + 'master_zombie_grunt_40', + 'master_zombie_grunt_60', + 'master_zombie_grunt_70', + 'master_zombie_grunt_80' + ], + bracket: 3 + }, + { + name: '§aZombie Knight', + cap: 10000, + mobs: [ + 'zombie_knight_86', + 'zombie_knight_96', + 'zombie_knight_106', + 'zombie_knight_116', + 'zombie_knight_126', + 'master_zombie_knight_86', + 'master_zombie_knight_96', + 'master_zombie_knight_106', + 'master_zombie_knight_116', + 'master_zombie_knight_126' + ], + bracket: 5 + }, + { name: '§aZombie Lord', cap: 1000, mobs: ['zombie_lord_150', 'master_zombie_lord_150'], bracket: 5 }, + { + name: '§aZombie Soldier', + cap: 40000, + mobs: [ + 'zombie_soldier_83', + 'zombie_soldier_93', + 'zombie_soldier_103', + 'zombie_soldier_113', + 'zombie_soldier_123', + 'master_zombie_soldier_83', + 'master_zombie_soldier_93', + 'master_zombie_soldier_103', + 'master_zombie_soldier_113', + 'master_zombie_soldier_123' + ], + bracket: 1 + } + ] + }, + garden: { + name: 'Garden', + mobs: [ + { name: '§aBeetle', cap: 250, mobs: ['pest_beetle_1'], bracket: 6 }, + { name: '§aCricket', cap: 250, mobs: ['pest_cricket_1'], bracket: 6 }, + { name: '§aEarthworm', cap: 250, mobs: ['pest_worm_1'], bracket: 6 }, + { name: '§aField Mouse', cap: 100, mobs: ['pest_mouse_1'], bracket: 7 }, + { name: '§aFly', cap: 250, mobs: ['pest_fly_1'], bracket: 6 }, + { name: '§aLocust', cap: 250, mobs: ['pest_locust_1'], bracket: 6 }, + { name: '§aMite', cap: 250, mobs: ['pest_mite_1'], bracket: 6 }, + { name: '§aMosquito', cap: 250, mobs: ['pest_mosquito_1'], bracket: 6 }, + { name: '§aMoth', cap: 250, mobs: ['pest_moth_1'], bracket: 6 }, + { name: '§aRat', cap: 250, mobs: ['pest_rat_1'], bracket: 6 }, + { name: '§aSlug', cap: 250, mobs: ['pest_slug_1'], bracket: 6 } + ] + } +}; + +export const BuildBattleTitleRequirements: { title: BuildBattleTitle; requirement: number }[] = [ + { title: 'Rookie', requirement: 0 }, + { title: 'Untrained', requirement: 100 }, + { title: 'Amatuer', requirement: 250 }, + { title: 'Prospect', requirement: 550 }, + { title: 'Apprentice', requirement: 1000 }, + { title: 'Experienced', requirement: 2000 }, + { title: 'Seasoned', requirement: 3500 }, + { title: 'Trained', requirement: 5000 }, + { title: 'Skilled', requirement: 7500 }, + { title: 'Talented', requirement: 10000 }, + { title: 'Professional', requirement: 15000 }, + { title: 'Artisan', requirement: 20000 }, + { title: 'Expert', requirement: 30000 }, + { title: 'Master', requirement: 50000 }, + { title: 'Legend', requirement: 100000 }, + { title: 'Grandmaster', requirement: 200000 }, + { title: 'Celestial', requirement: 300000 }, + { title: 'Divine', requirement: 400000 }, + { title: 'Ascended', requirement: 500000 } +]; + +export const BedWarsPrestiges: { prestige: BedWarsPrestige; requirement: number }[] = [ + { prestige: 'Stone', requirement: 0 }, + { prestige: 'Iron', requirement: 100 }, + { prestige: 'Gold', requirement: 200 }, + { prestige: 'Diamond', requirement: 300 }, + { prestige: 'Emerald', requirement: 400 }, + { prestige: 'Sapphire', requirement: 500 }, + { prestige: 'Ruby', requirement: 600 }, + { prestige: 'Crystal', requirement: 700 }, + { prestige: 'Opal', requirement: 800 }, + { prestige: 'Amethyst', requirement: 900 }, + { prestige: 'Rainbow', requirement: 1000 }, + { prestige: 'Iron', requirement: 1100 }, + { prestige: 'Gold', requirement: 1200 }, + { prestige: 'Diamond', requirement: 1300 }, + { prestige: 'Emerald', requirement: 1400 }, + { prestige: 'Sapphire', requirement: 1500 }, + { prestige: 'Ruby', requirement: 1600 }, + { prestige: 'Crystal', requirement: 1700 }, + { prestige: 'Opal', requirement: 1800 }, + { prestige: 'Amethyst', requirement: 1900 }, + { prestige: 'Mirror', requirement: 2000 }, + { prestige: 'Light', requirement: 2100 }, + { prestige: 'Dawn', requirement: 2200 }, + { prestige: 'Dusk', requirement: 2300 }, + { prestige: 'Air', requirement: 2400 }, + { prestige: 'Wind', requirement: 2500 }, + { prestige: 'Nebula', requirement: 2600 }, + { prestige: 'Thunder', requirement: 2700 }, + { prestige: 'Earth', requirement: 2800 }, + { prestige: 'Water', requirement: 2900 }, + { prestige: 'Fire', requirement: 3000 }, + { prestige: 'Sunrise', requirement: 3100 }, + { prestige: 'Eclipse', requirement: 3200 }, + { prestige: 'Gamma', requirement: 3300 }, + { prestige: 'Majestic', requirement: 3400 }, + { prestige: 'Andesine', requirement: 3500 }, + { prestige: 'Marine', requirement: 3600 }, + { prestige: 'Element', requirement: 3700 }, + { prestige: 'Galaxy', requirement: 3800 }, + { prestige: 'Atomic', requirement: 3900 }, + { prestige: 'Sunset', requirement: 4000 }, + { prestige: 'Time', requirement: 4100 }, + { prestige: 'Winter', requirement: 4200 }, + { prestige: 'Obsidian', requirement: 4300 }, + { prestige: 'Spring', requirement: 4400 }, + { prestige: 'Ice', requirement: 4500 }, + { prestige: 'Summer', requirement: 4600 }, + { prestige: 'Spinel', requirement: 4700 }, + { prestige: 'Autumn', requirement: 4800 }, + { prestige: 'Mystic', requirement: 4900 }, + { prestige: 'Eternal', requirement: 5000 } +]; + +// Credit: https://github.com/Statsify/statsify/blob/main/packages/schemas/src/player/gamemodes/skywars/util.ts#L12-L25 +export const SKYWARS_XP_TO_NEXT_LEVEL = [ + 0, 10, 25, 50, 75, 100, 250, 500, 750, 1000, 1250, 1500, 1750, 2000, 2500, 3000, 3500, 4000, 4500 +]; + +export const SKYWARS_TOTAL_XP = SKYWARS_XP_TO_NEXT_LEVEL.map((_, index) => + SKYWARS_XP_TO_NEXT_LEVEL.slice(0, index + 1).reduce((acc, xp) => acc + xp, 0) +); + +export const SKYWARS_CONSTANT_LEVELING_XP = SKYWARS_XP_TO_NEXT_LEVEL.reduce((acc, xp) => acc + xp, 0); +export const SKYWARS_CONSTANT_XP_TO_NEXT_LEVEL = 5000; +export const SKYWARS_LEVEL_MAX = 10_000; diff --git a/src/Utils/Divide.test.ts b/src/Utils/Divide.test.ts new file mode 100644 index 000000000..23e4cca6a --- /dev/null +++ b/src/Utils/Divide.test.ts @@ -0,0 +1,13 @@ +import Divide from './Divide.js'; +import { expect, expectTypeOf, test } from 'vitest'; + +test('Divide', () => { + expect(Divide(10, 2)).toBe(5); + expectTypeOf(Divide(10, 2)).toBeNumber(); + expect(Divide(10, 0)).toBe(10); + expectTypeOf(Divide(10, 0)).toBeNumber(); + expect(Divide(0, 0)).toBe(0); + expectTypeOf(Divide(0, 0)).toBeNumber(); + expect(Divide(-5, 10)).toBe(-0.5); + expectTypeOf(Divide(-5, 10)).toBeNumber(); +}); diff --git a/src/Utils/Divide.ts b/src/Utils/Divide.ts new file mode 100644 index 000000000..e122742ec --- /dev/null +++ b/src/Utils/Divide.ts @@ -0,0 +1,5 @@ +export default function Divide(a: number, b: number): number { + const out = Number(((a || 0) / (b || 0)).toFixed(2)) || 0; + if (isFinite(out)) return out; + return a; +} diff --git a/src/Utils/Guild.ts b/src/Utils/Guild.ts new file mode 100644 index 000000000..5bad0fe13 --- /dev/null +++ b/src/Utils/Guild.ts @@ -0,0 +1,83 @@ +import GuildMember from '../Structures/Guild/GuildMember.js'; +import GuildRank from '../Structures/Guild/GuildRank.js'; +import type { ExpHistory } from '../Types/Guild.js'; + +const dateRegExp = /(\d{4})-(\d{2})-(\d{2})/; +export function parseDate(date: Record) { + date[1] -= 1; + return new Date( + Math.round(new Date(new Date().setUTCFullYear(...(date as [any]))).setUTCHours(5, 0, 0) / 1000) * 1000 + ); +} + +export function parseHistory(historyData: Record): ExpHistory[] { + return Object.entries(historyData).map((x, index) => ({ + day: x[0], + date: x[0].match(dateRegExp) + ? parseDate( + x[0] + .match(dateRegExp)! + .slice(1) + .map((x) => parseInt(x, 10)) + ) + : undefined, + exp: x[1] || 0, + totalExp: + Object.values(historyData) + .slice(0, index + 1) + .reduce((pV: any, cV: any) => pV + cV, 0) || 0 + })); +} + +export function getGuildLevel(exp: number) { + const EXP_NEEDED: number[] = [ + 100000, 150000, 250000, 500000, 750000, 1000000, 1250000, 1500000, 2000000, 2500000, 2500000, 2500000, 2500000, + 2500000, 3000000 + ]; + let level = 0; + for (let i = 0; i <= 1000; i += 1) { + let need: number; + if (i >= EXP_NEEDED.length) { + need = EXP_NEEDED[EXP_NEEDED.length - 1] || 0; + } else { + need = EXP_NEEDED[i] || 0; + } + if (exp - need < 0) { + return Math.round((level + exp / need) * 100) / 100; + } + level += 1; + exp -= need; + } + return 1000; +} + +export function ranks(data: Record) { + return data.ranks && data.ranks.length + ? data.ranks.map((r: any) => new GuildRank(r)).sort((a: any, b: any) => a.priority - b.priority) + : []; +} + +export function expLimit(exp: number) { + return exp > 2e5 ? (exp > 7e5 ? 2.5e5 + Math.round(exp * 0.03) : 2e5 + Math.round((exp - 2e5) / 10)) : exp; +} + +export function calculateExpHistory(data: GuildMember[]): ExpHistory[] { + const finalObj: Record = {}; + if (undefined === data[0]?.expHistory) return []; + Object.keys(data[0].expHistory).forEach((day, index) => { + let GEXP = 0; + data.forEach((member) => (GEXP += member.expHistory?.[index]?.exp || 0)); + finalObj[data[0]?.expHistory[index]?.day || 'UNKNOWN'] = expLimit(GEXP); + }); + return parseHistory(finalObj); +} + +export function members(data: Record): GuildMember[] { + return data.length ? data.map((m: Record) => new GuildMember(m)) : []; +} + +export function totalWeeklyGEXP(data: GuildMember[]): number { + let GEXP: number = 0; + data.forEach((member) => (GEXP += member.weeklyExperience)); + return GEXP; +} diff --git a/src/Utils/Oscillation.test.ts b/src/Utils/Oscillation.test.ts new file mode 100644 index 000000000..27f7b5776 --- /dev/null +++ b/src/Utils/Oscillation.test.ts @@ -0,0 +1,18 @@ +import { expect, test } from 'vitest'; +import { monthAB } from './Oscillation.js'; + +test('Oscillation', () => { + expect(monthAB(0)).toBe('b'); + expect(monthAB(1)).toBe('a'); + expect(monthAB(2)).toBe('b'); + expect(monthAB(3)).toBe('a'); + expect(monthAB(4)).toBe('b'); + expect(monthAB(5)).toBe('a'); + expect(monthAB(6)).toBe('b'); + expect(monthAB(7)).toBe('a'); + expect(monthAB(8)).toBe('b'); + expect(monthAB(9)).toBe('a'); + expect(monthAB(10)).toBe('b'); + expect(monthAB(11)).toBe('a'); + expect(monthAB(12)).toBe('b'); +}); diff --git a/src/Utils/Oscillation.ts b/src/Utils/Oscillation.ts new file mode 100644 index 000000000..128096f3f --- /dev/null +++ b/src/Utils/Oscillation.ts @@ -0,0 +1,14 @@ +// See https://github.com/HypixelDev/PublicAPI/blob/db26b5fd3b7bb29da14e40e6d211143ec44a4519/Documentation/misc/Oscillation.md +// Month Oscillation started in December 2014, so every month that is pair ( odd in js!! ) is month A +// Weekly Oscillation started... just refer to the code in the docs +const weeklyOscillationStart = 1417237200000; +export function monthAB(month?: number) { + if (month === undefined) { + month = new Date().getMonth(); + } + return month % 2 ? 'a' : 'b'; +} + +export function weekAB() { + return (Math.abs(new Date().getTime() - weeklyOscillationStart) / 604800000) % 2 ? 'a' : 'b'; +} diff --git a/src/Utils/ParseBoosterType.ts b/src/Utils/ParseBoosterType.ts new file mode 100644 index 000000000..cc811af32 --- /dev/null +++ b/src/Utils/ParseBoosterType.ts @@ -0,0 +1,7 @@ +import type { BoosterType } from '../Types/Booster.js'; + +export default function ParseBoosterType(data: Record): BoosterType { + if (data.stacked === true) return 'STACKED'; + if (!data.stacked) return 'QUEUED'; + return 'ACTIVE'; +} diff --git a/src/Utils/ParseMode.ts b/src/Utils/ParseMode.ts new file mode 100644 index 000000000..0bd5759fb --- /dev/null +++ b/src/Utils/ParseMode.ts @@ -0,0 +1,11 @@ +export function ParseModeBefore(mode?: string): string { + return mode?.trim() ? `${mode.trim().replace(/_+$/, '')}_` : ''; +} + +export function ParseModeAfter(mode?: string): string { + return mode?.trim() ? `_${mode.trim().replace(/^_+/, '')}` : ''; +} + +export function ParseModeBeforeAfter(mode?: string): string { + return mode?.trim() ? `_${mode.trim().replace(/^_+|_+$/g, '')}_` : ''; +} diff --git a/src/Utils/RemoveSnakeCase.ts b/src/Utils/RemoveSnakeCase.ts new file mode 100644 index 000000000..3e9f0978c --- /dev/null +++ b/src/Utils/RemoveSnakeCase.ts @@ -0,0 +1,20 @@ +export function validateJSON(obj: any) { + return typeof obj === 'object' && JSON.stringify(obj)[0] === '{'; +} + +export function recursive(obj: any, lowerCase: boolean = false): any { + if (!validateJSON(obj)) return obj; + return Object.keys(obj).reduce( + (pV, cV) => ({ + ...pV, + [(lowerCase ? cV : cV.toLowerCase()).replace(/_[a-z]/gi, (x) => (x?.[1] || 'UNKNOWN').toUpperCase())]: recursive( + obj[cV] + ) + }), + {} + ); +} + +export function RemoveSnakeCaseString(str: string): string { + return str.toLowerCase().replace(/_[a-z]/gi, (x) => (x?.[1] || 'UNKNOWN').toUpperCase()); +} diff --git a/src/Utils/Romanize.test.ts b/src/Utils/Romanize.test.ts new file mode 100644 index 000000000..aad88fbc6 --- /dev/null +++ b/src/Utils/Romanize.test.ts @@ -0,0 +1,9 @@ +import Romanize from './Romanize.js'; +import { expect, test } from 'vitest'; + +test('Romanize', () => { + expect(Romanize('2')).toBe('II'); + expect(Romanize(128)).toBe('CXXVIII'); + expect(Romanize(500)).toBe('D'); + expect(Romanize('7')).toBe('VII'); +}); diff --git a/src/Utils/Romanize.ts b/src/Utils/Romanize.ts new file mode 100644 index 000000000..b9bffdb60 --- /dev/null +++ b/src/Utils/Romanize.ts @@ -0,0 +1,41 @@ +export default function Romanize(num: number | string): string { + const digits = String(Number(num)).split(''); + const key = [ + '', + 'C', + 'CC', + 'CCC', + 'CD', + 'D', + 'DC', + 'DCC', + 'DCCC', + 'CM', + '', + 'X', + 'XX', + 'XXX', + 'XL', + 'L', + 'LX', + 'LXX', + 'LXXX', + 'XC', + '', + 'I', + 'II', + 'III', + 'IV', + 'V', + 'VI', + 'VII', + 'VIII', + 'IX' + ]; + let roman = ''; + let i = 3; + while (i--) { + roman = (key[Number(digits.pop()) + i * 10] || '') + roman; + } + return Array(Number(digits.join('') + 1)).join('M') + roman; +} diff --git a/src/Utils/SkyBlockUtils.ts b/src/Utils/SkyBlockUtils.ts new file mode 100644 index 000000000..b5b53c255 --- /dev/null +++ b/src/Utils/SkyBlockUtils.ts @@ -0,0 +1,291 @@ +import { + CACTUS, + CARROT, + COCOA_BEANS, + CustomPetLeveling, + DEFAULT_LEVELING_XP, + DEFAULT_SKILL_CAPS, + DUNGEONEERING_XP, + GARDEN_XP, + HOTM_XP, + INFINITE, + MELON, + MOONFLOWER, + MUSHROOM, + NETHER_WART, + POTATO, + PUMPKIN, + PetLevels, + RUNECRAFTING_XP, + SLAYER_XP, + SOCIAL_XP, + SUGAR_CANE, + SUNFLOWER, + WHEAT, + WILD_ROSE, + petRarityOffset +} from './Constants.js'; +import { parse, simplify } from 'prismarine-nbt'; +import type SkyBlockProfile from '../Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import type { + LevelData, + PetLevelData, + Rarity, + SkillLevelData, + SkyBlockPetId, + SkyBlockSlayer, + SkyBlockXPTables, + SkyHelperNetWorthProfile +} from '../Types/SkyBlock.js'; + +export async function decode(base64: any, isBuffer: boolean = false): Promise { + // Credit: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/3b5b3ae4fe77c60eff90691797f09024baf68872/src/lib/server/stats/items/processing.ts#L215-L218 + const buffer = isBuffer ? base64 : Buffer.from(base64, 'base64'); + const parseData = await parse(buffer); + const data = simplify(parseData.parsed); + const newData = []; + for (let i = 0; i < data.i.length; i++) { + newData.push(data.i[i]); + } + return newData; +} + +// Credit: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/2d4d0317b1f7a9f27e59d25afd4df24c0e49b0da/src/lib/server/stats/pets.ts#L70-L101 (modified) +export function getPetLevel(petExp: number, type: SkyBlockPetId | 'UNKNOWN', rarity: Rarity | 'UNKNOWN'): PetLevelData { + const rarityOffset = + type === 'BINGO' ? (CustomPetLeveling[type]?.rarityOffset?.[rarity] ?? petRarityOffset[rarity]) : 0; + + const maxLevel = type === 'GOLDEN_DRAGON' ? CustomPetLeveling[type]?.maxLevel : 100; + + const levels: number[] = PetLevels.slice(rarityOffset, rarityOffset + maxLevel - 1).concat( + type === 'GOLDEN_DRAGON' ? CustomPetLeveling[type]?.petLevels : PetLevels + ); + + let level: number = 1; + let xpMaxLevel: number = 0; + let currentXp: number = 0; + for (let i: number = 0; i < maxLevel - 1; i++) { + xpMaxLevel += levels?.[i] || 0; + if (xpMaxLevel <= petExp) { + level++; + currentXp = petExp - xpMaxLevel; + } + } + + const xpForNext: number | null = levels[level - 1] ?? null; + const progress = xpForNext !== null ? (isNaN(currentXp / xpForNext) ? 0 : currentXp / xpForNext) : 0; + + return { xp: petExp, level, xpForNext, progress, maxed: maxLevel === level, maxLevel, xpMaxLevel, currentXp }; +} + +// CREDITS: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/2d4d0317b1f7a9f27e59d25afd4df24c0e49b0da/src/lib/server/stats/slayer.ts#L24-L59 (modified) +export function getSlayerLevel(slayer: SkyBlockSlayer, xp: number): LevelData { + if (SLAYER_XP[slayer] === undefined) { + return { + xp: 0, + level: 0, + xpForNext: SLAYER_XP[slayer] ? SLAYER_XP[slayer][1] : null, + progress: 0, + maxed: false, + maxLevel: 0 + }; + } + + const reversed = Object.entries(SLAYER_XP[slayer]).reverse(); + const maxLevel = Object.keys(SLAYER_XP[slayer]).length; + + for (const [level, requiredXP] of reversed) { + if (xp >= requiredXP) { + const xpForNext = SLAYER_XP[slayer][parseInt(level) + 1] || 0; + return { + xp, + xpForNext, + level: parseInt(level), + maxLevel, + maxed: parseInt(level) === maxLevel, + progress: isNaN(xp / xpForNext) ? 0 : xp / xpForNext + }; + } + } + + return { xp, xpForNext: 0, level: 0, maxLevel, maxed: false, progress: 0 }; +} + +function getXpTable(type: SkyBlockXPTables): Record { + const SKILL_TABLES = { + default: DEFAULT_LEVELING_XP, + runecrafting: RUNECRAFTING_XP, + social: SOCIAL_XP, + dungeoneering: DUNGEONEERING_XP, + hotm: HOTM_XP, + farming: DEFAULT_LEVELING_XP, + mining: DEFAULT_LEVELING_XP, + combat: DEFAULT_LEVELING_XP, + foraging: DEFAULT_LEVELING_XP, + fishing: DEFAULT_LEVELING_XP, + enchanting: DEFAULT_LEVELING_XP, + alchemy: DEFAULT_LEVELING_XP, + taming: DEFAULT_LEVELING_XP, + carpentry: DEFAULT_LEVELING_XP, + garden: GARDEN_XP, + wheat: WHEAT, + carrot: CARROT, + sugarCane: SUGAR_CANE, + potato: POTATO, + pumpkin: PUMPKIN, + melon: MELON, + cactus: CACTUS, + cocoaBeans: COCOA_BEANS, + mushroom: MUSHROOM, + netherWart: NETHER_WART, + moonFlower: MOONFLOWER, + sunFlower: SUNFLOWER, + wildRose: WILD_ROSE + }; + + return SKILL_TABLES[type] ?? DEFAULT_LEVELING_XP; +} + +export type Extra = { type: SkyBlockXPTables; cap?: number }; + +// Credit: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/2d4d0317b1f7a9f27e59d25afd4df24c0e49b0da/src/lib/server/stats/leveling/leveling.ts#L43-L126 (modified) +export function getLevelByXp(xp: number, extra: Extra = { type: 'default' }): SkillLevelData { + const xpTable = getXpTable(extra.type) as Record; + if (typeof xp !== 'number' || isNaN(xp)) { + xp = 0; + } + + const levelCap = extra.cap ?? DEFAULT_SKILL_CAPS[extra.type] ?? Math.max(...Object.keys(xpTable).map(Number)); + let uncappedLevel = 0; + let currentXp = xp; + let xpRemaining = xp; + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + while (xpTable[uncappedLevel + 1] <= xpRemaining) { + uncappedLevel++; + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-expect-error + xpRemaining -= xpTable[uncappedLevel]; + if (uncappedLevel <= levelCap) { + currentXp = xpRemaining; + } + } + + const isInfiniteLevelAble = INFINITE.includes(extra.type); + if (isInfiniteLevelAble) { + const maxExperience = Object.values(xpTable).at(-1) as number; + uncappedLevel += Math.floor(xpRemaining / maxExperience); + xpRemaining %= maxExperience; + currentXp = xpRemaining; + } + + const maxLevel = isInfiniteLevelAble ? Math.max(uncappedLevel, levelCap) : levelCap; + const level = isInfiniteLevelAble ? uncappedLevel : Math.min(levelCap, uncappedLevel); + + const xpForNext = ( + level < maxLevel + ? Math.ceil(xpTable[level + 1] ?? Object.values(xpTable).at(-1) ?? 0) + : isInfiniteLevelAble + ? Object.values(xpTable).at(-1) + : Infinity + ) as number; + + const progress = level >= maxLevel && !isInfiniteLevelAble ? 0 : Math.max(0, Math.min(currentXp / xpForNext, 1)); + const maxed = level >= maxLevel; + + return { xp, level, xpForNext, progress, maxed, maxLevel, currentXp }; +} + +export function PrepareSkyBlockProfileForSkyHelperNetworth( + profile: SkyBlockProfile & { me: NonNullable } +): SkyHelperNetWorthProfile { + /* eslint-disable camelcase */ + /* eslint-disable quote-props */ + return { + currencies: { + coin_purse: profile.me.currencies.purse, + essence: { + WITHER: { current: profile.me.currencies.witherEssence }, + DRAGON: { current: profile.me.currencies.dragonEssence }, + SPIDER: { current: profile.me.currencies.spiderEssence }, + UNDEAD: { current: profile.me.currencies.undeadEssence }, + DIAMOND: { current: profile.me.currencies.diamondEssence }, + GOLD: { current: profile.me.currencies.goldEssence }, + ICE: { current: profile.me.currencies.iceEssence }, + CRIMSON: { current: profile.me.currencies.crimsonEssence } + } + }, + profile: { bank_account: profile.banking.balance }, + player_data: profile.me.playerData, + leveling: profile.me.leveling, + inventory: { + inv_armor: { data: profile.me.inventory.armor.base64 ?? '' }, + equipment_contents: { data: profile.me.inventory.equipment.base64 ?? '' }, + wardrobe_contents: { data: profile.me.inventory.wardrobe.base64 ?? '' }, + inv_contents: { data: profile.me.inventory.inventory.base64 ?? '' }, + ender_chest_contents: { data: profile.me.inventory.enderChest.base64 ?? '' }, + personal_vault_contents: { data: profile.me.inventory.personalVault.base64 ?? '' }, + backpack_contents: { + '0': { data: profile.me.inventory.backpacks.backpack1?.backpackContentsBase64 ?? '' }, + '1': { data: profile.me.inventory.backpacks.backpack2?.backpackContentsBase64 ?? '' }, + '2': { data: profile.me.inventory.backpacks.backpack3?.backpackContentsBase64 ?? '' }, + '3': { data: profile.me.inventory.backpacks.backpack4?.backpackContentsBase64 ?? '' }, + '4': { data: profile.me.inventory.backpacks.backpack5?.backpackContentsBase64 ?? '' }, + '5': { data: profile.me.inventory.backpacks.backpack6?.backpackContentsBase64 ?? '' }, + '6': { data: profile.me.inventory.backpacks.backpack7?.backpackContentsBase64 ?? '' }, + '7': { data: profile.me.inventory.backpacks.backpack8?.backpackContentsBase64 ?? '' }, + '8': { data: profile.me.inventory.backpacks.backpack9?.backpackContentsBase64 ?? '' }, + '9': { data: profile.me.inventory.backpacks.backpack10?.backpackContentsBase64 ?? '' }, + '10': { data: profile.me.inventory.backpacks.backpack11?.backpackContentsBase64 ?? '' }, + '11': { data: profile.me.inventory.backpacks.backpack12?.backpackContentsBase64 ?? '' }, + '12': { data: profile.me.inventory.backpacks.backpack13?.backpackContentsBase64 ?? '' }, + '13': { data: profile.me.inventory.backpacks.backpack14?.backpackContentsBase64 ?? '' }, + '14': { data: profile.me.inventory.backpacks.backpack15?.backpackContentsBase64 ?? '' }, + '15': { data: profile.me.inventory.backpacks.backpack16?.backpackContentsBase64 ?? '' }, + '16': { data: profile.me.inventory.backpacks.backpack17?.backpackContentsBase64 ?? '' }, + '17': { data: profile.me.inventory.backpacks.backpack18?.backpackContentsBase64 ?? '' } + }, + backpack_icons: { + '0': { data: profile.me.inventory.backpacks.backpack1?.backpackItemBase64 ?? '' }, + '1': { data: profile.me.inventory.backpacks.backpack2?.backpackItemBase64 ?? '' }, + '2': { data: profile.me.inventory.backpacks.backpack3?.backpackItemBase64 ?? '' }, + '3': { data: profile.me.inventory.backpacks.backpack4?.backpackItemBase64 ?? '' }, + '4': { data: profile.me.inventory.backpacks.backpack5?.backpackItemBase64 ?? '' }, + '5': { data: profile.me.inventory.backpacks.backpack6?.backpackItemBase64 ?? '' }, + '6': { data: profile.me.inventory.backpacks.backpack7?.backpackItemBase64 ?? '' }, + '7': { data: profile.me.inventory.backpacks.backpack8?.backpackItemBase64 ?? '' }, + '8': { data: profile.me.inventory.backpacks.backpack9?.backpackItemBase64 ?? '' }, + '9': { data: profile.me.inventory.backpacks.backpack10?.backpackItemBase64 ?? '' }, + '10': { data: profile.me.inventory.backpacks.backpack11?.backpackItemBase64 ?? '' }, + '11': { data: profile.me.inventory.backpacks.backpack12?.backpackItemBase64 ?? '' }, + '12': { data: profile.me.inventory.backpacks.backpack13?.backpackItemBase64 ?? '' }, + '13': { data: profile.me.inventory.backpacks.backpack14?.backpackItemBase64 ?? '' }, + '14': { data: profile.me.inventory.backpacks.backpack15?.backpackItemBase64 ?? '' }, + '15': { data: profile.me.inventory.backpacks.backpack16?.backpackItemBase64 ?? '' }, + '16': { data: profile.me.inventory.backpacks.backpack17?.backpackItemBase64 ?? '' }, + '17': { data: profile.me.inventory.backpacks.backpack18?.backpackItemBase64 ?? '' } + }, + bag_contents: { + talisman_bag: { data: profile.me.inventory.bags.talisman.base64 ?? '' }, + fishing_bag: { data: profile.me.inventory.bags.fishing.base64 ?? '' }, + potion_bag: { data: profile.me.inventory.bags.potion.base64 ?? '' }, + sacks_bag: { data: profile.me.inventory.bags.sacks.base64 ?? '' }, + quiver: { data: profile.me.inventory.bags.quiver.base64 ?? '' } + }, + sacks_counts: profile.me.inventory.sacksCounts + }, + shared_inventory: { + candy_inventory_contents: { data: profile.me.inventory.candy.base64 ?? '' }, + carnival_mask_inventory_contents: { data: profile.me.inventory.carnivalMask.base64 ?? '' } + }, + pets_data: { + pets: profile.me.pets.pets.map((pet) => { + return { type: pet.type, tier: pet.tier, exp: pet.level.xp, heldItem: pet.heldItem, skin: pet.skin }; + }) + }, + sacks_counts: profile.me.inventory.sacksCounts + }; + /* eslint-enable camelcase */ + /* eslint-enable quote-props */ +} diff --git a/src/Utils/TicksToMilliseconds.ts b/src/Utils/TicksToMilliseconds.ts new file mode 100644 index 000000000..1af5ed962 --- /dev/null +++ b/src/Utils/TicksToMilliseconds.ts @@ -0,0 +1,3 @@ +export default function TicksToMilliseconds(ticks: number): number { + return (ticks / 20) * 1000; +} diff --git a/src/index.js b/src/index.js deleted file mode 100644 index f32ed6229..000000000 --- a/src/index.js +++ /dev/null @@ -1,96 +0,0 @@ -module.exports = { - Client: require('./Client.js'), - version: require('../package.json').version, - - /* API Status */ - APIStatus: require('./structures/APIStatus.js'), - APIIncident: require('./structures/APIIncident.js'), - - Player: require('./structures/Player.js'), - Game: require('./structures/Game.js'), - Status: require('./structures/Status.js'), - Color: require('./structures/Color.js'), - Pet: require('./structures/Pet'), - Pets: require('./structures/Pets'), - PlayerCosmetics: require('./structures/PlayerCosmetics'), - - /* Challenges */ - Challenges: require('./structures/Static/Challenges.js'), - GameChallenges: require('./structures/Static/GameChallenges.js'), - - /* Watchdog */ - WatchdogStats: require('./structures/Watchdog/Stats.js'), - - /* Guild */ - Guild: require('./structures/Guild/Guild.js'), - GuildMember: require('./structures/Guild/GuildMember.js'), - GuildRank: require('./structures/Guild/GuildRank.js'), - - /* SkyBlock */ - SkyblockProfile: require('./structures/SkyBlock/SkyblockProfile.js'), - SkyblockMember: require('./structures/SkyBlock/SkyblockMember.js'), - SkyblockGarden: require('./structures/SkyBlock/SkyblockGarden.js'), - SkyblockInventoryItem: require('./structures/SkyBlock/SkyblockInventoryItem.js'), - SkyblockPet: require('./structures/SkyBlock/SkyblockPet'), - GovernmentData: require('./structures/SkyBlock/Static/Government.js'), - Candidate: require('./structures/SkyBlock/Static/Candidate.js'), - BingoData: require('./structures/SkyBlock/Static/BingoData.js'), - Bingo: require('./structures/SkyBlock/Static/Bingo.js'), - - /* Skyblock Auctions */ - BaseAuction: require('./structures/SkyBlock/Auctions/BaseAuction.js'), - PartialAuction: require('./structures/SkyBlock/Auctions/PartialAuction.js'), - Auction: require('./structures/SkyBlock/Auctions/Auction.js'), - AuctionInfo: require('./structures/SkyBlock/Auctions/AuctionInfo.js'), - Bid: require('./structures/SkyBlock/Auctions/Bid.js'), - FireSale: require('./structures/SkyBlock/Static/FireSale.js'), - - /* Skyblock Bazaar */ - Product: require('./structures/SkyBlock/Bazzar/Product.js'), - Order: require('./structures/SkyBlock/Bazzar/Order.js'), - - /* Skyblock News */ - SkyblockNews: require('./structures/SkyBlock/News/SkyblockNews'), - - /* Booster */ - Booster: require('./structures/Boosters/Booster.js'), - - /* House */ - House: require('./structures/House.js'), - - /* MiniGames */ - Arcade: require('./structures/MiniGames/Arcade.js'), - ArenaBrawl: require('./structures/MiniGames/ArenaBrawl.js'), - BedWars: require('./structures/MiniGames/BedWars.js'), - BlitzSurvivalGames: require('./structures/MiniGames/BlitzSurvivalGames.js'), - BuildBattle: require('./structures/MiniGames/BuildBattle.js'), - CopsAndCrims: require('./structures/MiniGames/CopsAndCrims.js'), - Duels: require('./structures/MiniGames/Duels.js'), - MegaWalls: require('./structures/MiniGames/MegaWalls.js'), - MurderMystery: require('./structures/MiniGames/MurderMystery.js'), - Paintball: require('./structures/MiniGames/Paintball.js'), - Pit: require('./structures/MiniGames/Pit.js'), - Quakecraft: require('./structures/MiniGames/Quakecraft.js'), - SkyWars: require('./structures/MiniGames/SkyWars.js'), - SmashHeroes: require('./structures/MiniGames/SmashHeroes.js'), - SpeedUHC: require('./structures/MiniGames/SpeedUHC.js'), - TNTGames: require('./structures/MiniGames/TNTGames.js'), - TurboKartRacers: require('./structures/MiniGames/TurboKartRacers.js'), - UHC: require('./structures/MiniGames/UHC.js'), - VampireZ: require('./structures/MiniGames/VampireZ.js'), - Walls: require('./structures/MiniGames/Walls.js'), - Warlords: require('./structures/MiniGames/Warlords.js'), - WoolGames: require('./structures/MiniGames/WoolGames.js'), - - /* Leaderboards */ - Leaderboard: require('./structures/Leaderboard.js'), - - /* Server Info */ - ServerInfo: require('./structures/ServerInfo.js'), - - /* Errors */ - Errors: require('./Errors.js'), - - /* Utils */ - Utils: require('./utils') -}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..dbdfc893b --- /dev/null +++ b/src/index.ts @@ -0,0 +1,1302 @@ +/* v8 ignore next 10000 */ +/* eslint-disable @stylistic/max-len */ + +import Client from './Client.js'; +import Errors from './Errors.js'; + +export * from './Types/API.js'; +export * from './Types/Booster.js'; +export * from './Types/Client.js'; +export * from './Types/Color.js'; +export * from './Types/Game.js'; +export * from './Types/Global.js'; +export * from './Types/Guild.js'; +export * from './Types/Player.js'; +export * from './Types/Requests.js'; +export * from './Types/SkyBlock.js'; +export * from './Types/Static.js'; + +export * from './Utils/Constants.js'; +export * from './Utils/Divide.js'; +export * from './Utils/Guild.js'; +export * from './Utils/Oscillation.js'; +export * from './Utils/ParseBoosterType.js'; +export * from './Utils/ParseMode.js'; +export * from './Utils/RemoveSnakeCase.js'; +export * from './Utils/Romanize.js'; +export * from './Utils/SkyBlockUtils.js'; +export * from './Utils/TicksToMilliseconds.js'; + +import Achievements from './Structures/Static/Achievements/Achievements.js'; +import Arcade from './Structures/MiniGames/Arcade/Arcade.js'; +import ArcadeOptions from './Structures/MiniGames/Arcade/ArcadeOptions.js'; +import ArenaBrawl from './Structures/MiniGames/ArenaBrawl/ArenaBrawl.js'; +import ArenaBrawlMode from './Structures/MiniGames/ArenaBrawl/ArenaBrawlMode.js'; +import BaseAchievement from './Structures/Static/Achievements/BaseAchievement.js'; +import BaseKillDeathsType from './Structures/MiniGames/Shared/BaseKillDeathsType.js'; +import BaseSkyWarsMode from './Structures/MiniGames/SkyWars/SkyWarsMode/BaseSkyWarsMode.js'; +import BedWars from './Structures/MiniGames/BedWars/BedWars.js'; +import BedWarsBeds from './Structures/MiniGames/BedWars/BedWarsBeds.js'; +import BedWarsBoxes from './Structures/MiniGames/BedWars/BedWarsBoxes.js'; +import BedWarsChallenge from './Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenge.js'; +import BedWarsChallenges from './Structures/MiniGames/BedWars/BedWarsChallenges/BedWarsChallenges.js'; +import BedWarsEightOne from './Structures/MiniGames/BedWars/BedWarsEightOne.js'; +import BedWarsEightTwo from './Structures/MiniGames/BedWars/BedWarsEightTwo.js'; +import BedWarsFavorites from './Structures/MiniGames/BedWars/BedWarsFavorites.js'; +import BedWarsFigurines from './Structures/MiniGames/BedWars/BedWarsFigurines.js'; +import BedWarsFourFour from './Structures/MiniGames/BedWars/BedWarsFourFour.js'; +import BedWarsFourThree from './Structures/MiniGames/BedWars/BedWarsFourThree.js'; +import BedWarsItemsPurchased from './Structures/MiniGames/BedWars/BedWarsItemsPurchased.js'; +import BedWarsKillsDeaths from './Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeaths.js'; +import BedWarsKillsDeathsType from './Structures/MiniGames/BedWars/BedWarsKillsDeaths/BedWarsKillsDeathsType.js'; +import BedWarsMode from './Structures/MiniGames/BedWars/BedWarsMode.js'; +import BedWarsPractice from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPractice.js'; +import BedWarsPracticeBridging from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridging.js'; +import BedWarsPracticeBridgingRecords from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecords.js'; +import BedWarsPracticeBridgingRecordsDistance from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsDistance.js'; +import BedWarsPracticeBridgingRecordsEevation from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeBridgingRecords/BedWarsPracticeBridgingRecordsEevation.js'; +import BedWarsPracticeMode from './Structures/MiniGames/BedWars/BedWarsPractice/BedWarsPracticeMode.js'; +import BedWarsPrivateGameSettings from './Structures/MiniGames/BedWars/BedWarsPrivateGameSettings.js'; +import BedWarsResourcesCollected from './Structures/MiniGames/BedWars/BedWarsResourcesCollected.js'; +import BedWarsSettings from './Structures/MiniGames/BedWars/BedWarsSettings.js'; +import BedWarsSlumber from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumber.js'; +import BedWarsSlumberMinion from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberMinion.js'; +import BedWarsSlumberPhase from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhase.js'; +import BedWarsSlumberPhaseThree from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberPhaseThree.js'; +import BedWarsSlumberQuest from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuest.js'; +import BedWarsSlumberQuestGamblerGeorge from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestGamblerGeorge.js'; +import BedWarsSlumberQuestItem from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestItem.js'; +import BedWarsSlumberQuestNPC from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPC.js'; +import BedWarsSlumberQuestNPCSBoolean from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSBoolean.js'; +import BedWarsSlumberQuestNPCSNumber from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestNPCSNumber.js'; +import BedWarsSlumberQuestObjective from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberQuest/BedWarsSlumberQuestObjective.js'; +import BedWarsSlumberRoom from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberRoom.js'; +import BedWarsSlumberSandman from './Structures/MiniGames/BedWars/BedWarsSlumber/BedWarsSlumberSandman.js'; +import BedWarsTwoFour from './Structures/MiniGames/BedWars/BedWarsTwoFour.js'; +import BlitzSurvivalGames from './Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGames.js'; +import BlitzSurvivalGamesData from './Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesData.js'; +import BlitzSurvivalGamesKit from './Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesKit.js'; +import BlitzSurvivalGamesPrivateGames from './Structures/MiniGames/BlitzSurvivalGames/BlitzSurvivalGamesPrivateGames.js'; +import BlockingDead from './Structures/MiniGames/Arcade/BlockingDead.js'; +import Booster from './Structures/Boosters/Booster.js'; +import BowSpleef from './Structures/MiniGames/TNTGames/BowSpleef.js'; +import BuildBattle from './Structures/MiniGames/BuildBattle/BuildBattle.js'; +import BuildBattleLastWin from './Structures/MiniGames/BuildBattle/BuildBattleLastWin.js'; +import BuildBattleVotes from './Structures/MiniGames/BuildBattle/BuildBattleVotes.js'; +import CaptureTheWool from './Structures/MiniGames/WoolGames/CaptureTheWool.js'; +import Challenge from './Structures/Static/Challenge.js'; +import Challenges from './Structures/Static/Challenges.js'; +import Color from './Structures/Color.js'; +import CopsAndCrims from './Structures/MiniGames/CopsAndCrims/CopsAndCrims.js'; +import CopsAndCrimsGamemode from './Structures/MiniGames/CopsAndCrims/CopsAndCrimsGamemode.js'; +import CopsAndCrimsGun from './Structures/MiniGames/CopsAndCrims/CopsAndCrimsGun.js'; +import DragonWars from './Structures/MiniGames/Arcade/DragonWars.js'; +import DrawTheirThing from './Structures/MiniGames/Arcade/DrawTheirThing.js'; +import Dropper from './Structures/MiniGames/Arcade/Dropper/Dropper.js'; +import DropperMap from './Structures/MiniGames/Arcade/Dropper/DropperMap.js'; +import Dtt from './Structures/MiniGames/Arcade/Dtt.js'; +import Duels from './Structures/MiniGames/Duels/Duels.js'; +import DuelsBridge from './Structures/MiniGames/Duels/DuelsBridge.js'; +import DuelsGamemode from './Structures/MiniGames/Duels/DuelsGamemode.js'; +import DuelsMegaWalls from './Structures/MiniGames/Duels/DuelsMegaWalls.js'; +import DuelsOP from './Structures/MiniGames/Duels/DuelsOP.js'; +import DuelsSkyWars from './Structures/MiniGames/Duels/DuelsSkyWars.js'; +import DuelsUHC from './Structures/MiniGames/Duels/DuelsUHC.js'; +import EasterSimulator from './Structures/MiniGames/Arcade/EasterSimulator.js'; +import Emblem from './Structures/MiniGames/Shared/Emblem/Emblem.js'; +import EmblemColors from './Structures/MiniGames/Shared/Emblem/EmblemColors.js'; +import EnderSpleef from './Structures/MiniGames/Arcade/EnderSpleef.js'; +import FarmHunt from './Structures/MiniGames/Arcade/FarmHunt.js'; +import FootBall from './Structures/MiniGames/Arcade/FootBall.js'; +import GalaxyWars from './Structures/MiniGames/Arcade/GalaxyWars.js'; +import Game from './Structures/Game.js'; +import GameAchievements from './Structures/Static/Achievements/GameAchievements.js'; +import GameChallenges from './Structures/Static/GameChallenges.js'; +import GameCounts from './Structures/Static/GameCounts/GameCounts.js'; +import GameCountsArcade from './Structures/Static/GameCounts/Arcade/GameCountsArcade.js'; +import GameCountsArcadeModes from './Structures/Static/GameCounts/Arcade/GameCountsArcadeModes.js'; +import GameCountsBasicModes from './Structures/Static/GameCounts/GameCountsBasicModes.js'; +import GameCountsBattleGround from './Structures/Static/GameCounts/BattleGround/GameCountsBattleGround.js'; +import GameCountsBattleGroundModes from './Structures/Static/GameCounts/BattleGround/GameCountsBattleGroundModes.js'; +import GameCountsBedWars from './Structures/Static/GameCounts/BedWars/GameCountsBedWars.js'; +import GameCountsBedWarsModes from './Structures/Static/GameCounts/BedWars/GameCountsBedWarsModes.js'; +import GameCountsBuildBattle from './Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattle.js'; +import GameCountsBuildBattleModes from './Structures/Static/GameCounts/BuildBattle/GameCountsBuildBattleModes.js'; +import GameCountsDuels from './Structures/Static/GameCounts/Duels/GameCountsDuels.js'; +import GameCountsDuelsModes from './Structures/Static/GameCounts/Duels/GameCountsDuelsModes.js'; +import GameCountsGames from './Structures/Static/GameCounts/GameCountsGames.js'; +import GameCountsGeneric from './Structures/Static/GameCounts/GameCountsGeneric.js'; +import GameCountsLegacy from './Structures/Static/GameCounts/Legacy/GameCountsLegacy.js'; +import GameCountsLegacyModes from './Structures/Static/GameCounts/Legacy/GameCountsLegacyModes.js'; +import GameCountsMCGO from './Structures/Static/GameCounts/MCGO/GameCountsMCGO.js'; +import GameCountsMCGOModes from './Structures/Static/GameCounts/MCGO/GameCountsMCGOModes.js'; +import GameCountsMurderMystery from './Structures/Static/GameCounts/MurderMystery/GameCountsMurderMystery.js'; +import GameCountsMurderMysteryModes from './Structures/Static/GameCounts/MurderMystery/GameCountsMurderMysteryModes.js'; +import GameCountsPit from './Structures/Static/GameCounts/Pit/GameCountsPit.js'; +import GameCountsPitModes from './Structures/Static/GameCounts/Pit/GameCountsPitModes.js'; +import GameCountsReplay from './Structures/Static/GameCounts/Replay/GameCountsReplay.js'; +import GameCountsReplayModes from './Structures/Static/GameCounts/Replay/GameCountsReplayModes.js'; +import GameCountsSkyBlock from './Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlock.js'; +import GameCountsSkyBlockModes from './Structures/Static/GameCounts/SkyBlock/GameCountsSkyBlockModes.js'; +import GameCountsSkyWars from './Structures/Static/GameCounts/SkyWars/GameCountsSkyWars.js'; +import GameCountsSkyWarsModes from './Structures/Static/GameCounts/SkyWars/GameCountsSkyWarsModes.js'; +import GameCountsSpeedUHC from './Structures/Static/GameCounts/SpeedUHC/GameCountsSpeedUHC.js'; +import GameCountsSuperSmash from './Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmash.js'; +import GameCountsSuperSmashModes from './Structures/Static/GameCounts/SuperSmash/GameCountsSuperSmashModes.js'; +import GameCountsSurvivalGames from './Structures/Static/GameCounts/SurvivalGames/GameCountsSurvivalGames.js'; +import GameCountsTNTGames from './Structures/Static/GameCounts/TNTGames/GameCountsTNTGames.js'; +import GameCountsTNTGamesModes from './Structures/Static/GameCounts/TNTGames/GameCountsTNTGamesModes.js'; +import GameCountsUHC from './Structures/Static/GameCounts/UHC/GameCountsUHC.js'; +import GameCountsUHCModes from './Structures/Static/GameCounts/UHC/GameCountsUHCModes.js'; +import GameCountsWalls3 from './Structures/Static/GameCounts/Walls3/GameCountsWalls3.js'; +import GameCountsWalls3Modes from './Structures/Static/GameCounts/Walls3/GameCountsWalls3Modes.js'; +import GameCountsWoolGames from './Structures/Static/GameCounts/WoolGames/GameCountsWoolGames.js'; +import GameCountsWoolGamesModes from './Structures/Static/GameCounts/WoolGames/GameCountsWoolGamesModes.js'; +import GameQuests from './Structures/Static/GameQuests.js'; +import GrinchSimulator from './Structures/MiniGames/Arcade/GrinchSimulator.js'; +import Guild from './Structures/Guild/Guild.js'; +import GuildAchievements from './Structures/Static/Achievements/GuildAchievements.js'; +import GuildMember from './Structures/Guild/GuildMember.js'; +import GuildRank from './Structures/Guild/GuildRank.js'; +import HalloweenSimulator from './Structures/MiniGames/Arcade/HalloweenSimulator.js'; +import HideAndSeek from './Structures/MiniGames/Arcade/HideAndSeek.js'; +import HoleInTheWall from './Structures/MiniGames/Arcade/HoleInTheWall.js'; +import House from './Structures/House.js'; +import HypixelSports from './Structures/MiniGames/Arcade/HypixelSports.js'; +import ItemBytes from './Structures/ItemBytes.js'; +import LawnMoower from './Structures/MiniGames/Arcade/PartyGames/LawnMoower.js'; +import Leaderboard from './Structures/Leaderboard.js'; +import LeaderboardSettings from './Structures/MiniGames/Shared/LeaderboardSettings.js'; +import MegaWalls from './Structures/MiniGames/MegaWalls/MegaWalls.js'; +import MegaWallsKitStats from './Structures/MiniGames/MegaWalls/MegaWallsKitStats.js'; +import MegaWallsModeStats from './Structures/MiniGames/MegaWalls/MegaWallsModeStats.js'; +import MiniWalls from './Structures/MiniGames/Arcade/MiniWalls.js'; +import MurderMystery from './Structures/MiniGames/MurderMystery/MurderMystery.js'; +import MurderMysteryDescent from './Structures/MiniGames/MurderMystery/MurderMysteryDescent.js'; +import MurderMysteryDescentItem from './Structures/MiniGames/MurderMystery/MurderMysteryDescentItem.js'; +import MurderMysteryFavorites from './Structures/MiniGames/MurderMystery/MurderMysteryFavorites.js'; +import MurderMysteryGamemode from './Structures/MiniGames/MurderMystery/MurderMysteryGamemode.js'; +import MurderMysteryKnifeSkinPrestige from './Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestige.js'; +import MurderMysteryKnifeSkinPrestigeXp from './Structures/MiniGames/MurderMystery/MurderMysteryKnifeSkinPrestigeXp.js'; +import MurderMysteryMap from './Structures/MiniGames/MurderMystery/MurderMysteryMap.js'; +import OneInTheQuiver from './Structures/MiniGames/Arcade/OneInTheQuiver.js'; +import OneTimeAchievement from './Structures/Static/Achievements/OneTimeAchievement.js'; +import PVPRun from './Structures/MiniGames/TNTGames/PVPRun.js'; +import Paintball from './Structures/MiniGames/Paintball.js'; +import PartyGames from './Structures/MiniGames/Arcade/PartyGames/PartyGames.js'; +import PartyGamesGame from './Structures/MiniGames/Arcade/PartyGames/PartyGamesGame.js'; +import Pit from './Structures/MiniGames/Pit/Pit.js'; +import PitInventoryItem from './Structures/MiniGames/Pit/PitInventoryItem.js'; +import Player from './Structures/Player/Player.js'; +import PlayerAchievements from './Structures/Player/PlayerAchievements/PlayerAchievements.js'; +import PlayerAchievementsRewards from './Structures/Player/PlayerAchievements/PlayerAchievementsRewards.js'; +import PlayerAchievementsTotem from './Structures/Player/PlayerAchievements/PlayerAchievementsTotem.js'; +import PlayerAdventRewards from './Structures/Player/PlayerAdventRewards/PlayerAdventRewards.js'; +import PlayerAdventRewardsDay from './Structures/Player/PlayerAdventRewards/PlayerAdventRewardsDay.js'; +import PlayerCosmetics from './Structures/Player/PlayerCosmetics/PlayerCosmetics.js'; +import PlayerCosmeticsPet from './Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPet.js'; +import PlayerCosmeticsPets from './Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPets.js'; +import PlayerCosmeticsPetsConsumables from './Structures/Player/PlayerCosmetics/Pets/PlayerCosmeticsPetsConsumables.js'; +import PlayerGifting from './Structures/Player/PlayerGifting.js'; +import PlayerHousing from './Structures/Player/PlayerHousing/PlayerHousing.js'; +import PlayerHousingGivenCookies from './Structures/Player/PlayerHousing/PlayerHousingGivenCookies.js'; +import PlayerHousingPlayerSettings from './Structures/Player/PlayerHousing/PlayerHousingPlayerSettings.js'; +import PlayerParkour from './Structures/Player/PlayerParkour.js'; +import PlayerQuest from './Structures/Player/PlayerQuests/PlayerQuest.js'; +import PlayerQuestCompletion from './Structures/Player/PlayerQuests/PlayerQuestCompletion.js'; +import PlayerQuestCompletions from './Structures/Player/PlayerQuests/PlayerQuestCompletions.js'; +import PlayerQuests from './Structures/Player/PlayerQuests/PlayerQuests.js'; +import PlayerRankPurchase from './Structures/Player/PlayerRankPurchase.js'; +import PlayerRewards from './Structures/Player/PlayerRewards/PlayerRewards.js'; +import PlayerRewardsMonthlyCrate from './Structures/Player/PlayerRewards/PlayerRewardsMonthlyCrate.js'; +import PlayerScorpiusBribe from './Structures/Player/PlayerScorpiusBribe.js'; +import PlayerSeasonalChristmasYear from './Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYear.js'; +import PlayerSeasonalChristmasYearAdventRewards from './Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearAdventRewards.js'; +import PlayerSeasonalChristmasYearLeveling from './Structures/Player/PlayerSeasonal/Christmas/PlayerSeasonalChristmasYearLeveling.js'; +import PlayerSocialMedia from './Structures/Player/PlayerSocialMedia.js'; +import PlayerStats from './Structures/Player/PlayerStats.js'; +import PlayerTourney from './Structures/Player/PlayerTourney/PlayerTourney.js'; +import PlayerTourneyData from './Structures/Player/PlayerTourney/PlayerTourneyData.js'; +import Quakecraft from './Structures/MiniGames/Quakecraft/Quakecraft.js'; +import QuakecraftMode from './Structures/MiniGames/Quakecraft/QuakecraftMode.js'; +import Quest from './Structures/Static/Quest.js'; +import QuestObjective from './Structures/Static/QuestObjective.js'; +import Quests from './Structures/Static/Quests.js'; +import RPG16 from './Structures/MiniGames/Arcade/PartyGames/RPG16.js'; +import RecentGame from './Structures/RecentGame.js'; +import SantaSays from './Structures/MiniGames/Arcade/SantaSays.js'; +import SantaSimulator from './Structures/MiniGames/Arcade/SantaSimulator.js'; +import ScubaSimulator from './Structures/MiniGames/Arcade/ScubaSimulator.js'; +import SheepWars from './Structures/MiniGames/WoolGames/SheepWars.js'; +import SimonSays from './Structures/MiniGames/Arcade/SimonSays.js'; +import SkyBlockAuction from './Structures/SkyBlock/Auctions/SkyBlockAuction.js'; +import SkyBlockAuctionBid from './Structures/SkyBlock/Auctions/SkyBlockAuctionBid.js'; +import SkyBlockAuctionInfo from './Structures/SkyBlock/Auctions/SkyBlockAuctionInfo.js'; +import SkyBlockBaseAuction from './Structures/SkyBlock/Auctions/SkyBlockBaseAuction.js'; +import SkyBlockBaseAuctionInfo from './Structures/SkyBlock/Auctions/SkyBlockBaseAuctionInfo.js'; +import SkyBlockBazaar from './Structures/SkyBlock/Bazaar/SkyBlockBazaar.js'; +import SkyBlockBazaarProduct from './Structures/SkyBlock/Bazaar/SkyBlockBazaarProduct.js'; +import SkyBlockBazaarProductOrder from './Structures/SkyBlock/Bazaar/SkyBlockBazaarProductOrder.js'; +import SkyBlockBazaarQuickStatus from './Structures/SkyBlock/Bazaar/SkyBlockBazaarQuickStatus.js'; +import SkyBlockBingo from './Structures/SkyBlock/Bingo/SkyBlockBingo.js'; +import SkyBlockBingoGoal from './Structures/SkyBlock/Bingo/SkyBlockBingoGoal.js'; +import SkyBlockCollection from './Structures/SkyBlock/Collections/SkyBlockCollection.js'; +import SkyBlockCollectionTier from './Structures/SkyBlock/Collections/SkyBlockCollectionTier.js'; +import SkyBlockCollections from './Structures/SkyBlock/Collections/SkyBlockCollections.js'; +import SkyBlockElection from './Structures/SkyBlock/Election/SkyBlockElection.js'; +import SkyBlockElectionCandidate from './Structures/SkyBlock/Election/SkyBlockElectionCandidate.js'; +import SkyBlockElectionCandidatePerk from './Structures/SkyBlock/Election/SkyBlockElectionCandidatePerk.js'; +import SkyBlockElectionData from './Structures/SkyBlock/Election/SkyBlockElectionData.js'; +import SkyBlockFireSale from './Structures/SkyBlock/FireSale/SkyBlockFireSale.js'; +import SkyBlockGarden from './Structures/SkyBlock/Garden/SkyBlockGarden.js'; +import SkyBlockGardenActiveVisitor from './Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitor.js'; +import SkyBlockGardenActiveVisitorRequirement from './Structures/SkyBlock/Garden/SkyBlockGardenActiveVisitorRequirement.js'; +import SkyBlockGardenComposter from './Structures/SkyBlock/Garden/SkyBlockGardenComposter.js'; +import SkyBlockGardenComposterUpgrades from './Structures/SkyBlock/Garden/SkyBlockGardenComposterUpgrades.js'; +import SkyBlockGardenCropMilestones from './Structures/SkyBlock/Garden/SkyBlockGardenCropMilestones.js'; +import SkyBlockGardenCropsUpgrades from './Structures/SkyBlock/Garden/SkyBlockGardenCropsUpgrades.js'; +import SkyBlockGardenVisitors from './Structures/SkyBlock/Garden/SkyBlockGardenVisitors.js'; +import SkyBlockInventoryItem from './Structures/SkyBlock/Inventory/SkyBlockInventoryItem.js'; +import SkyBlockInventoryItemAttribute from './Structures/SkyBlock/Inventory/SkyBlockInventoryItemAttribute.js'; +import SkyBlockInventoryItemEnchantment from './Structures/SkyBlock/Inventory/SkyBlockInventoryItemEnchantment.js'; +import SkyBlockInventoryItemRune from './Structures/SkyBlock/Inventory/SkyBlockInventoryItemRune.js'; +import SkyBlockItem from './Structures/SkyBlock/SkyBlockItem.js'; +import SkyBlockMember from './Structures/SkyBlock/Member/SkyBlockMember.js'; +import SkyBlockMemberAccessoryBag from './Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBag.js'; +import SkyBlockMemberAccessoryBagTuning from './Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuning.js'; +import SkyBlockMemberAccessoryBagTuningSlot from './Structures/SkyBlock/Member/AccessoryBag/SkyBlockMemberAccessoryBagTuningSlot.js'; +import SkyBlockMemberBestiary from './Structures/SkyBlock/Member/Bestiary/SkyBlockMemberBestiary.js'; +import SkyBlockMemberChocolateFactory from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactory.js'; +import SkyBlockMemberChocolateFactoryEggs from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEggs.js'; +import SkyBlockMemberChocolateFactoryEmployees from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryEmployees.js'; +import SkyBlockMemberChocolateFactoryHitmen from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryHitmen.js'; +import SkyBlockMemberChocolateFactoryTimeTower from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryTimeTower.js'; +import SkyBlockMemberChocolateFactoryUpgrades from './Structures/SkyBlock/Member/ChocolateFactory/SkyBlockMemberChocolateFactoryUpgrades.js'; +import SkyBlockMemberCrimsonIsle from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsle.js'; +import SkyBlockMemberCrimsonIsleAbiphone from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleAbiphone.js'; +import SkyBlockMemberCrimsonIsleDojo from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojo.js'; +import SkyBlockMemberCrimsonIsleDojoMinigame from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleDojoMinigame.js'; +import SkyBlockMemberCrimsonIsleKuudra from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudra.js'; +import SkyBlockMemberCrimsonIsleKuudraPartyFinder from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleKuudraPartyFinder.js'; +import SkyBlockMemberCrimsonIsleMatriarch from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleMatriarch.js'; +import SkyBlockMemberCrimsonIsleTrophyFish from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFish.js'; +import SkyBlockMemberCrimsonIsleTrophyFishCaught from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishCaught.js'; +import SkyBlockMemberCrimsonIsleTrophyFishFish from './Structures/SkyBlock/Member/CrimsonIsle/SkyBlockMemberCrimsonIsleTrophyFish/SkyBlockMemberCrimsonIsleTrophyFishFish.js'; +import SkyBlockMemberCurrencies from './Structures/SkyBlock/Member/SkyBlockMemberCurrencies.js'; +import SkyBlockMemberDungeons from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeons.js'; +import SkyBlockMemberDungeonsClasses from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsClasses.js'; +import SkyBlockMemberDungeonsFloor from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloor.js'; +import SkyBlockMemberDungeonsFloorRun from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsFloorRun.js'; +import SkyBlockMemberDungeonsMode from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsMode.js'; +import SkyBlockMemberDungeonsTreasureRun from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasureRun.js'; +import SkyBlockMemberDungeonsTreasuresChest from './Structures/SkyBlock/Member/Dungeons/SkyBlockMemberDungeonsTreasuresChest.js'; +import SkyBlockMemberFairySouls from './Structures/SkyBlock/Member/SkyBlockMemberFairySouls.js'; +import SkyBlockMemberInventories from './Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventories.js'; +import SkyBlockMemberInventoriesArmor from './Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmor.js'; +import SkyBlockMemberInventoriesArmorDecoded from './Structures/SkyBlock/Member/Inventories/Armor/SkyBlockMemberInventoriesArmorDecoded.js'; +import SkyBlockMemberInventoriesBackpack from './Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpack.js'; +import SkyBlockMemberInventoriesBackpackDecoded from './Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpackDecoded.js'; +import SkyBlockMemberInventoriesBackpacks from './Structures/SkyBlock/Member/Inventories/Backpacks/SkyBlockMemberInventoriesBackpacks.js'; +import SkyBlockMemberInventoriesBags from './Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBags.js'; +import SkyBlockMemberInventoriesBagsTalisman from './Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalisman.js'; +import SkyBlockMemberInventoriesBagsTalismanDecoded from './Structures/SkyBlock/Member/Inventories/Bags/SkyBlockMemberInventoriesBagsTalismanDecoded.js'; +import SkyBlockMemberInventoriesBaseInventory from './Structures/SkyBlock/Member/Inventories/SkyBlockMemberInventoriesBaseInventory.js'; +import SkyBlockMemberInventoriesEquipment from './Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipment.js'; +import SkyBlockMemberInventoriesEquipmentDecoded from './Structures/SkyBlock/Member/Inventories/Equipment/SkyBlockMemberInventoriesEquipmentDecoded.js'; +import SkyBlockMemberInventoriesInventory from './Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventory.js'; +import SkyBlockMemberInventoriesInventoryDecoded from './Structures/SkyBlock/Member/Inventories/Inventory/SkyBlockMemberInventoriesInventoryDecoded.js'; +import SkyBlockMemberJacobContest from './Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContest.js'; +import SkyBlockMemberJacobContests from './Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContests.js'; +import SkyBlockMemberJacobContestsMedals from './Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsMedals.js'; +import SkyBlockMemberJacobContestsPerks from './Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsPerks.js'; +import SkyBlockMemberJacobContestsUniqueBrackets from './Structures/SkyBlock/Member/JacobContests/SkyBlockMemberJacobContestsUniqueBrackets.js'; +import SkyBlockMemberLeveling from './Structures/SkyBlock/Member/SkyBlockMemberLeveling.js'; +import SkyBlockMemberMining from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMining.js'; +import SkyBlockMemberMiningCrystal from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningCrystal.js'; +import SkyBlockMemberMiningHotm from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotm.js'; +import SkyBlockMemberMiningHotmForge from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForge.js'; +import SkyBlockMemberMiningHotmForgeItem from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningHotmForgeItem.js'; +import SkyBlockMemberMiningPowder from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowder.js'; +import SkyBlockMemberMiningPowders from './Structures/SkyBlock/Member/Mining/SkyBlockMemberMiningPowders.js'; +import SkyBlockMemberObjectives from './Structures/SkyBlock/Member/SkyBlockMemberObjectives.js'; +import SkyBlockMemberPet from './Structures/SkyBlock/Member/Pets/SkyBlockMemberPet.js'; +import SkyBlockMemberPets from './Structures/SkyBlock/Member/Pets/SkyBlockMemberPets.js'; +import SkyBlockMemberPetsAutoPetRule from './Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPetRule.js'; +import SkyBlockMemberPetsAutoPets from './Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsAutoPets.js'; +import SkyBlockMemberPetsCare from './Structures/SkyBlock/Member/Pets/SkyBlockMemberPetsCare.js'; +import SkyBlockMemberPlayerData from './Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerData.js'; +import SkyBlockMemberPlayerDataActiveEffect from './Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataActiveEffect.js'; +import SkyBlockMemberPlayerDataMinion from './Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinion.js'; +import SkyBlockMemberPlayerDataMinions from './Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataMinions.js'; +import SkyBlockMemberPlayerDataSkills from './Structures/SkyBlock/Member/PlayerData/SkyBlockMemberPlayerDataSkills.js'; +import SkyBlockMemberPlayerStats from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStats.js'; +import SkyBlockMemberPlayerStatsAuctions from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctions.js'; +import SkyBlockMemberPlayerStatsAuctionsStats from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsAuctionsStats.js'; +import SkyBlockMemberPlayerStatsCandy from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsCandy.js'; +import SkyBlockMemberPlayerStatsEndIsland from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIsland.js'; +import SkyBlockMemberPlayerStatsEndIslandDragonFight from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFight.js'; +import SkyBlockMemberPlayerStatsEndIslandDragonFightDragon from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsEndIslandDragonFightDragon.js'; +import SkyBlockMemberPlayerStatsFishing from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsFishing.js'; +import SkyBlockMemberPlayerStatsGifts from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsGifts.js'; +import SkyBlockMemberPlayerStatsMythos from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsMythos.js'; +import SkyBlockMemberPlayerStatsSpookyFestival from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsSpookyFestival.js'; +import SkyBlockMemberPlayerStatsWinter from './Structures/SkyBlock/Member/PlayerStats/SkyBlockMemberPlayerStatsWinter.js'; +import SkyBlockMemberProfile from './Structures/SkyBlock/Member/SkyBlockMemberProfile.js'; +import SkyBlockMemberQuests from './Structures/SkyBlock/Member/Quests/SkyBlockMemberQuests.js'; +import SkyBlockMemberQuestsHarp from './Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarp.js'; +import SkyBlockMemberQuestsHarpSong from './Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsHarpSong.js'; +import SkyBlockMemberQuestsTrapper from './Structures/SkyBlock/Member/Quests/SkyBlockMemberQuestsTrapper.js'; +import SkyBlockMemberRift from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRift.js'; +import SkyBlockMemberRiftAccess from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftAccess.js'; +import SkyBlockMemberRiftBlackLagoon from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftBlackLagoon.js'; +import SkyBlockMemberRiftCastle from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftCastle.js'; +import SkyBlockMemberRiftDeadCats from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDeadCats.js'; +import SkyBlockMemberRiftDreamFarm from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftDreamFarm.js'; +import SkyBlockMemberRiftEnigma from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftEnigma.js'; +import SkyBlockMemberRiftGallery from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallery.js'; +import SkyBlockMemberRiftGallerySecuredTrophy from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftGallerySecuredTrophy.js'; +import SkyBlockMemberRiftInventory from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftInventory.js'; +import SkyBlockMemberRiftVillagePlaza from './Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlaza.js'; +import SkyBlockMemberRiftVillagePlazaBarry from './Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaBarry.js'; +import SkyBlockMemberRiftVillagePlazaCowboy from './Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaCowboy.js'; +import SkyBlockMemberRiftVillagePlazaMurder from './Structures/SkyBlock/Member/Rift/VillagePlaza/SkyBlockMemberRiftVillagePlazaMurder.js'; +import SkyBlockMemberRiftWestVillage from './Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillage.js'; +import SkyBlockMemberRiftWestVillageCrazyKloon from './Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageCrazyKloon.js'; +import SkyBlockMemberRiftWestVillageGlyphs from './Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageGlyphs.js'; +import SkyBlockMemberRiftWestVillageKatHouse from './Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageKatHouse.js'; +import SkyBlockMemberRiftWestVillageMirrorverse from './Structures/SkyBlock/Member/Rift/WestVillage/SkyBlockMemberRiftWestVillageMirrorverse.js'; +import SkyBlockMemberRiftWitherCage from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWitherCage.js'; +import SkyBlockMemberRiftWizardTower from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWizardTower.js'; +import SkyBlockMemberRiftWyldWoods from './Structures/SkyBlock/Member/Rift/SkyBlockMemberRiftWyldWoods.js'; +import SkyBlockMemberSlayer from './Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayer.js'; +import SkyBlockMemberSlayerClaimedLevels from './Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayerClaimedLevels.js'; +import SkyBlockMemberSlayers from './Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayers.js'; +import SkyBlockMemberSlayersQuest from './Structures/SkyBlock/Member/Slayers/SkyBlockMemberSlayersQuest.js'; +import SkyBlockMuseum from './Structures/SkyBlock/Museum/SkyBlockMuseum.js'; +import SkyBlockMuseumItem from './Structures/SkyBlock/Museum/SkyBlockMuseumItem.js'; +import SkyBlockMuseumMember from './Structures/SkyBlock/Museum/SkyBlockMuseumMember.js'; +import SkyBlockNews from './Structures/SkyBlock/News/SkyBlockNews.js'; +import SkyBlockPotionEffect from './Structures/SkyBlock/Potion/SkyBlockPotionEffect.js'; +import SkyBlockProfile from './Structures/SkyBlock/Profile/SkyBlockProfile.js'; +import SkyBlockProfileBanking from './Structures/SkyBlock/Profile/Banking/SkyBlockProfileBanking.js'; +import SkyBlockProfileCommunityUpgrades from './Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgrades.js'; +import SkyBlockProfileCommunityUpgradesUpgrade from './Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrade.js'; +import SkyBlockProfileCommunityUpgradesUpgraded from './Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgraded.js'; +import SkyBlockProfileCommunityUpgradesUpgrading from './Structures/SkyBlock/Profile/CommunityUpgrades/SkyBlockProfileCommunityUpgradesUpgrading.js'; +import SkyBlockProfilesBankingTransaction from './Structures/SkyBlock/Profile/Banking/SkyBlockProfilesBankingTransaction.js'; +import SkyBlockSkill from './Structures/SkyBlock/Skills/SkyBlockSkill.js'; +import SkyBlockSkillLevel from './Structures/SkyBlock/Skills/SkyBlockSkillLevel.js'; +import SkyBlockSkills from './Structures/SkyBlock/Skills/SkyBlockSkills.js'; +import SkyWars from './Structures/MiniGames/SkyWars/SkyWars.js'; +import SkyWarsHeads from './Structures/MiniGames/SkyWars/SkyWarsHeads.js'; +import SkyWarsKillsDeaths from './Structures/MiniGames/SkyWars/SkyWarsKillsDeaths.js'; +import SkyWarsKillsDeathsType from './Structures/MiniGames/SkyWars/SkyWarsKillsDeathsType.js'; +import SkyWarsKitsMythic from './Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythic.js'; +import SkyWarsKitsMythics from './Structures/MiniGames/SkyWars/SkyWarsKitsMythics/SkyWarsKitsMythics.js'; +import SkyWarsMega from './Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMega.js'; +import SkyWarsMegaKits from './Structures/MiniGames/SkyWars/SkyWarsMega/SkyWarsMegaKits.js'; +import SkyWarsMini from './Structures/MiniGames/SkyWars/SkyWarsMini.js'; +import SkyWarsMode from './Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsMode.js'; +import SkyWarsModePerk from './Structures/MiniGames/SkyWars/SkyWarsMode/SkyWarsModePerk.js'; +import SkyWarsPrivateGames from './Structures/MiniGames/SkyWars/SkyWarsPrivateGames.js'; +import SkyWarsRanked from './Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRanked.js'; +import SkyWarsRankedKits from './Structures/MiniGames/SkyWars/SkyWarsRanked/SkyWarsRankedKits.js'; +import SkyWarsSolo from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSolo.js'; +import SkyWarsSoloKits from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKits.js'; +import SkyWarsSoloKitsAdvanced from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsAdvanced.js'; +import SkyWarsSoloKitsBasic from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsBasic.js'; +import SkyWarsSoloKitsLab from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLab.js'; +import SkyWarsSoloKitsLabAdvanced from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabAdvanced.js'; +import SkyWarsSoloKitsLabBasic from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsLab/SkyWarsSoloKitsLabBasic.js'; +import SkyWarsSoloKitsMini from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsMini.js'; +import SkyWarsSoloKitsTourney from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourney.js'; +import SkyWarsSoloKitsTourneyAdvanced from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyAdvanced.js'; +import SkyWarsSoloKitsTourneyBasic from './Structures/MiniGames/SkyWars/SkyWarsSolo/SkyWarsSoloKits/SkyWarsSoloKitsTourney/SkyWarsSoloKitsTourneyBasic.js'; +import SkyWarsTeams from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeams.js'; +import SkyWarsTeamsKits from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKits.js'; +import SkyWarsTeamsKitsAttacking from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsAttacking.js'; +import SkyWarsTeamsKitsDefending from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsDefending.js'; +import SkyWarsTeamsKitsMining from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsMining.js'; +import SkyWarsTeamsKitsSupporting from './Structures/MiniGames/SkyWars/SkyWarsTeams/SkyWarsTeamsKits/SkyWarsTeamsKitsSupporting.js'; +import SmashHeoresHero from './Structures/MiniGames/SmashHeroes/SmashHeoresHero.js'; +import SmashHeroes from './Structures/MiniGames/SmashHeroes/SmashHeroes.js'; +import SmashHeroesMode from './Structures/MiniGames/SmashHeroes/SmashHeroesMode.js'; +import Soccer from './Structures/MiniGames/Arcade/Soccer.js'; +import SpeedUHC from './Structures/MiniGames/SpeedUHC/SpeedUHC.js'; +import SpeedUHCMode from './Structures/MiniGames/SpeedUHC/SpeedUHCMode.js'; +import Status from './Structures/Status.js'; +import TNTGames from './Structures/MiniGames/TNTGames/TNTGames.js'; +import TNTRun from './Structures/MiniGames/TNTGames/TNTRun.js'; +import TNTTag from './Structures/MiniGames/TNTGames/TNTTag.js'; +import TNTWizards from './Structures/MiniGames/TNTGames/TNTWizards.js'; +import ThrowOut from './Structures/MiniGames/Arcade/ThrowOut.js'; +import TieredAchievement from './Structures/Static/Achievements/TieredAchievement.js'; +import TurboKartRacers from './Structures/MiniGames/TurboKartRacers/TurboKartRacers.js'; +import TurboKartRacersMap from './Structures/MiniGames/TurboKartRacers/TurboKartRacersMap.js'; +import UHC from './Structures/MiniGames/UHC/UHC.js'; +import UHCGamemode from './Structures/MiniGames/UHC/UHCGamemode.js'; +import VampireZ from './Structures/MiniGames/VampireZ/VampireZ.js'; +import VampireZRole from './Structures/MiniGames/VampireZ/VampireZRole.js'; +import Walls from './Structures/MiniGames/Walls.js'; +import Warlords from './Structures/MiniGames/Warlords/Warlords.js'; +import WarlordsClass from './Structures/MiniGames/Warlords/WarlordsClass.js'; +import WatchdogStats from './Structures/WatchdogStats.js'; +import WoolGames from './Structures/MiniGames/WoolGames/WoolGames.js'; +import WoolHunt from './Structures/MiniGames/Arcade/WoolHunt.js'; +import WoolWars from './Structures/MiniGames/WoolGames/WoolWars.js'; +import WoolWarsClass from './Structures/MiniGames/WoolGames/WoolWarsClass.js'; +import Zombies from './Structures/MiniGames/Arcade/Zombies/Zombies.js'; +import ZombiesMap from './Structures/MiniGames/Arcade/Zombies/ZombiesMap.js'; +import ZombiesMapMode from './Structures/MiniGames/Arcade/Zombies/ZombiesMapMode.js'; + +export { + Client, + Errors, + Achievements, + Arcade, + ArcadeOptions, + ArenaBrawl, + ArenaBrawlMode, + BaseAchievement, + BaseKillDeathsType, + BaseSkyWarsMode, + BedWars, + BedWarsBeds, + BedWarsBoxes, + BedWarsChallenge, + BedWarsChallenges, + BedWarsEightOne, + BedWarsEightTwo, + BedWarsFavorites, + BedWarsFigurines, + BedWarsFourFour, + BedWarsFourThree, + BedWarsItemsPurchased, + BedWarsKillsDeaths, + BedWarsKillsDeathsType, + BedWarsMode, + BedWarsPractice, + BedWarsPracticeBridging, + BedWarsPracticeBridgingRecords, + BedWarsPracticeBridgingRecordsDistance, + BedWarsPracticeBridgingRecordsEevation, + BedWarsPracticeMode, + BedWarsPrivateGameSettings, + BedWarsResourcesCollected, + BedWarsSettings, + BedWarsSlumber, + BedWarsSlumberMinion, + BedWarsSlumberPhase, + BedWarsSlumberPhaseThree, + BedWarsSlumberQuest, + BedWarsSlumberQuestGamblerGeorge, + BedWarsSlumberQuestItem, + BedWarsSlumberQuestNPC, + BedWarsSlumberQuestNPCSBoolean, + BedWarsSlumberQuestNPCSNumber, + BedWarsSlumberQuestObjective, + BedWarsSlumberRoom, + BedWarsSlumberSandman, + BedWarsTwoFour, + BlitzSurvivalGames, + BlitzSurvivalGamesData, + BlitzSurvivalGamesKit, + BlitzSurvivalGamesPrivateGames, + BlockingDead, + Booster, + BowSpleef, + BuildBattle, + BuildBattleLastWin, + BuildBattleVotes, + CaptureTheWool, + Challenge, + Challenges, + Color, + CopsAndCrims, + CopsAndCrimsGamemode, + CopsAndCrimsGun, + DragonWars, + DrawTheirThing, + Dropper, + DropperMap, + Dtt, + Duels, + DuelsBridge, + DuelsGamemode, + DuelsMegaWalls, + DuelsOP, + DuelsSkyWars, + DuelsUHC, + EasterSimulator, + Emblem, + EmblemColors, + EnderSpleef, + FarmHunt, + FootBall, + GalaxyWars, + Game, + GameAchievements, + GameChallenges, + GameCounts, + GameCountsArcade, + GameCountsArcadeModes, + GameCountsBasicModes, + GameCountsBattleGround, + GameCountsBattleGroundModes, + GameCountsBedWars, + GameCountsBedWarsModes, + GameCountsBuildBattle, + GameCountsBuildBattleModes, + GameCountsDuels, + GameCountsDuelsModes, + GameCountsGames, + GameCountsGeneric, + GameCountsLegacy, + GameCountsLegacyModes, + GameCountsMCGO, + GameCountsMCGOModes, + GameCountsMurderMystery, + GameCountsMurderMysteryModes, + GameCountsPit, + GameCountsPitModes, + GameCountsReplay, + GameCountsReplayModes, + GameCountsSkyBlock, + GameCountsSkyBlockModes, + GameCountsSkyWars, + GameCountsSkyWarsModes, + GameCountsSpeedUHC, + GameCountsSuperSmash, + GameCountsSuperSmashModes, + GameCountsSurvivalGames, + GameCountsTNTGames, + GameCountsTNTGamesModes, + GameCountsUHC, + GameCountsUHCModes, + GameCountsWalls3, + GameCountsWalls3Modes, + GameCountsWoolGames, + GameCountsWoolGamesModes, + GameQuests, + GrinchSimulator, + Guild, + GuildAchievements, + GuildMember, + GuildRank, + HalloweenSimulator, + HideAndSeek, + HoleInTheWall, + House, + HypixelSports, + ItemBytes, + LawnMoower, + Leaderboard, + LeaderboardSettings, + MegaWalls, + MegaWallsKitStats, + MegaWallsModeStats, + MiniWalls, + MurderMystery, + MurderMysteryDescent, + MurderMysteryDescentItem, + MurderMysteryFavorites, + MurderMysteryGamemode, + MurderMysteryKnifeSkinPrestige, + MurderMysteryKnifeSkinPrestigeXp, + MurderMysteryMap, + OneInTheQuiver, + OneTimeAchievement, + PVPRun, + Paintball, + PartyGames, + PartyGamesGame, + Pit, + PitInventoryItem, + Player, + PlayerAchievements, + PlayerAchievementsRewards, + PlayerAchievementsTotem, + PlayerAdventRewards, + PlayerAdventRewardsDay, + PlayerCosmetics, + PlayerCosmeticsPet, + PlayerCosmeticsPets, + PlayerCosmeticsPetsConsumables, + PlayerGifting, + PlayerHousing, + PlayerHousingGivenCookies, + PlayerHousingPlayerSettings, + PlayerParkour, + PlayerQuest, + PlayerQuestCompletion, + PlayerQuestCompletions, + PlayerQuests, + PlayerRankPurchase, + PlayerRewards, + PlayerRewardsMonthlyCrate, + PlayerScorpiusBribe, + PlayerSeasonalChristmasYear, + PlayerSeasonalChristmasYearAdventRewards, + PlayerSeasonalChristmasYearLeveling, + PlayerSocialMedia, + PlayerStats, + PlayerTourney, + PlayerTourneyData, + Quakecraft, + QuakecraftMode, + Quest, + QuestObjective, + Quests, + RPG16, + RecentGame, + SantaSays, + SantaSimulator, + ScubaSimulator, + SheepWars, + SimonSays, + SkyBlockAuction, + SkyBlockAuctionBid, + SkyBlockAuctionInfo, + SkyBlockBaseAuction, + SkyBlockBaseAuctionInfo, + SkyBlockBazaar, + SkyBlockBazaarProduct, + SkyBlockBazaarProductOrder, + SkyBlockBazaarQuickStatus, + SkyBlockBingo, + SkyBlockBingoGoal, + SkyBlockCollection, + SkyBlockCollectionTier, + SkyBlockCollections, + SkyBlockElection, + SkyBlockElectionCandidate, + SkyBlockElectionCandidatePerk, + SkyBlockElectionData, + SkyBlockFireSale, + SkyBlockGarden, + SkyBlockGardenActiveVisitor, + SkyBlockGardenActiveVisitorRequirement, + SkyBlockGardenComposter, + SkyBlockGardenComposterUpgrades, + SkyBlockGardenCropMilestones, + SkyBlockGardenCropsUpgrades, + SkyBlockGardenVisitors, + SkyBlockInventoryItem, + SkyBlockInventoryItemAttribute, + SkyBlockInventoryItemEnchantment, + SkyBlockInventoryItemRune, + SkyBlockItem, + SkyBlockMember, + SkyBlockMemberAccessoryBag, + SkyBlockMemberAccessoryBagTuning, + SkyBlockMemberAccessoryBagTuningSlot, + SkyBlockMemberBestiary, + SkyBlockMemberChocolateFactory, + SkyBlockMemberChocolateFactoryEggs, + SkyBlockMemberChocolateFactoryEmployees, + SkyBlockMemberChocolateFactoryHitmen, + SkyBlockMemberChocolateFactoryTimeTower, + SkyBlockMemberChocolateFactoryUpgrades, + SkyBlockMemberCrimsonIsle, + SkyBlockMemberCrimsonIsleAbiphone, + SkyBlockMemberCrimsonIsleDojo, + SkyBlockMemberCrimsonIsleDojoMinigame, + SkyBlockMemberCrimsonIsleKuudra, + SkyBlockMemberCrimsonIsleKuudraPartyFinder, + SkyBlockMemberCrimsonIsleMatriarch, + SkyBlockMemberCrimsonIsleTrophyFish, + SkyBlockMemberCrimsonIsleTrophyFishCaught, + SkyBlockMemberCrimsonIsleTrophyFishFish, + SkyBlockMemberCurrencies, + SkyBlockMemberDungeons, + SkyBlockMemberDungeonsClasses, + SkyBlockMemberDungeonsFloor, + SkyBlockMemberDungeonsFloorRun, + SkyBlockMemberDungeonsMode, + SkyBlockMemberDungeonsTreasureRun, + SkyBlockMemberDungeonsTreasuresChest, + SkyBlockMemberFairySouls, + SkyBlockMemberInventories, + SkyBlockMemberInventoriesArmor, + SkyBlockMemberInventoriesArmorDecoded, + SkyBlockMemberInventoriesBackpack, + SkyBlockMemberInventoriesBackpackDecoded, + SkyBlockMemberInventoriesBackpacks, + SkyBlockMemberInventoriesBags, + SkyBlockMemberInventoriesBagsTalisman, + SkyBlockMemberInventoriesBagsTalismanDecoded, + SkyBlockMemberInventoriesBaseInventory, + SkyBlockMemberInventoriesEquipment, + SkyBlockMemberInventoriesEquipmentDecoded, + SkyBlockMemberInventoriesInventory, + SkyBlockMemberInventoriesInventoryDecoded, + SkyBlockMemberJacobContest, + SkyBlockMemberJacobContests, + SkyBlockMemberJacobContestsMedals, + SkyBlockMemberJacobContestsPerks, + SkyBlockMemberJacobContestsUniqueBrackets, + SkyBlockMemberLeveling, + SkyBlockMemberMining, + SkyBlockMemberMiningCrystal, + SkyBlockMemberMiningHotm, + SkyBlockMemberMiningHotmForge, + SkyBlockMemberMiningHotmForgeItem, + SkyBlockMemberMiningPowder, + SkyBlockMemberMiningPowders, + SkyBlockMemberObjectives, + SkyBlockMemberPet, + SkyBlockMemberPets, + SkyBlockMemberPetsAutoPetRule, + SkyBlockMemberPetsAutoPets, + SkyBlockMemberPetsCare, + SkyBlockMemberPlayerData, + SkyBlockMemberPlayerDataActiveEffect, + SkyBlockMemberPlayerDataMinion, + SkyBlockMemberPlayerDataMinions, + SkyBlockMemberPlayerDataSkills, + SkyBlockMemberPlayerStats, + SkyBlockMemberPlayerStatsAuctions, + SkyBlockMemberPlayerStatsAuctionsStats, + SkyBlockMemberPlayerStatsCandy, + SkyBlockMemberPlayerStatsEndIsland, + SkyBlockMemberPlayerStatsEndIslandDragonFight, + SkyBlockMemberPlayerStatsEndIslandDragonFightDragon, + SkyBlockMemberPlayerStatsFishing, + SkyBlockMemberPlayerStatsGifts, + SkyBlockMemberPlayerStatsMythos, + SkyBlockMemberPlayerStatsSpookyFestival, + SkyBlockMemberPlayerStatsWinter, + SkyBlockMemberProfile, + SkyBlockMemberQuests, + SkyBlockMemberQuestsHarp, + SkyBlockMemberQuestsHarpSong, + SkyBlockMemberQuestsTrapper, + SkyBlockMemberRift, + SkyBlockMemberRiftAccess, + SkyBlockMemberRiftBlackLagoon, + SkyBlockMemberRiftCastle, + SkyBlockMemberRiftDeadCats, + SkyBlockMemberRiftDreamFarm, + SkyBlockMemberRiftEnigma, + SkyBlockMemberRiftGallery, + SkyBlockMemberRiftGallerySecuredTrophy, + SkyBlockMemberRiftInventory, + SkyBlockMemberRiftVillagePlaza, + SkyBlockMemberRiftVillagePlazaBarry, + SkyBlockMemberRiftVillagePlazaCowboy, + SkyBlockMemberRiftVillagePlazaMurder, + SkyBlockMemberRiftWestVillage, + SkyBlockMemberRiftWestVillageCrazyKloon, + SkyBlockMemberRiftWestVillageGlyphs, + SkyBlockMemberRiftWestVillageKatHouse, + SkyBlockMemberRiftWestVillageMirrorverse, + SkyBlockMemberRiftWitherCage, + SkyBlockMemberRiftWizardTower, + SkyBlockMemberRiftWyldWoods, + SkyBlockMemberSlayer, + SkyBlockMemberSlayerClaimedLevels, + SkyBlockMemberSlayers, + SkyBlockMemberSlayersQuest, + SkyBlockMuseum, + SkyBlockMuseumItem, + SkyBlockMuseumMember, + SkyBlockNews, + SkyBlockPotionEffect, + SkyBlockProfile, + SkyBlockProfileBanking, + SkyBlockProfileCommunityUpgrades, + SkyBlockProfileCommunityUpgradesUpgrade, + SkyBlockProfileCommunityUpgradesUpgraded, + SkyBlockProfileCommunityUpgradesUpgrading, + SkyBlockProfilesBankingTransaction, + SkyBlockSkill, + SkyBlockSkillLevel, + SkyBlockSkills, + SkyWars, + SkyWarsHeads, + SkyWarsKillsDeaths, + SkyWarsKillsDeathsType, + SkyWarsKitsMythic, + SkyWarsKitsMythics, + SkyWarsMega, + SkyWarsMegaKits, + SkyWarsMini, + SkyWarsMode, + SkyWarsModePerk, + SkyWarsPrivateGames, + SkyWarsRanked, + SkyWarsRankedKits, + SkyWarsSolo, + SkyWarsSoloKits, + SkyWarsSoloKitsAdvanced, + SkyWarsSoloKitsBasic, + SkyWarsSoloKitsLab, + SkyWarsSoloKitsLabAdvanced, + SkyWarsSoloKitsLabBasic, + SkyWarsSoloKitsMini, + SkyWarsSoloKitsTourney, + SkyWarsSoloKitsTourneyAdvanced, + SkyWarsSoloKitsTourneyBasic, + SkyWarsTeams, + SkyWarsTeamsKits, + SkyWarsTeamsKitsAttacking, + SkyWarsTeamsKitsDefending, + SkyWarsTeamsKitsMining, + SkyWarsTeamsKitsSupporting, + SmashHeoresHero, + SmashHeroes, + SmashHeroesMode, + Soccer, + SpeedUHC, + SpeedUHCMode, + Status, + TNTGames, + TNTRun, + TNTTag, + TNTWizards, + ThrowOut, + TieredAchievement, + TurboKartRacers, + TurboKartRacersMap, + UHC, + UHCGamemode, + VampireZ, + VampireZRole, + Walls, + Warlords, + WarlordsClass, + WatchdogStats, + WoolGames, + WoolHunt, + WoolWars, + WoolWarsClass, + Zombies, + ZombiesMap, + ZombiesMapMode +}; + +export default { + Client, + Errors, + Achievements, + Arcade, + ArcadeOptions, + ArenaBrawl, + ArenaBrawlMode, + BaseAchievement, + BaseKillDeathsType, + BaseSkyWarsMode, + BedWars, + BedWarsBeds, + BedWarsBoxes, + BedWarsChallenge, + BedWarsChallenges, + BedWarsEightOne, + BedWarsEightTwo, + BedWarsFavorites, + BedWarsFigurines, + BedWarsFourFour, + BedWarsFourThree, + BedWarsItemsPurchased, + BedWarsKillsDeaths, + BedWarsKillsDeathsType, + BedWarsMode, + BedWarsPractice, + BedWarsPracticeBridging, + BedWarsPracticeBridgingRecords, + BedWarsPracticeBridgingRecordsDistance, + BedWarsPracticeBridgingRecordsEevation, + BedWarsPracticeMode, + BedWarsPrivateGameSettings, + BedWarsResourcesCollected, + BedWarsSettings, + BedWarsSlumber, + BedWarsSlumberMinion, + BedWarsSlumberPhase, + BedWarsSlumberPhaseThree, + BedWarsSlumberQuest, + BedWarsSlumberQuestGamblerGeorge, + BedWarsSlumberQuestItem, + BedWarsSlumberQuestNPC, + BedWarsSlumberQuestNPCSBoolean, + BedWarsSlumberQuestNPCSNumber, + BedWarsSlumberQuestObjective, + BedWarsSlumberRoom, + BedWarsSlumberSandman, + BedWarsTwoFour, + BlitzSurvivalGames, + BlitzSurvivalGamesData, + BlitzSurvivalGamesKit, + BlitzSurvivalGamesPrivateGames, + BlockingDead, + Booster, + BowSpleef, + BuildBattle, + BuildBattleLastWin, + BuildBattleVotes, + CaptureTheWool, + Challenge, + Challenges, + Color, + CopsAndCrims, + CopsAndCrimsGamemode, + CopsAndCrimsGun, + DragonWars, + DrawTheirThing, + Dropper, + DropperMap, + Dtt, + Duels, + DuelsBridge, + DuelsGamemode, + DuelsMegaWalls, + DuelsOP, + DuelsSkyWars, + DuelsUHC, + EasterSimulator, + Emblem, + EmblemColors, + EnderSpleef, + FarmHunt, + FootBall, + GalaxyWars, + Game, + GameAchievements, + GameChallenges, + GameCounts, + GameCountsArcade, + GameCountsArcadeModes, + GameCountsBasicModes, + GameCountsBattleGround, + GameCountsBattleGroundModes, + GameCountsBedWars, + GameCountsBedWarsModes, + GameCountsBuildBattle, + GameCountsBuildBattleModes, + GameCountsDuels, + GameCountsDuelsModes, + GameCountsGames, + GameCountsGeneric, + GameCountsLegacy, + GameCountsLegacyModes, + GameCountsMCGO, + GameCountsMCGOModes, + GameCountsMurderMystery, + GameCountsMurderMysteryModes, + GameCountsPit, + GameCountsPitModes, + GameCountsReplay, + GameCountsReplayModes, + GameCountsSkyBlock, + GameCountsSkyBlockModes, + GameCountsSkyWars, + GameCountsSkyWarsModes, + GameCountsSpeedUHC, + GameCountsSuperSmash, + GameCountsSuperSmashModes, + GameCountsSurvivalGames, + GameCountsTNTGames, + GameCountsTNTGamesModes, + GameCountsUHC, + GameCountsUHCModes, + GameCountsWalls3, + GameCountsWalls3Modes, + GameCountsWoolGames, + GameCountsWoolGamesModes, + GameQuests, + GrinchSimulator, + Guild, + GuildAchievements, + GuildMember, + GuildRank, + HalloweenSimulator, + HideAndSeek, + HoleInTheWall, + House, + HypixelSports, + ItemBytes, + LawnMoower, + Leaderboard, + LeaderboardSettings, + MegaWalls, + MegaWallsKitStats, + MegaWallsModeStats, + MiniWalls, + MurderMystery, + MurderMysteryDescent, + MurderMysteryDescentItem, + MurderMysteryFavorites, + MurderMysteryGamemode, + MurderMysteryKnifeSkinPrestige, + MurderMysteryKnifeSkinPrestigeXp, + MurderMysteryMap, + OneInTheQuiver, + OneTimeAchievement, + PVPRun, + Paintball, + PartyGames, + PartyGamesGame, + Pit, + PitInventoryItem, + Player, + PlayerAchievements, + PlayerAchievementsRewards, + PlayerAchievementsTotem, + PlayerAdventRewards, + PlayerAdventRewardsDay, + PlayerCosmetics, + PlayerCosmeticsPet, + PlayerCosmeticsPets, + PlayerCosmeticsPetsConsumables, + PlayerGifting, + PlayerHousing, + PlayerHousingGivenCookies, + PlayerHousingPlayerSettings, + PlayerParkour, + PlayerQuest, + PlayerQuestCompletion, + PlayerQuestCompletions, + PlayerQuests, + PlayerRankPurchase, + PlayerRewards, + PlayerRewardsMonthlyCrate, + PlayerScorpiusBribe, + PlayerSeasonalChristmasYear, + PlayerSeasonalChristmasYearAdventRewards, + PlayerSeasonalChristmasYearLeveling, + PlayerSocialMedia, + PlayerStats, + PlayerTourney, + PlayerTourneyData, + Quakecraft, + QuakecraftMode, + Quest, + QuestObjective, + Quests, + RPG16, + RecentGame, + SantaSays, + SantaSimulator, + ScubaSimulator, + SheepWars, + SimonSays, + SkyBlockAuction, + SkyBlockAuctionBid, + SkyBlockAuctionInfo, + SkyBlockBaseAuction, + SkyBlockBaseAuctionInfo, + SkyBlockBazaar, + SkyBlockBazaarProduct, + SkyBlockBazaarProductOrder, + SkyBlockBazaarQuickStatus, + SkyBlockBingo, + SkyBlockBingoGoal, + SkyBlockCollection, + SkyBlockCollectionTier, + SkyBlockCollections, + SkyBlockElection, + SkyBlockElectionCandidate, + SkyBlockElectionCandidatePerk, + SkyBlockElectionData, + SkyBlockFireSale, + SkyBlockGarden, + SkyBlockGardenActiveVisitor, + SkyBlockGardenActiveVisitorRequirement, + SkyBlockGardenComposter, + SkyBlockGardenComposterUpgrades, + SkyBlockGardenCropMilestones, + SkyBlockGardenCropsUpgrades, + SkyBlockGardenVisitors, + SkyBlockInventoryItem, + SkyBlockInventoryItemAttribute, + SkyBlockInventoryItemEnchantment, + SkyBlockInventoryItemRune, + SkyBlockItem, + SkyBlockMember, + SkyBlockMemberAccessoryBag, + SkyBlockMemberAccessoryBagTuning, + SkyBlockMemberAccessoryBagTuningSlot, + SkyBlockMemberBestiary, + SkyBlockMemberChocolateFactory, + SkyBlockMemberChocolateFactoryEggs, + SkyBlockMemberChocolateFactoryEmployees, + SkyBlockMemberChocolateFactoryHitmen, + SkyBlockMemberChocolateFactoryTimeTower, + SkyBlockMemberChocolateFactoryUpgrades, + SkyBlockMemberCrimsonIsle, + SkyBlockMemberCrimsonIsleAbiphone, + SkyBlockMemberCrimsonIsleDojo, + SkyBlockMemberCrimsonIsleDojoMinigame, + SkyBlockMemberCrimsonIsleKuudra, + SkyBlockMemberCrimsonIsleKuudraPartyFinder, + SkyBlockMemberCrimsonIsleMatriarch, + SkyBlockMemberCrimsonIsleTrophyFish, + SkyBlockMemberCrimsonIsleTrophyFishCaught, + SkyBlockMemberCrimsonIsleTrophyFishFish, + SkyBlockMemberCurrencies, + SkyBlockMemberDungeons, + SkyBlockMemberDungeonsClasses, + SkyBlockMemberDungeonsFloor, + SkyBlockMemberDungeonsFloorRun, + SkyBlockMemberDungeonsMode, + SkyBlockMemberDungeonsTreasureRun, + SkyBlockMemberDungeonsTreasuresChest, + SkyBlockMemberFairySouls, + SkyBlockMemberInventories, + SkyBlockMemberInventoriesArmor, + SkyBlockMemberInventoriesArmorDecoded, + SkyBlockMemberInventoriesBackpack, + SkyBlockMemberInventoriesBackpackDecoded, + SkyBlockMemberInventoriesBackpacks, + SkyBlockMemberInventoriesBags, + SkyBlockMemberInventoriesBagsTalisman, + SkyBlockMemberInventoriesBagsTalismanDecoded, + SkyBlockMemberInventoriesBaseInventory, + SkyBlockMemberInventoriesEquipment, + SkyBlockMemberInventoriesEquipmentDecoded, + SkyBlockMemberInventoriesInventory, + SkyBlockMemberInventoriesInventoryDecoded, + SkyBlockMemberJacobContest, + SkyBlockMemberJacobContests, + SkyBlockMemberJacobContestsMedals, + SkyBlockMemberJacobContestsPerks, + SkyBlockMemberJacobContestsUniqueBrackets, + SkyBlockMemberLeveling, + SkyBlockMemberMining, + SkyBlockMemberMiningCrystal, + SkyBlockMemberMiningHotm, + SkyBlockMemberMiningHotmForge, + SkyBlockMemberMiningHotmForgeItem, + SkyBlockMemberMiningPowder, + SkyBlockMemberMiningPowders, + SkyBlockMemberObjectives, + SkyBlockMemberPet, + SkyBlockMemberPets, + SkyBlockMemberPetsAutoPetRule, + SkyBlockMemberPetsAutoPets, + SkyBlockMemberPetsCare, + SkyBlockMemberPlayerData, + SkyBlockMemberPlayerDataActiveEffect, + SkyBlockMemberPlayerDataMinion, + SkyBlockMemberPlayerDataMinions, + SkyBlockMemberPlayerDataSkills, + SkyBlockMemberPlayerStats, + SkyBlockMemberPlayerStatsAuctions, + SkyBlockMemberPlayerStatsAuctionsStats, + SkyBlockMemberPlayerStatsCandy, + SkyBlockMemberPlayerStatsEndIsland, + SkyBlockMemberPlayerStatsEndIslandDragonFight, + SkyBlockMemberPlayerStatsEndIslandDragonFightDragon, + SkyBlockMemberPlayerStatsFishing, + SkyBlockMemberPlayerStatsGifts, + SkyBlockMemberPlayerStatsMythos, + SkyBlockMemberPlayerStatsSpookyFestival, + SkyBlockMemberPlayerStatsWinter, + SkyBlockMemberProfile, + SkyBlockMemberQuests, + SkyBlockMemberQuestsHarp, + SkyBlockMemberQuestsHarpSong, + SkyBlockMemberQuestsTrapper, + SkyBlockMemberRift, + SkyBlockMemberRiftAccess, + SkyBlockMemberRiftBlackLagoon, + SkyBlockMemberRiftCastle, + SkyBlockMemberRiftDeadCats, + SkyBlockMemberRiftDreamFarm, + SkyBlockMemberRiftEnigma, + SkyBlockMemberRiftGallery, + SkyBlockMemberRiftGallerySecuredTrophy, + SkyBlockMemberRiftInventory, + SkyBlockMemberRiftVillagePlaza, + SkyBlockMemberRiftVillagePlazaBarry, + SkyBlockMemberRiftVillagePlazaCowboy, + SkyBlockMemberRiftVillagePlazaMurder, + SkyBlockMemberRiftWestVillage, + SkyBlockMemberRiftWestVillageCrazyKloon, + SkyBlockMemberRiftWestVillageGlyphs, + SkyBlockMemberRiftWestVillageKatHouse, + SkyBlockMemberRiftWestVillageMirrorverse, + SkyBlockMemberRiftWitherCage, + SkyBlockMemberRiftWizardTower, + SkyBlockMemberRiftWyldWoods, + SkyBlockMemberSlayer, + SkyBlockMemberSlayerClaimedLevels, + SkyBlockMemberSlayers, + SkyBlockMemberSlayersQuest, + SkyBlockMuseum, + SkyBlockMuseumItem, + SkyBlockMuseumMember, + SkyBlockNews, + SkyBlockPotionEffect, + SkyBlockProfile, + SkyBlockProfileBanking, + SkyBlockProfileCommunityUpgrades, + SkyBlockProfileCommunityUpgradesUpgrade, + SkyBlockProfileCommunityUpgradesUpgraded, + SkyBlockProfileCommunityUpgradesUpgrading, + SkyBlockProfilesBankingTransaction, + SkyBlockSkill, + SkyBlockSkillLevel, + SkyBlockSkills, + SkyWars, + SkyWarsHeads, + SkyWarsKillsDeaths, + SkyWarsKillsDeathsType, + SkyWarsKitsMythic, + SkyWarsKitsMythics, + SkyWarsMega, + SkyWarsMegaKits, + SkyWarsMini, + SkyWarsMode, + SkyWarsModePerk, + SkyWarsPrivateGames, + SkyWarsRanked, + SkyWarsRankedKits, + SkyWarsSolo, + SkyWarsSoloKits, + SkyWarsSoloKitsAdvanced, + SkyWarsSoloKitsBasic, + SkyWarsSoloKitsLab, + SkyWarsSoloKitsLabAdvanced, + SkyWarsSoloKitsLabBasic, + SkyWarsSoloKitsMini, + SkyWarsSoloKitsTourney, + SkyWarsSoloKitsTourneyAdvanced, + SkyWarsSoloKitsTourneyBasic, + SkyWarsTeams, + SkyWarsTeamsKits, + SkyWarsTeamsKitsAttacking, + SkyWarsTeamsKitsDefending, + SkyWarsTeamsKitsMining, + SkyWarsTeamsKitsSupporting, + SmashHeoresHero, + SmashHeroes, + SmashHeroesMode, + Soccer, + SpeedUHC, + SpeedUHCMode, + Status, + TNTGames, + TNTRun, + TNTTag, + TNTWizards, + ThrowOut, + TieredAchievement, + TurboKartRacers, + TurboKartRacersMap, + UHC, + UHCGamemode, + VampireZ, + VampireZRole, + Walls, + Warlords, + WarlordsClass, + WatchdogStats, + WoolGames, + WoolHunt, + WoolWars, + WoolWarsClass, + Zombies, + ZombiesMap, + ZombiesMapMode +}; diff --git a/src/structures/APIIncident.js b/src/structures/APIIncident.js deleted file mode 100644 index 8da44522c..000000000 --- a/src/structures/APIIncident.js +++ /dev/null @@ -1,71 +0,0 @@ -const regex = /https:\/\/status.hypixel.net\/incidents\/([a-z0-9]+)/; -/** - * API incident class - */ -class APIIncident { - /** - * @param {object} data API incident data - */ - constructor(data) { - /** - * Link to incident - * @type {string|null} - */ - this.link = data.link || null; - /** - * Timestamp when investigation was started as Date object - * @type {object|null} - */ - this.start = data.pubDate ? new Date(data.pubDate) : null; - /** - * Formatted timestamp when investigation was started - * @type {string|null} - */ - this.startFormatted = data.pubDate || null; - /** - * Timestamp when investigation was started as Date - * @type {Date|null} - */ - this.startTimestamp = new Date(data.pubDate).getTime() || null; - /** - * Incident author - * @type {string|null} - */ - this.author = data.creator || null; - /** - * Content as HTML - * @type {string|null} - */ - this.HTMLContent = data.content || null; - /** - * Content snippet - * @type {string|null} - */ - this.snippet = data.contentSnippet || null; - /** - * GUID - * @type {string|null} - */ - this.guid = data.guid ? regex.exec(data.guid)[1] : null; - /** - * Incident categories - * @type {string[]} - */ - this.categories = data.categories || []; - /** - * Whether the incident is resolved/completed or not - * @author linearaccelerator - * @type {boolean} - */ - this.isResolved = this.HTMLContent.includes('Resolved -') || this.HTMLContent.includes('Completed -'); - } - /** - * HTML Content - * @return {string} - */ - toString() { - return this.HTMLContent; - } -} - -module.exports = APIIncident; diff --git a/src/structures/APIStatus.js b/src/structures/APIStatus.js deleted file mode 100644 index 8b95df58a..000000000 --- a/src/structures/APIStatus.js +++ /dev/null @@ -1,46 +0,0 @@ -const APIIncident = require('./APIIncident'); -/** - * API status class - */ -class APIStatus { - /** - * @param {object} data API status data - */ - constructor(data) { - /** - * Source url - * @type {string|null} - */ - this.sourceUrl = data.feedUrl || null; - /** - * Title - * @type {string|null} - */ - this.title = data.title || null; - /** - * Description - * @type {string|null} - */ - this.description = data.description || null; - /** - * API incident - * @type {APIIncident[]} - */ - this.incidents = data.items.map((x) => new APIIncident(x)); - /** - * All incidents that aren't completed/resolved - * @author linearaccelerator - * @type {APIIncident[]} - */ - this.currentIncidents = this.incidents.filter((i) => !i.isResolved); - } - /** - * Status Title - * @return {string} - */ - toString() { - return this.title; - } -} - -module.exports = APIStatus; diff --git a/src/structures/Boosters/Booster.js b/src/structures/Boosters/Booster.js deleted file mode 100644 index b43b1cece..000000000 --- a/src/structures/Boosters/Booster.js +++ /dev/null @@ -1,84 +0,0 @@ -const Game = require('../Game'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function parseType(data) { - if (true === data.stacked) return 'STACKED'; - if (!data.stacked) return 'QUEUED'; - return 'ACTIVE'; -} - -/** - * Booster class - */ -class Booster { - /** - * @param {object} data - */ - constructor(data) { - /** - * Booster's purchaser's UUID - * @type {string} - */ - this.purchaser = data.purchaserUuid; - /** - * Booster's multiplier - * @type {number} - */ - this.amount = data.amount; - /** - * Booster's length in seconds - * @type {number} - */ - this.originalLength = data.originalLength; - /** - * Length remaining in seconds - * @type {number} - */ - this.remaining = data.length; - /** - * Date activated timestamp - * @type {number} - */ - this.activatedTimestamp = data.dateActivated; - /** - * Date activated - * @type {Date} - */ - this.activated = new Date(data.dateActivated); - /** - * Game type - * @type {Game} - */ - this.game = data.gameType ? new Game(data.gameType) : null; - /** - * Is Booster Active - * @type {boolean} - */ - this.isActive = Array.isArray(data.stacked); - /** - * Booster type : either 'QUEUED', 'STACKED'* or 'ACTIVE'. - * *STACKED is always queued, when active, they disappear into stackers of the active game booster - * @type {string} - */ - this.type = parseType(data); - /** - * Stacked by ( if any ) - * @type {string[]} - */ - this.stackers = Array.isArray(data.stacked) ? Array.from(data.stacked) : []; - /** - * Possibly expired booster - * Works by checking if date.length is negative - * @type {boolean} - */ - this.expired = 0 > data.length; - } - /** - * Beautiful format - * @return {string} - */ - toString() { - return `${this.purchaser}'s booster in ${this.game}`; - } -} -module.exports = Booster; diff --git a/src/structures/Color.js b/src/structures/Color.js deleted file mode 100644 index 9c50d6a73..000000000 --- a/src/structures/Color.js +++ /dev/null @@ -1,174 +0,0 @@ -/** - * Color class - */ -class Color { - /** - * @param {ColorCode} color Color code - */ - constructor(color) { - this.color = color; - } - - /** - * Returns regular color name - * @return {ColorString} - */ - toString() { - const ColorStrings = { - BLACK: 'Black', - DARK_BLUE: 'Dark Blue', - DARK_GREEN: 'Dark Green', - DARK_AQUA: 'Dark Aqua', - DARK_RED: 'Dark Red', - DARK_PURPLE: 'Dark Purple', - GOLD: 'Gold', - GRAY: 'Gray', - DARK_GRAY: 'Dark Gray', - BLUE: 'Blue', - GREEN: 'Green', - AQUA: 'Aqua', - RED: 'Red', - LIGHT_PURPLE: 'Light Purple', - YELLOW: 'Yellow', - WHITE: 'White' - }; - return ColorStrings[this.color]; - } - - /** - * Returns color HEX code - * @return {ColorHex} - */ - toHex() { - const ColorHex = { - BLACK: '#000000', - DARK_BLUE: '#0000AA', - DARK_GREEN: '#008000', - DARK_AQUA: '#00AAAA', - DARK_RED: '#AA0000', - DARK_PURPLE: '#AA00AA', - GOLD: '#FFAA00', - GRAY: '#AAAAAA', - DARK_GRAY: '#555555', - BLUE: '#5555FF', - GREEN: '#3CE63C', - AQUA: '#3CE6E6', - RED: '#FF5555', - LIGHT_PURPLE: '#FF55FF', - YELLOW: '#FFFF55', - WHITE: '#FFFFFF' - }; - return ColorHex[this.color]; - } - - /** - * Returns color code - * @return {ColorCode} - */ - toCode() { - return this.color; - } - - /** - * Returns color code - * @return {InGameCode} - */ - toInGameCode() { - const InGameCodes = { - BLACK: '§0', - DARK_BLUE: '§1', - DARK_GREEN: '§2', - DARK_AQUA: '§3', - DARK_RED: '§4', - DARK_PURPLE: '§5', - GOLD: '§6', - GRAY: '§7', - DARK_GRAY: '§8', - BLUE: '§9', - GREEN: '§a', - AQUA: '§b', - RED: '§c', - LIGHT_PURPLE: '§d', - YELLOW: '§e', - WHITE: '§f' - }; - return InGameCodes[this.color]; - } -} -/** - * @typedef {string} ColorCode - * * 'BLACK' - * * 'DARK_BLUE' - * * 'DARK_GREEN' - * * 'DARK_AQUA' - * * 'DARK_RED' - * * 'DARK_PURPLE' - * * 'GOLD' - * * 'GRAY' - * * 'DARK_GRAY' - * * 'BLUE' - * * 'GREEN' - * * 'AQUA' - * * 'RED' - * * 'LIGHT_PURPLE' - * * 'YELLOW' - * * 'WHITE' - */ -/** - * @typedef {string} ColorString - * * BLACK: 'Black' - * * DARK_BLUE: 'Dark Blue' - * * DARK_GREEN: 'Dark Green' - * * DARK_AQUA: 'Dark Aqua' - * * DARK_RED: 'Dark Red' - * * DARK_PURPLE: 'Dark Purple' - * * GOLD: 'Gold' - * * GRAY: 'Gray' - * * DARK_GRAY: 'Dark Gray' - * * BLUE: 'Blue`' - * * GREEN: 'Green' - * * AQUA: 'Aqua' - * * RED: 'Red' - * * LIGHT_PURPLE: 'Light Purple' - * * YELLOW: 'Yellow' - * * WHITE: 'White' - */ -/** - * @typedef {string} ColorHex - * * BLACK: '#000000' - * * DARK_BLUE: '#0000AA' - * * DARK_GREEN: '#008000' - * * DARK_AQUA: '#00AAAA' - * * DARK_RED: '#AA0000' - * * DARK_PURPLE: '#AA00AA' - * * GOLD: '#FFAA00' - * * GRAY: '#AAAAAA' - * * DARK_GRAY: '#555555' - * * BLUE: '#5555FF' - * * GREEN: '#3CE63C' - * * AQUA: '#3CE6E6' - * * RED: '#FF5555' - * * LIGHT_PURPLE: '#FF55FF' - * * YELLOW: '#FFFF55' - * * WHITE: '#FFFFFF' - */ -/** - * @typedef {string} InGameCode - * * BLACK: '§0' - * * DARK_BLUE: '§1' - * * DARK_GREEN: '§2' - * * DARK_AQUA: '§3' - * * DARK_RED: '§4' - * * DARK_PURPLE: '§5' - * * GOLD: '§6' - * * GRAY: '§7' - * * DARK_GRAY: '§8' - * * BLUE: '§9' - * * GREEN: '§a' - * * AQUA: '§b' - * * RED: '§c' - * * LIGHT_PURPLE: '§d' - * * YELLOW: '§e' - * * WHITE: '§f' - */ -module.exports = Color; diff --git a/src/structures/Game.js b/src/structures/Game.js deleted file mode 100644 index 1e1b0fde9..000000000 --- a/src/structures/Game.js +++ /dev/null @@ -1,166 +0,0 @@ -const { games } = require('../utils/Constants'); -/** - * Game class - */ -class Game { - /** - * @param {GameId|GameCode} game Game ID or Game Code - */ - constructor(game) { - /** - * Input - * @type {GameId|GameCode} - */ - this.game = game.toString().toLowerCase(); - const result = games.find( - (g) => g.code.toLowerCase() === this.game || g.id.toString() === this.game || g.name.toLowerCase() === this.game - ); - /** - * ID of game - * @type {GameId} - */ - this.id = result ? result.id : 'Not Found'; - /** - * Codename of game - * @type {GameCode} - */ - this.code = result ? result.code : 'Not Found'; - /** - * Name of game - * @type {GameString} - */ - this.name = result ? result.name : 'Not Found'; - /** - * Whether the game is found - * @type {boolean} - */ - this.found = Boolean(result); - } - - /** - * Returns regular game name - * @return {GameString} - */ - toString() { - return this.name; - } - - /** - * Static list of game IDs ( The list has the same order as CODES or NAMES ) - * @type {GameId[]} - */ - static get IDS() { - return games.map((x) => x.id); - } - - /** - * Static list of game codes - * @type {GameCode[]} - */ - static get CODES() { - return games.map((x) => x.code); - } - - /** - * Static list of game strings - * @type {GameString[]} - */ - static get NAMES() { - return games.map((x) => x.name); - } -} -/** - * @typedef {string} GameString - * * QUAKECRAFT: `Quake Craft` - * * WALLS: `Walls` - * * PAINTBALL: `Paintball` - * * SURVIVAL_GAMES: `Blitz Survival Games` - * * TNTGAMES: `The TNT Games` - * * VAMPIREZ: `VAMPIREZ` - * * WALLS3: `Mega Walls` - * * ARCADE: `Arcade` - * * ARENA: `Arena Brawl` - * * UHC: `UHC Champions` - * * MCGO: `Cops And Crims` - * * WARLORDS: `Warlords` - * * SUPER_SMASH: `Smash Heroes` - * * GINGERBREAD: `Turbo Kart Racers` - * * HOUSING: `Housing` - * * SKYWARS: `SkyWars` - * * TRUE_COMBAT: `Crazy Walls` - * * SPEED_UHC: `Speed UHC` - * * SKYCLASH: `SkyClash` - * * LEGACY: `Classic Games` - * * PROTOTYPE: `Prototype` - * * BEDWARS: `BedWars` - * * MURDER_MYSTERY: `Murder Mystery` - * * BUILD_BATTLE: `Build Battle` - * * DUELS: `Duels` - * * SKYBLOCK: `SkyBlock` - * * PIT: `The Pit` - * * REPLAY: `Replay` - * * SMP: `SMP` - */ -/** - * @typedef {string} GameCode - * * QUAKECRAFT - * * WALLS - * * PAINTBALL - * * SURVIVAL_GAMES - * * TNTGAMES - * * VAMPIREZ - * * WALLS3 - * * ARCADE - * * ARENA - * * UHC - * * MCGO - * * WARLORDS - * * SUPER_SMASH - * * GINGERBREAD - * * HOUSING - * * SKYWARS - * * TRUE_COMBAT - * * SPEED_UHC - * * SKYCLASH - * * LEGACY - * * PROTOTYPE - * * BEDWARS - * * MURDER_MYSTERY - * * BUILD_BATTLE - * * DUELS - * * SKYBLOCK - * * PIT - * * REPLAY - * * SMP - */ -/** - * @typedef {number} GameId - * * QUAKECRAFT: `2` - * * WALLS: `3` - * * PAINTBALL: `4` - * * SURVIVAL_GAMES: `5` - * * TNTGAMES: `6` - * * VAMPIREZ: `7` - * * WALLS3: `13` - * * ARCADE: `14` - * * ARENA: `17` - * * UHC: `20` - * * MCGO: `21` - * * BATTLEGROUND: `23` - * * SUPER_SMASH: `24` - * * GINGERBREAD: `25` - * * HOUSING: `26` - * * SKYWARS: `51` - * * TRUE_COMBAT: `52` - * * SPEED_UHC: `54` - * * SKYCLASH: `55` - * * LEGACY: `56` - * * PROTOTYPE: `57` - * * BEDWARS: `58` - * * MURDER_MYSTERY: `59` - * * BUILD_BATTLE: `60` - * * DUELS: `61` - * * SKYBLOCK: `63` - * * PIT: `64` - */ -module.exports = Game; diff --git a/src/structures/GameCounts.js b/src/structures/GameCounts.js deleted file mode 100644 index 6e4077f5d..000000000 --- a/src/structures/GameCounts.js +++ /dev/null @@ -1,151 +0,0 @@ -const { MiniGamesString } = require('../utils/Constants'); -const { removeSnakeCaseString, recursive } = require('../utils/removeSnakeCase'); -/** - * GameCounts class - */ -class GameCounts { - /** - * @param {object} data - */ - constructor(data) { - /** - * Player count in Main lobby - * @name GameCounts#mainLobby - * @type {object} - */ - /** - * Player count in Tournament lobby - * @name GameCounts#tournamentLobby - * @type {object} - */ - /** - * Player count in SkyWars - * @name GameCounts#skywars - * @type {object} - */ - /** - * Player count in The Prototype - * @name GameCounts#prototype - * @type {object} - */ - /** - * Player count in BedWars - * @name GameCounts#bedwars - * @type {object} - */ - /** - * Player count in The Classic Games - * @name GameCounts#classicGames - * @type {object} - */ - /** - * Player count in Housing - * @name GameCounts#housing - * @type {object} - */ - /** - * Player count in Blitz Survival Games - * @name GameCounts#blitzSurvivalGames - * @type {object} - */ - /** - * Player count in UHC Champions - * @name GameCounts#uhcChampions - * @type {object} - */ - /** - * Player count in The Pit - * @name GameCounts#thePit - * @type {object} - */ - /** - * Player count in SkyBlock - * @name GameCounts#skyblock - * @type {object} - */ - /** - * Player count in Warlords - * @name GameCounts#warlords - * @type {object} - */ - /** - * Player count in Smash Heroes - * @name GameCounts#smashHeroes - * @type {object} - */ - /** - * Player count in Cops And Crims - * @name GameCounts#copsAndCrims - * @type {object} - */ - /** - * Player count in Speed UHC - * @name GameCounts#speedUhc - * @type {object} - */ - /** - * Player count in Arcade - * @name GameCounts#arcade - * @type {object} - */ - /** - * Player count in The TNT Games - * @name GameCounts#theTntGames - * @type {object} - */ - /** - * Player count in Duels - * @name GameCounts#duels - * @type {object} - */ - /** - * Player count in Murder Mystery - * @name GameCounts#murderMystery - * @type {object} - */ - /** - * Player count in Mega Walls - * @name GameCounts#megaWalls - * @type {object} - */ - /** - * Player count in SMP - * @name GameCounts#smp - * @type {object} - */ - /** - * Player count in Replay - * @name GameCounts#replay - * @type {object} - */ - /** - * Player count in Limbo - * @name GameCounts#limbo - * @type {object} - */ - /** - * Player count in Idle - * @name GameCounts#idle - * @type {object} - */ - /** - * Player count in Queue - * @name GameCounts#queue - * @type {object} - */ - /** - * Current player count - * @type {number} - */ - this.playerCount = data.playerCount; - for (const game in data.games) { - if (Object.prototype.hasOwnProperty.call(MiniGamesString, game)) { - const objectName = MiniGamesString[game].toUpperCase().replace(/ +/g, '_'); - this[removeSnakeCaseString(objectName)] = recursive(data.games[game], true); - } else { - this[removeSnakeCaseString(game)] = recursive(data.games[game], true); - } - } - } -} -module.exports = GameCounts; diff --git a/src/structures/Guild/Guild.js b/src/structures/Guild/Guild.js deleted file mode 100644 index 70c109124..000000000 --- a/src/structures/Guild/Guild.js +++ /dev/null @@ -1,191 +0,0 @@ -const { getGuildLevel, ranks, calculateExpHistory } = require('../../utils/Guild'); -const GuildMember = require('./GuildMember'); -const GuildRank = require('./GuildRank'); -const Color = require('../Color'); -const Game = require('../Game'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function members(data) { - return data.members.length ? data.members.map((m) => new GuildMember(m)) : []; -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function totalWeeklyGexp(data) { - return members(data) - .map((m) => m.weeklyExperience) - .reduce((acc, cur) => acc + cur); -} - -/** - * Guild class - */ -class Guild { - /** - * @param {data} data Guild data - * @param {string} [me] Player uuid u#sed to search for this guild - */ - constructor(data, me = '') { - /** - * Guild ID - * @type {string} - */ - - // eslint-disable-next-line no-underscore-dangle - this.id = data._id; - /** - * Guild name - * @type {string} - */ - this.name = data.name; - /** - * Guild description - * @type {string} - */ - this.description = data.description ?? ''; - /** - * Guild experience - * @type {number} - */ - this.experience = data.exp || 0; - /** - * Guild level - * @type {number} - */ - this.level = getGuildLevel(this.experience); - /** - * Guild members - * @type {Array} - */ - this.members = members(data); - /** - * Me, if a player UUID is used to get the guild - * @type {GuildMember|null} - */ - this.me = this.members.find((member) => member.uuid === me); - /** - * Guild ranks - * @type {Array} - */ - this.ranks = ranks(data); - /** - * The total guild experience earned in the last 7 days - * @author linearaccelerator - * @type {number} - */ - this.totalWeeklyGexp = totalWeeklyGexp(data); - /** - * An array containing all guild ranks sorted by newest - * @author linearaccelerator - * @return {Array} - */ - this.getRanksByNewest = function () { - return this.ranks.length - ? this.ranks.map((r) => new GuildRank(r)).sort((a, b) => b.createdAt - a.createdAt) - : null; - }; - /** - * A map containing all guild members, keyed by their uuids - * @author linearaccelerator - * @return {Map} - */ - this.getMemberUUIDMap = function () { - return this.members.length ? new Map(this.members.map((m) => [m.uuid, m])) : null; - }; - /** - * Returns a guild rank by priority - * @author linearaccelerator - * @param {number} priority - The priority of the guild rank - * @return {GuildRank} - */ - this.getRankByPriority = function (priority) { - if (!this.ranks.length || !this.ranks.some((r) => r.priority === priority)) return null; - return new GuildRank(this.ranks.find((r) => r.priority === priority)); - }; - /** - * Date of guild creation as timestamp - * @type {string} - */ - this.createdAtTimestamp = data.created; - /** - * Date of guild creation - * @type {Date} - */ - this.createdAt = new Date(data.created); - /** - * Whether this guild can be joined using /g join - * @type {boolean} - */ - this.joinable = data.joinable ?? false; - /** - * Whether this guild is listed in the Guild Finder - * @type {boolean} - */ - this.publiclyListed = Boolean(data.publiclyListed); - /** - * Timestamp guild chat will be unmuted at. - * @type {number|null} - */ - this.chatMuteUntilTimestamp = data.chatMute ?? null; - /** - * Timestamp guild chat will be unmuted at as Date. - * @type {Date|null} - */ - this.chatMuteUntil = data.chatMute ? new Date(data.chatMute) : null; - /** - * Timestamp guild chat will be unmuted at. - * @type {Array<{ Pattern: string, Color: string }>} - */ - this.banner = data.banner ?? null; - /** - * Guild tag - * @type {string} - */ - this.tag = data.tag ?? null; - /** - * Guild tag color - * @type {Color} - */ - this.tagColor = data.tagColor ? new Color(data.tagColor) : null; - /** - * Ranking in the number of guild coins owned in the legacy guild system. (0 - indexed) - * @deprecated - * @type {number} - */ - this.legacyRank = !isNaN(data.legacyRanking) ? parseInt(data.legacyRanking + 1, 10) : 0; - /** - * Experience history per day, resets at 5 am UTC. Please remember this is only an estimation based on the sum of every guild member's daily gexp. - * @type {Array} - */ - this.expHistory = calculateExpHistory(data); - /** - * Guild achievements - * @type {{winners: number, experienceKings: number, onlinePlayers: number}} - */ - this.achievements = { - winners: data.achievements.WINNERS ?? 0, - experienceKings: data.achievements.EXPERIENCE_KINGS ?? 0, - onlinePlayers: data.achievements.ONLINE_PLAYERS ?? 0 - }; - /** - * Guild preferred games - * @type {Array} - */ - this.preferredGames = data.preferredGames ? data.preferredGames.map((g) => new Game(g)) : []; - } - /** - * Guild name - * @return {string} - */ - toString() { - return this.name; - } - /** - * The Guild Master of the guild as a GuildMember - * @type {GuildMember} - */ - get guildMaster() { - return this.members.find((member) => 'Guild Master' === member.rank || 'GUILDMASTER' === member.rank); - } -} - -module.exports = Guild; diff --git a/src/structures/Guild/GuildMember.js b/src/structures/Guild/GuildMember.js deleted file mode 100644 index dc9be2975..000000000 --- a/src/structures/Guild/GuildMember.js +++ /dev/null @@ -1,66 +0,0 @@ -const { parseHistory } = require('../../utils/Guild'); -/** - * GuildMember class - */ -class GuildMember { - /** - * @param {data} data Guild member data - */ - constructor(data) { - /** - * Guild member UUID - * @type {string} - */ - this.uuid = data.uuid; - /** - * Timestamp this member joined at - * @type {number} - */ - this.joinedAtTimestamp = data.joined; - /** - * Timestamp this member joined at as Date - * @type {Date} - */ - this.joinedAt = new Date(data.joined); - /** - * The number of challenges completed that count towards the current quest - * @type {number} - */ - this.questParticipation = data.questParticipation || 0; - /** - * Member's rank - * @type {string} - */ - this.rank = data.rank; - /** - * Timestamp this member will be unmuted at ( if muted ) - * @type {Number|null} - */ - this.mutedUntilTimestamp = data.mutedTill ?? null; - /** - * Timestamp this member will be unmuted at as Date ( if muted ) - * @type {Date|null} - */ - this.mutedUntil = data.mutedTill ? new Date(data.mutedTill) : null; - const xpCheck = data.expHistory && 'number' === typeof Object.values(data.expHistory)[0]; - /** - * Experience history per day, resets at 5 am UTC - * @type {Array} - */ - this.expHistory = parseHistory(data.expHistory); - /** - * Experience per week, resets every Monday at 5 am UTC - * @type {number} - */ - this.weeklyExperience = xpCheck ? Object.values(data.expHistory).reduce((pV, cV) => pV + cV, 0) : null; - } - /** - * UUID - * @return {string} - */ - toString() { - return this.uuid; - } -} - -module.exports = GuildMember; diff --git a/src/structures/Guild/GuildRank.js b/src/structures/Guild/GuildRank.js deleted file mode 100644 index 4da8be8b0..000000000 --- a/src/structures/Guild/GuildRank.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * GuildRank class - */ -class GuildRank { - /** - * @param {data} data Guild rank data - */ - constructor(data) { - /** - * Guild rank name - * @type {string} - */ - this.name = data.name; - /** - * Whether this rank is the default rank a player gets when they join a guild - * @type {boolean} - */ - this.default = data.default; - /** - * Guild rank tag that appears in guild chat. null if none - * @type {string|null} - */ - this.tag = data.tag ?? null; - /** - * Timestamp this rank was created at - * @type {number} - */ - this.createdAtTimestamp = data.created ? data.created : data.createdAtTimestamp; - /** - * Timestamp this rank was created at as Date - * @type {Date} - */ - this.createdAt = new Date(data.created ? data.created : data.createdAtTimestamp); - /** - * Guild rank priority - Higher number = higher up in the hierarchy - * @type {number} - */ - this.priority = data.priority; - } - /** - * Rank Name - * @return {string} - */ - toString() { - return this.name; - } -} -module.exports = GuildRank; diff --git a/src/structures/House.js b/src/structures/House.js deleted file mode 100644 index 04221dd62..000000000 --- a/src/structures/House.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * House class - */ -class House { - /** - * @param {object} data data - */ - constructor(data) { - /** - * Name of the house - * @type {string} - */ - this.name = data.name || ''; - /** - * UUID of the house - * @type {string} - */ - this.uuid = data.uuid || ''; - /** - * UUID of the house owner - * @type {string} - */ - this.owner = data.owner || ''; - /** - * Timestamp when the house was created - * @type {number} - */ - this.createdAtTimestamp = data.createdAt || 0; - /** - * Date when the house was created - * @type {Date|null} - */ - this.createdAt = new Date(this.createdAtTimestamp); - /** - * Number of players currently at the house - * @type {number} - */ - this.players = data.players || 0; - /** - * Number of cookies the house has - * @type {number} - */ - this.cookies = data.cookies?.current || 0; - } - /** - * House Nmae - * @return {string} - */ - toString() { - return this.name; - } -} - -module.exports = House; diff --git a/src/structures/ItemBytes.js b/src/structures/ItemBytes.js deleted file mode 100644 index 628d1b584..000000000 --- a/src/structures/ItemBytes.js +++ /dev/null @@ -1,33 +0,0 @@ -const { decode } = require('../utils/SkyblockUtils'); -/** - * Item Bytes class - */ -class ItemBytes { - /** - * @param {string} data base64 encoded bytes - */ - constructor(data) { - /** - * Item Bytes as Buffer - * @type {Buffer} - */ - this.bytesBuffer = Buffer.from(data, 'base64'); - } - - /** - * Returns Item Bytes in base64 encoded - * @return {String} - */ - base64() { - return this.bytesBuffer.toString('base64'); - } - - /** - * Returns NBT of Item Bytes - * @return {any[]} - */ - async readNBT() { - return await decode(this.bytesBuffer, true); - } -} -module.exports = ItemBytes; diff --git a/src/structures/Leaderboard.js b/src/structures/Leaderboard.js deleted file mode 100644 index 2e3d897c7..000000000 --- a/src/structures/Leaderboard.js +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Leaderboard class - */ -class Leaderboard { - /** - * @param {object} data Leaderboard data - */ - constructor(data) { - /** - * Leaderboard name - * @type {string|null} - */ - this.name = data.prefix || null; - /** - * Leaderboard title - * @type {string} - */ - this.title = data.title || null; - /** - * Leaderboard player count - * @type {string} - */ - this.playerCount = data.count || 0; - /** - * Leaderboard leaders. Array of Player UUIDs - * @type {string[]} - */ - this.leaders = data.leaders || []; - } -} -module.exports = Leaderboard; diff --git a/src/structures/MiniGames/Arcade.js b/src/structures/MiniGames/Arcade.js deleted file mode 100644 index f37ff4f70..000000000 --- a/src/structures/MiniGames/Arcade.js +++ /dev/null @@ -1,986 +0,0 @@ -// IMPORTANT : a lot of the properties from the API seem to be nonsense - -const { removeSnakeCaseString } = require('../../utils/removeSnakeCase'); -const { weekAB, monthAB } = require('../../utils/oscillation'); -const divide = require('../../utils/divide'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function parseZombiesKills(data) { - const matches = Array.from(Object.keys(data)) - .map((x) => x.match(/^([A-Za-z]+)_zombie_kills_zombies$/)) - .filter((x) => x); - // From entries might be broken - return Object.fromEntries(matches.map((x) => [removeSnakeCaseString(x[1]), data[x[0]] || 0])); -} -/** - * Zombies - Stats by Map + Difficulty - */ -class ZombiesStats { - /** - * Constructor - * @param {Object} data Data from API - * @param {string} type Map name + difficulty ( default overall ) - */ - constructor(data, type = '') { - if (type) type = `_${type}`; - /** - * Best Round - * @type {number} - */ - this.bestRound = data[`best_round_zombies${type}`] || 0; - /** - * Deaths ( NOT losses ) - * @type {number} - */ - this.deaths = data[`deaths_zombies${type}`] || 0; - /** - * Doors opened - * @type {number} - */ - this.doorsOpened = data[`doors_opened_zombies${type}`] || 0; - /** - * Fastest time to reach round 10 in seconds - * @type {number} - */ - this.fastestRound10 = data[`fastest_time_10_zombies${type}_normal`] || 0; - /** - * Fastest time to reach round 20 in seconds - * @type {number} - */ - this.fastestRound20 = data[`fastest_time_20_zombies${type}_normal`] || 0; - /** - * Fastest time to reach round 30 in seconds - * @type {number} - */ - this.fastestRound30 = data[`fastest_time_30_zombies${type}_normal`] || 0; - /** - * Players revived - * @type {number} - */ - this.playersRevived = data[`players_revived_zombies${type}`] || 0; - /** - * Number of times player is knocked down - * @type {number} - */ - this.timesKnockedDown = data[`times_knocked_down_zombies${type}`] || 0; - /** - * Total amount of rounds the player survived - * @type {number} - */ - this.roundsSurvived = data[`total_rounds_survived_zombies${type}`] || 0; - /** - * Total amount of windows fully repaired by player - * @type {number} - */ - this.windowsRepaired = data[`windows_repaired_zombies${type}`] || 0; - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_zombies${type}`] || 0; - /** - * Total Zombie Kills - * @type {number} - */ - this.zombieKills = data[`zombie_kills_zombies${type}`] || 0; - } -} - -/** - * Zombies - Overall stats - */ -class Zombies { - /** - * Constructor - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Overall Stats - * @type {ZombiesStats} - */ - this.overall = new ZombiesStats(data); - /** - * Stats for Dead End - * @type {ZombiesStats} - */ - this.deadEnd = new ZombiesStats(data, 'deadend'); - /** - * Stats for Bad Blood - * @type {ZombiesStats} - */ - this.badBlood = new ZombiesStats(data, 'badblood'); - /** - * Stats for Alien Arcadium - * @type {ZombiesStats} - */ - this.alienArcadium = new ZombiesStats(data, 'alienarcadium'); - /** - * Stats for Prison - * @type {ZombiesStats} - */ - this.prison = new ZombiesStats(data, 'prison'); - /** - * Kills By Zombie - * @type {Record} - */ - this.killsByZombie = parseZombiesKills(data); - /** - * Bullets Hit - * @type {number} - */ - this.bulletsHit = data.bullets_hit_zombies || 0; - /** - * Bullets Shot - * @type {number} - */ - this.bulletsShot = data.bullets_shot_zombies || 0; - /** - * Gun Accuracy - * @type {number} - */ - this.gunAccuracy = divide(this.bulletsHit, this.bulletsShot); - /** - * Headshots - * @type {number} - */ - this.headshots = data.headshots_zombies || 0; - /** - * Headshot Accuracy - * @type {number} - */ - this.headshotAccuracy = divide(this.headshots, this.bulletsShot); - } -} - -/** - * Dropper stats by map - */ -class DropperMap { - /** - * Constructor - * @param {Object} data Data from API - * @param {string} mapName String map name - */ - constructor(data, mapName) { - /** - * Best Complete Time - * @type {number} - */ - this.bestTime = data?.[mapName]?.best_time ?? 0; - /** - * Total completions - * @type {number} - */ - this.completions = data?.[mapName]?.completions ?? 0; - } -} - -/** - * Blocking Dead class - */ -class BlockingDead { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_dayone || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_dayone || 0; - /** - * Headshots - * @type {number} - */ - this.headshots = data.headshots_dayone || 0; - } -} -/** - * Bounty Hunters class - */ -class BountyHunters { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_oneinthequiver || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_oneinthequiver || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_oneinthequiver || 0; - /** - * Kill Death Ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Bounty Kills - * @type {number} - */ - this.bountyKills = data.bounty_kills_oneinthequiver || 0; - /** - * Bow Kills - * @type {number} - */ - this.bowKills = data.bow_kills_oneinthequiver || 0; - /** - * Sword Kills - * @type {number} - */ - this.swordKills = data.sword_kills_oneinthequiver || 0; - } -} -/** - * Dragon Wars class - */ -class DragonWars { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_dragonwars2 || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_dragonwars2 || 0; - } -} -/** - * Dropper class - */ -class Dropper { - constructor(data) { - /** - * Total Wins - * @type {number} - */ - this.wins = data?.wins ?? 0; - /** - * Total Fails - * @type {number} - */ - this.fails = data?.fails ?? 0; - /** - * Fastest Game - * @type {number} - */ - this.fastestGame = data?.fastest_game ?? 0; - /** - * Total Amount of Flawless Games - * @type {number} - */ - this.flawlessGames = data?.flawless_games ?? 0; - /** - * Total Amount of Games Played - * @type {number} - */ - this.gamesPlayed = data?.games_played ?? 0; - /** - * Total Amount of Maps Completed - * @type {number} - */ - this.mapsCompleted = data?.maps_completed ?? 0; - /** - * Total Amount of Games Finished - * @type {number} - */ - this.gamesFinished = data?.games_finished ?? 0; - /** - * Maps - * @type {Object.} - */ - this.maps = {}; - Object.keys(data?.map_stats ?? {}).forEach((map) => { - this.maps[map] = new DropperMap(data?.map_stats, map); - }); - } -} -/** - * Ender Spleef class - */ -class EnderSpleef { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_ender || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_dragonwars2 || 0; - /** - * Trail - * @type {string} - */ - this.trail = data.enderspleef_trail || ''; - /** - * Blocks Destroyed - * @type {number} - */ - this.blocksDestroyed = data.blocks_destroyed_ender || 0; - /** - * Big Shot Activations - * @type {number} - */ - this.bigShotActivations = data.bigshot_powerup_activations_ender || 0; - /** - * Triple Shot Activations - * @type {number} - */ - this.tripleShotActivations = data.tripleshot_powerup_activations_ender || 0; - /** - * Total Powerup Activations - * @type {number} - */ - this.totalPowerUpActivations = this.bigShotActivations + this.tripleShotActivations; - } -} -/** - * Farm Hunt class - */ -class FarmHunt { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_farm_hunt || 0; - /** - * Wins as Animal - * @type {number} - */ - this.winsAsAnimal = data.animal_wins_farm_hunt || 0; - /** - * Wins as Hunter - * @type {number} - */ - this.winsAsHunter = data.hunter_wins_farm_hunt || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_farm_hunt || 0; - /** - * Kills as Animal - * @type {number} - */ - this.killsAsAnimal = data.animal_kills_farm_hunt || 0; - /** - * Kills as Hunter - * @type {number} - */ - this.killsAsHunter = data.hunter_kills_farm_hunt || 0; - /** - * Taunts Used - * @type {number} - */ - this.tauntsUsed = data.taunts_used_farm_hunt || 0; - /** - * Risky Taunts Used - * @type {number} - */ - this.riskyTauntsUsed = data.risky_taunts_used_farm_hunt || 0; - /** - * Safe Taunts Used - * @type {number} - */ - this.safeTauntsUsed = data.safe_taunts_used_farm_hunt || 0; - /** - * Dangerous Taunts Used - * @type {number} - */ - this.dangerousTauntsUsed = data.dangerous_taunts_used_farm_hunt || 0; - /** - * Firework Taunts Used - * @type {number} - */ - this.fireworkTauntsUsed = data.firework_taunts_used_farm_hunt || 0; - /** - * Poop Collected - * @type {number} - */ - this.poop = (data.poop_collected_farm_hunt || 0) + (data.poop_collected || 0); - } -} -/** - * Football class - */ -class Football { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_soccer || 0; - /** - * Goals - * @type {number} - */ - this.goals = data.goals_soccer || 0; - /** - * Kikcs - * @type {number} - */ - this.kicks = data.kicks_soccer || 0; - /** - * Power Kicks - * @type {number} - */ - this.powerKicks = data.powerkicks_soccer || 0; - } -} -/** - * Galxy Wars - */ -class GalaxyWars { - /** - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.sw_game_wins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.sw_kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.sw_deaths || 0; - /** - * Total shots fired - * @type {number} - */ - this.shotsFired = data.sw_shots_fired || 0; - /** - * Total weekly kills - * @type {number} - */ - this.weeklyKills = parseInt(data[`weekly_kills_${weekAB()}`] || 0, 10); - /** - * Total Monthly kills - * @type {number} - */ - this.monthlyKills = parseInt(data[`monthly_kills_${monthAB()}`] || 0, 10); - /** - * Attacker Kills - * @type {number} - */ - this.attackerKills = data.sw_rebel_kills || 0; - /** - * Defender Kills - * @type {number} - */ - this.defenderKills = data.sw_empire_kills || 0; - } -} -/** - * Party Pooper Stats (Sub gamemode of Hide and Seek) - */ -class PartyPooper { - /** - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Wins as Seeker - * @type {number} - */ - this.winsAsSeeker = data.party_pooper_seeker_wins_hide_and_seek || 0; - /** - * Wins as Hider - * @type {number} - */ - this.winsAsHider = data.party_pooper_hider_wins_hide_and_seek || 0; - /** - * Wins - * @type {number} - */ - this.wins = this.winsAsSeeker + this.winsAsHider; - } -} -/** - * Prop Hunt Stats (Sub gamemode of Hide and Seek) - */ -class PropHunt { - /** - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Wins as Seeker - * @type {number} - */ - this.winsAsSeeker = data.prop_hunt_seeker_wins_hide_and_seek || 0; - /** - * Wins as Hider - * @type {number} - */ - this.winsAsHider = data.prop_hunt_hider_wins_hide_and_seek || 0; - /** - * Wins - * @type {number} - */ - this.wins = this.winsAsSeeker + this.winsAsHider; - } -} -/** - * Hide And Seek Stats - */ -class HideAndSeek { - /** - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Party Pooper Stats - * @type {PartyPooper} - */ - this.partyPooper = new PartyPooper(data); - /** - * Prop Hunt Stats - * @type {PropHunt} - */ - this.propHunt = new PropHunt(data); - /** - * Wins as Seeker - * @type {number} - */ - this.winsAsSeeker = data.seeker_wins_hide_and_seek || 0; - /** - * Wins as Hider - * @type {number} - */ - this.winsAsHider = data.hider_wins_hide_and_seek || 0; - } -} -/** - * Hide And Seek Stats - */ -class HoleInTheWall { - /** - * @param {Object} data Data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_hole_in_the_wall || 0; - /** - * Rounds Played - * @type {number} - */ - this.rounds = data.rounds_hole_in_the_wall || 0; - /** - * Score Record in Finals - * @type {number} - */ - this.scoreRecordFinals = data.hitw_record_f || 0; - /** - * Score Record in Normal - * @type {number} - */ - this.scoreRecordNormal = data.hitw_record_q || 0; - /** - * Score Record Overall - * @type {number} - */ - this.scoreRecordOverall = this.scoreRecordFinals + this.scoreRecordNormal; - } -} -/** - * Hypixel Says Stats - */ -class HypixelSays { - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_simon_says || 0; - /** - * Rounds - * @type {number} - */ - this.rounds = data.rounds_simon_says || 0; - /** - * Round Wins - * @type {number} - */ - this.roundWins = data.round_wins_simon_says || 0; - /** - * Top Score - * @type {number} - */ - this.topScore = data.top_score_simon_says || 0; - } -} -/** - * Mini Walls class - */ -class MiniWalls { - /** - * Constructor - * @param {Object} data data from API - */ - constructor(data) { - /** - * Active Kit - * @type {string} - */ - this.kit = data.miniWalls_activeKit || ''; - /** - * Wins - * @type {number} - */ - this.wins = data.wins_mini_walls || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_mini_walls || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_mini_walls || 0; - /** - * Kill Death Ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Final Kills - * @type {number} - */ - this.finalKills = data.final_kills_mini_walls || 0; - /** - * Wither Kills - * @type {number} - */ - this.witherKills = data.wither_kills_mini_walls || 0; - /** - * Wither Damage - * @type {number} - */ - this.witherDamage = data.wither_damage_mini_walls || 0; - /** - * Arrows Shot - * @type {number} - */ - this.arrowsShot = data.arrows_shot_mini_walls || 0; - /** - * Arrows Hit - * @type {number} - */ - this.arrowsHit = data.arrows_hit_mini_walls || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot); - } -} -/** - * Party Games class - */ -class PartyGames { - /** - * Constructor - * @param {Object} data data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_party || 0; - /** - * Rounds Won - * @type {number} - */ - this.roundWins = data.round_wins_party || 0; - /** - * Stars Earned - * @type {number} - */ - this.stars = data.total_stars_party || 0; - } -} -/** - * Pixel Party Game Mode - */ -class PixelPartyGameMode { - /** - * Constructor - * @param {Object} data data from API - * @param {string} modeName Mode name - */ - constructor(data, modeName) { - /** - * Wins - * @type {number} - */ - this.wins = data?.[`wins_${modeName}`] || 0; - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data?.[`games_played_${modeName}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss Ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Rounds Played - * @type {number} - */ - this.roundsPlayed = data?.[`rounds_completed_${modeName}`] || 0; - /** - * Power Ups Collected - * @type {number} - */ - this.powerUpsCollected = data?.[`power_ups_collected_${modeName}`] || 0; - } -} -/** - * Party Games class - */ -class PixelParty { - /** - * Constructor - * @param {Object} data data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data?.pixel_party?.wins || 0; - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data?.pixel_party?.games_played || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss Ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Rounds Played - * @type {number} - */ - this.roundsPlayed = data?.pixel_party?.rounds_completed || 0; - /** - * Power Ups Collected - * @type {number} - */ - this.powerUpsCollected = data?.pixel_party?.power_ups_collected || 0; - /** - * Normal Game Mode - * @type {PixelPartyGameMode} - */ - this.normal = new PixelPartyGameMode(data.pixel_party, 'normal'); - /** - * Hyper Game Mode - * @type {PixelPartyGameMode} - */ - this.hyper = new PixelPartyGameMode(data.pixel_party, 'hyper'); - /** - * Highest Round - * @type {number} - */ - this.highestRound = data?.pixel_party?.highest_round || 0; - /** - * Music Volume - * @type {number} - */ - this.musicVolume = data.pixel_party_music_volume || 0; - /** - * Color Blind Settings - * @type {object} - */ - this.colorBlind = data.pixelparty || {}; - } -} -/** - * Throw Out class - */ -class ThrowOut { - /** - * Constructor - * @param {Object} data data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_throw_out || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_throw_out || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_throw_out || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - } -} -/** - * Arcade class - */ -class Arcade { - /** - * Constructor - * @param {Object} data Data from the API - */ - constructor(data = {}) { - /** - * Amount of coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Weekly coins - * @type {number} - */ - this.weeklyCoins = parseInt(data[`weekly_coins_${weekAB()}`] || 0, 10); - /** - * Monthly coins - * @type {number} - */ - this.monthlyCoins = parseInt(data[`monthly_coins_${monthAB()}`] || 0, 10); - /** - * Hints Disabled - * @type {boolean} - */ - this.hintsDisabled = !data.hints; - /** - * Flash Disabled - * @type {boolean} - */ - this.flashDisabled = !data.flash; - /** - * Blocking dead ( previously known as DayOne ) stats - * @type {BlockingDead} - */ - this.blockingDead = new BlockingDead(data); - /** - * Bounty Hunters (previously known as One In The Quiver) stats - * @type {BountyHunters} - */ - this.bountyHunters = new BountyHunters(data); - /** - * Dragon wars stats - * @type {DragonWars} - */ - this.dragonWars = new DragonWars(data); - /** - * Dropper - * @type {Dropper} - */ - this.dropper = new Dropper(data.dropper); - /** - * Ender Spleef stats - * @type {EnderSpleef} - */ - this.enderSpleef = new EnderSpleef(data); - /** - * Farm Hunt stats - * @type {FarmHunt} - */ - this.farmHunt = new FarmHunt(data); - /** - * Football stats - * @type {Football} - */ - this.football = new Football(data); - /** - * Galaxy Wars stats - * @type {GalaxyWars} - */ - this.galaxyWars = new GalaxyWars(data); - /** - * Hide and Seek stats - * @type {HideAndSeek} - */ - this.hideAndSeek = new HideAndSeek(data); - /** - * Hole in the Wall stats - * @type {HoleInTheWall} - */ - this.holeInTheWall = new HoleInTheWall(data); - /** - * Hypixel Says stats - * @type {HypixelSays} - */ - this.hypixelSays = new HypixelSays(data); - /** - * Mini Walls stats - * @type {MiniWalls} - */ - this.miniWalls = new MiniWalls(data); - /** - * Party games stats - * @type {PartyGames} - */ - this.partyGames = new PartyGames(data); - /** - * Pixel Party stats - * @type {PixelParty} - */ - this.pixelParty = new PixelParty(data); - /** - * Throw out stats - * @type {ThrowOut} - */ - this.throwOut = new ThrowOut(data); - /** - * Zombies - * @type {Zombies} - */ - this.zombies = new Zombies(data); - } -} - -module.exports = Arcade; diff --git a/src/structures/MiniGames/ArenaBrawl.js b/src/structures/MiniGames/ArenaBrawl.js deleted file mode 100644 index 3cfbef99b..000000000 --- a/src/structures/MiniGames/ArenaBrawl.js +++ /dev/null @@ -1,118 +0,0 @@ -const divide = require('../../utils/divide'); - -class ArenaBrawlMode { - /** - * @param {object} data ArenaBrawl data - * @param {string} mode mode - */ - constructor(data, mode) { - /** - * Damage - * @type {number} - */ - this.damage = data[`damage_${mode}`]; - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${mode}`]; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${mode}`]; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Healed - * @type {number} - */ - this.healed = data[`healed_${mode}`]; - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${mode}`]; - /** - * Losses - * @type {number} - */ - this.losses = data[`losses_${mode}`]; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Games Played - * @type {number} - */ - this.games = data[`games_${mode}`]; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data[`win_streaks_${mode}`]; - } -} - -/** - * ArenaBrawl class - */ -class ArenaBrawl { - /** - * @param {object} data ArenaBrawl data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Coins Spent - * @type {number} - */ - this.coinsSpent = data.coins_spent || 0; - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Keys - * @type {number} - */ - this.keys = data.keys || 0; - /** - * Chests - * @type {number} - */ - this.chests = data.magical_chest || 0; - /** - * Rune - * @type {string} - */ - this.rune = data.active_rune || ''; - /** - * ArenaBrawl mode stats - * @type {ArenaBrawlMode} - */ - this['1v1'] = new ArenaBrawlMode(data, '1v1'); - /** - * ArenaBrawl mode stats - * @type {ArenaBrawlMode} - */ - this['2v2'] = new ArenaBrawlMode(data, '2v2'); - /** - * ArenaBrawl mode stats - * @type {ArenaBrawlMode} - */ - this['4v4'] = new ArenaBrawlMode(data, '4v4'); - } -} - -module.exports = ArenaBrawl; diff --git a/src/structures/MiniGames/BedWars.js b/src/structures/MiniGames/BedWars.js deleted file mode 100644 index 14645f5c9..000000000 --- a/src/structures/MiniGames/BedWars.js +++ /dev/null @@ -1,554 +0,0 @@ -const divide = require('../../utils/divide'); - -const generateStatsForMode = (data, mode) => { - return { - winstreak: data[`${mode}_winstreak`] || 0, - playedGames: data[`${mode}_games_played_bedwars`] || 0, - - kills: data[`${mode}_kills_bedwars`] || 0, - deaths: data[`${mode}_deaths_bedwars`] || 0, - - wins: data[`${mode}_wins_bedwars`] || 0, - losses: data[`${mode}_losses_bedwars`] || 0, - - finalKills: data[`${mode}_final_kills_bedwars`] || 0, - finalDeaths: data[`${mode}_final_deaths_bedwars`] || 0, - - beds: { - broken: data[`${mode}_beds_broken_bedwars`] || 0, - lost: data[`${mode}_beds_lost_bedwars`] || 0, - BLRatio: divide(data[`${mode}_beds_broken_bedwars`], data[`${mode}_beds_lost_bedwars`]) - }, - - avg: { - kills: divide(data[`${mode}_kills_bedwars`], data[`${mode}_games_played_bedwars`]), - finalKills: divide(data[`${mode}_final_kills_bedwars`], data[`${mode}_games_played_bedwars`]), - bedsBroken: divide(data[`${mode}_beds_broken_bedwars`], data[`${mode}_games_played_bedwars`]) - }, - - KDRatio: divide(data[`${mode}_kills_bedwars`], data[`${mode}_deaths_bedwars`]), - WLRatio: divide(data[`${mode}_wins_bedwars`], data[`${mode}_losses_bedwars`]), - finalKDRatio: divide(data[`${mode}_final_kills_bedwars`], data[`${mode}_final_deaths_bedwars`]) - }; -}; - -// eslint-disable-next-line jsdoc/require-jsdoc -function getBedWarsPrestige(level) { - if (5000 <= level) return 'Eternal'; - return ( - [ - 'Stone', - 'Iron', - 'Gold', - 'Diamond', - 'Emerald', - 'Sapphire', - 'Ruby', - 'Crystal', - 'Opal', - 'Amethyst', - 'Rainbow', - 'Iron Prime', - 'Gold Prime', - 'Diamond Prime', - 'Emerald Prime', - 'Sapphire Prime', - 'Ruby Prime', - 'Crystal Prime', - 'Opal Prime', - 'Amethyst Prime', - 'Mirror', - 'Light', - 'Dawn', - 'Dusk', - 'Air', - 'Wind', - 'Nebula', - 'Thunder', - 'Earth', - 'Water', - 'Fire', - 'Sunrise', - 'Eclipse', - 'Gamma', - 'Majestic', - 'Andesine', - 'Marine', - 'Element', - 'Galaxy', - 'Atomic', - 'Sunset', - 'Time', - 'Winter', - 'Obsidian', - 'Spring', - 'Ice', - 'Summer', - 'Spinel', - 'Autumn', - 'Mystic', - 'Eternal' - ][Math.floor(level / 100)] || 'Eternal' - ); -} -const EASY_LEVELS = 4; -const EASY_LEVELS_XP = 7000; -const XP_PER_PRESTIGE = 96 * 5000 + EASY_LEVELS_XP; -const LEVELS_PER_PRESTIGE = 100; -const HIGHEST_PRESTIGE = 10; - -// eslint-disable-next-line jsdoc/require-jsdoc -function getLevelRespectingPrestige(level) { - if (level > HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE) { - return level - HIGHEST_PRESTIGE * LEVELS_PER_PRESTIGE; - } - return level % LEVELS_PER_PRESTIGE; -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function getExpForLevel(level) { - if (0 === level) return 0; - const respectedLevel = getLevelRespectingPrestige(level); - if (respectedLevel > EASY_LEVELS) return 5000; - switch (respectedLevel) { - case 1: - return 500; - case 2: - return 1000; - case 3: - return 2000; - case 4: - return 3500; - default: { - return 5000; - } - } -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function getLevelForExp(exp) { - const prestiges = Math.floor(exp / XP_PER_PRESTIGE); - let level = prestiges * LEVELS_PER_PRESTIGE; - let expWithoutPrestiges = exp - prestiges * XP_PER_PRESTIGE; - - for (let i = 1; i <= EASY_LEVELS; ++i) { - const expForEasyLevel = getExpForLevel(i); - if (expWithoutPrestiges < expForEasyLevel) { - break; - } - level++; - expWithoutPrestiges -= expForEasyLevel; - } - return level + Math.floor(expWithoutPrestiges / 5000); -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function generateStatsForPractice(data) { - return { - selected: data?.practice?.selected || 'NONE', - bridging: { - blocksPlaced: data?.practice?.bridging?.blocks_placed ?? 0, - attempts: { - failed: data?.practice?.bridging?.failed_attempts ?? 0, - successful: data?.practice?.bridging?.successful_attempts ?? 0, - total: data?.practice?.bridging?.failed_attempts + data?.practice?.bridging?.successful_attempts - }, - records: { - blocks30: { - elevation: { - none: { - straight: data?.practice?.records?.['bridging_distance_30:elevation_NONE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_30:elevation_NONE:angle_DIAGONAL:'] ?? 0 - }, - slight: { - straight: data?.practice?.records?.['bridging_distance_30:elevation_SLIGHT:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_30:elevation_SLIGHT:angle_DIAGONAL:'] ?? 0 - }, - staircase: { - straight: data?.practice?.records?.['bridging_distance_30:elevation_STAIRCASE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_30:elevation_STAIRCASE:angle_DIAGONAL:'] ?? 0 - } - } - }, - blocks50: { - elevation: { - none: { - straight: data?.practice?.records?.['bridging_distance_50:elevation_NONE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_50:elevation_NONE:angle_DIAGONAL:'] ?? 0 - }, - slight: { - straight: data?.practice?.records?.['bridging_distance_50:elevation_SLIGHT:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_50:elevation_SLIGHT:angle_DIAGONAL:'] ?? 0 - }, - staircase: { - straight: data?.practice?.records?.['bridging_distance_50:elevation_STAIRCASE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_50:elevation_STAIRCASE:angle_DIAGONAL:'] ?? 0 - } - } - }, - blocks100: { - elevation: { - none: { - straight: data?.practice?.records?.['bridging_distance_100:elevation_NONE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_100:elevation_NONE:angle_DIAGONAL:'] ?? 0 - }, - slight: { - straight: data?.practice?.records?.['bridging_distance_100:elevation_SLIGHT:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_100:elevation_SLIGHT:angle_DIAGONAL:'] ?? 0 - }, - staircase: { - straight: data?.practice?.records?.['bridging_distance_100:elevation_STAIRCASE:angle_STRAIGHT:'] ?? 0, - diagonal: data?.practice?.records?.['bridging_distance_100:elevation_STAIRCASE:angle_DIAGONAL:'] ?? 0 - } - } - } - } - }, - fireballJumping: { - blocksPlaced: data?.practice?.fireball_jumping?.blocks_placed ?? 0, - attempts: { - failed: data?.practice?.fireball_jumping?.failed_attempts ?? 0, - successful: data?.practice?.fireball_jumping?.successful_attempts ?? 0, - total: data?.practice?.fireball_jumping?.failed_attempts + data?.practice?.fireball_jumping?.successful_attempts - } - }, - pearlClutching: { - attempts: { - failed: data?.practice?.pearl_clutching?.failed_attempts ?? 0, - successful: data?.practice?.pearl_clutching?.successful_attempts ?? 0, - total: data?.practice?.pearl_clutching?.failed_attempts + data?.practice?.pearl_clutching?.successful_attempts - } - }, - mlg: { - blocksPlaced: data?.practice?.mlg?.blocks_placed ?? 0, - attempts: { - failed: data?.practice?.mlg?.failed_attempts ?? 0, - successful: data?.practice?.mlg?.successful_attempts ?? 0, - total: data?.practice?.mlg?.failed_attempts + data?.practice?.mlg?.successful_attempts - } - } - }; -} -/** - * BedWars class - */ -class BedWars { - /** - * @param {object} data BedWars data - */ - constructor(data) { - /** - * Tokens - * @type {number} - */ - this.tokens = data.coins || 0; - /** - * Level - * @type {number} - */ - this.level = data.Experience ? getLevelForExp(data.Experience) : 0; - /** - * Experience - * @type {number} - */ - this.experience = data.Experience || 0; - /** - * Prestige - * @type {BedWarsPrestige} - */ - this.prestige = data.Experience ? getBedWarsPrestige(getLevelForExp(data.Experience)) : 'Stone'; - /** - * Played games - * @type {number} - */ - this.playedGames = data.games_played_bedwars || 0; - /** - * Wins - * @type {number} - */ - this.wins = data.wins_bedwars || 0; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.winstreak || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_bedwars || 0; - /** - * Final kills - * @type {number} - */ - this.finalKills = data.final_kills_bedwars || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses_bedwars || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_bedwars || 0; - /** - * Final deaths - * @type {number} - */ - this.finalDeaths = data.final_deaths_bedwars || 0; - /** - * Collected items - * @type {BedWarsCollectedItems} - */ - this.collectedItemsTotal = { - iron: data.iron_resources_collected_bedwars || 0, - gold: data.gold_resources_collected_bedwars || 0, - diamond: data.diamond_resources_collected_bedwars || 0, - emerald: data.emerald_resources_collected_bedwars || 0 - }; - /** - * Beds lost/broken/BL Ratio - * @type {BedWarsBeds} - */ - this.beds = { - lost: data.beds_lost_bedwars || 0, - broken: data.beds_broken_bedwars || 0, - BLRatio: divide(data.beds_broken_bedwars, data.beds_lost_bedwars) - }; - /** - * Average Kills/Final kills/Beds broken - * @type {BedWarsAvg} - */ - this.avg = { - kills: divide(this.kills, this.playedGames), - finalKills: divide(this.finalKills, this.playedGames), - bedsBroken: divide(this.beds.broken, this.playedGames) - }; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Final kill death ratio - * @type {number} - */ - this.finalKDRatio = divide(this.finalKills, this.finalDeaths); - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * BedWars Solo stats - * @type {BedWarsModeStats} - */ - this.solo = generateStatsForMode(data, 'eight_one'); - /** - * BedWars Doubles stats - * @type {BedWarsModeStats} - */ - this.doubles = generateStatsForMode(data, 'eight_two'); - /** - * BedWars 3v3v3v3 stats - * @type {BedWarsModeStats} - */ - this.threes = generateStatsForMode(data, 'four_three'); - /** - * BedWars 4v4v4v4 stats - * @type {BedWarsModeStats} - */ - this.fours = generateStatsForMode(data, 'four_four'); - /** - * BedWars 4v4 stats - * @type {BedWarsModeStats} - */ - this['4v4'] = generateStatsForMode(data, 'two_four'); - /** - * BedWars Dream Mode Stats - * @type {BedwarsDreamStats} - */ - this.dream = ['ultimate', 'rush', 'armed', 'lucky', 'voidless'].reduce( - (ac, mode) => ({ - [mode]: { - doubles: generateStatsForMode(data, `eight_two_${mode}`), - fours: generateStatsForMode(data, `four_four_${mode}`) - }, - ...ac - }), - {} - ); - /** - * BedWars Castle Stats - * @type {BedWarsModeStats} - */ - this.castle = generateStatsForMode(data, 'castle'); - /** - * BedWars Practice Stats - * @type {BedWarsPracticeStats} - */ - this.practice = generateStatsForPractice(data); - /** - * Bedwars Slumber Tickets - * @type {number} - */ - this.slumberTickets = data.slumber?.tickets ?? 0; - /** - * Bedwars Slumber Total Tickets - * @type {number} - */ - this.totalSlumberTicket = data.slumber?.total_tickets ?? 0; - } -} -/** - * @typedef {string} BedWarsPrestige - * * `Stone` - * * `Iron` - * * `Gold` - * * `Diamond` - * * `Emerald` - * * `Sapphire` - * * `Ruby` - * * `Crystal` - * * `Opal` - * * `Amethyst` - * * `Rainbow` - * * `Iron Prime` - * * `Gold Prime` - * * `Diamond Prime` - * * `Emerald Prime` - * * `Sapphire Prime` - * * `Ruby Prime` - * * `Crystal Prime` - * * `Opal Prime` - * * `Amethyst Prime` - * * `Mirror` - * * `Light` - * * `Dawn` - * * `Dusk` - * * `Air` - * * `Wind` - * * `Nebula` - * * `Thunder` - * * `Earth` - * * `Water` - * * `Fire` - * * `Sunrise` - * * `Eclipse` - * * `Gamma` - * * `Majestic` - * * `Andesine` - * * `Marine` - * * `Element` - * * `Galaxy` - * * `Atomic` - * * `Sunset` - * * `Time` - * * `Winter` - * * `Obsidian` - * * `Spring` - * * `Ice` - * * `Summer` - * * `Spinel` - * * `Autumn` - * * `Mystic` - * * `Eternal` - */ -/** - * @typedef {object} BedWarsAvg - * @property {number} kills Average kills - * @property {number} finalKills Average final kills - * @property {number} bedsBroken Average beds broken - */ -/** - * @typedef {object} BedWarsCollectedItems - * @property {number} iron Iron - * @property {number} gold Gold - * @property {number} diamond Diamond - * @property {number} emerald Emerald - */ -/** - * @typedef {object} BedWarsBeds - * @property {number} lost Beds lost - * @property {number} broken Beds broken - * @property {number} BLRatio Beds broken/Beds lost ratio - */ -/** - * @typedef {Object} BedWarsModeStats - * @property {number} winstreak Winstreak - * @property {number} playedGames Played games - * @property {number} kills Kills - * @property {number} deaths Deaths - * @property {number} wins Wins - * @property {number} losses Losses - * @property {number} finalKills Final kills - * @property {number} finalDeaths Final deaths - * @property {BedWarsBeds} beds Beds - * @property {BedWarsAvg} avg Average Kills/Final kills/Beds broken - * @property {number} KDRatio Kill Death ratio - * @property {number} WLRatio Win Loss ratio - * @property {number} finalKDRatio Final kills/Final deaths ratio - */ -/** - * @typedef {Object} BedwarsDreamStats - * @property {BedwarsDreamModeStats} ultimate Ultimate stats - * @property {BedwarsDreamModeStats} rush Rush stats - * @property {BedwarsDreamModeStats} armed Armed stats - * @property {BedwarsDreamModeStats} lucky Lucky Blocks stats (true api naming) - * @property {BedwarsDreamModeStats} voidless Voidless stats - */ -/** - * @typedef {Object} BedwarsDreamModeStats - * @property {BedWarsModeStats} doubles Doubles - * @property {BedWarsModeStats} fours Fours - */ -/** - * @typedef {Object} BedWarsPracticeAttempts - * @property {number} failed Total failed attempts - * @property {number} successful Total successful attempts - * @property {number} total Total Number of attempts - */ -/** - * @typedef {Object} BedWarsPracticeElevation - * @property {number} straight straight - * @property {number} diagonal diagonal - */ -/** - * @typedef {Object} BedWarsPracticeElevations - * @property {BedWarsPracticeElevation} none none - * @property {BedWarsPracticeElevation} slight slight - * @property {BedWarsPracticeElevation} staircase staircase - */ -/** - * @typedef {Object} BedWarsPracticeRecord - * @property {BedWarsPracticeElevations} elevation Elevation - */ -/** - * @typedef {Object} BedWarsPracticeRecords - * @property {BedWarsPracticeRecord} blocks30 30 Blocks - * @property {BedWarsPracticeRecord} blocks50 50 Blocks - * @property {BedWarsPracticeRecord} blocks100 100 Blocks - */ -/** - * @typedef {Object} BedWarsPracticeBridging - * @property {number} blocksPlaced Blocks placed - * @property {BedWarsPracticeAttempts} attempts Attempts - */ -/** - * @typedef {Object} BedWarsPracticePearlClutching - * @property {BedWarsPracticeAttempts} attempts Attempts - */ -/** - * @typedef {Object} BedWarsPracticeMLG - * @property {number} blocksPlaced Blocks placed - * @property {BedWarsPracticeAttempts} attempts Attempts - */ -/** - * @typedef {Object} BedWarsPracticeStats - * @property {string} selected Selected Type of Practice - * @property {BedWarsPracticeBridging} bridging Bridging stats - * @property {BedWarsPracticePearlClutching} pearlClutching Pearl Clutching stats - * @property {BedWarsPracticeMLG} mlg MLG stats - */ -module.exports = BedWars; diff --git a/src/structures/MiniGames/BlitzSurvivalGames.js b/src/structures/MiniGames/BlitzSurvivalGames.js deleted file mode 100644 index 773d6fb6c..000000000 --- a/src/structures/MiniGames/BlitzSurvivalGames.js +++ /dev/null @@ -1,424 +0,0 @@ -const divide = require('../../utils/divide'); - -class BlitzSGKit { - /** - * @param {object} data Blitz SG data - * @param {string} kitName Kit name - */ - constructor(data, kitName) { - /** - * Kit Level - * @type {number} - */ - this.level = data[kitName] || 0; - /** - * Kit Level - * @type {number} - */ - this.exp = data[`exp_${kitName}`] || 0; - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${kitName}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${kitName}`] || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${kitName}`] || 0; - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data[`games_played_${kitName}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Arrows Shot - * @type {number} - */ - this.arrowsShot = data[`arrows_fired_${kitName}`] || 0; - /** - * Arrows Hit - * @type {number} - */ - this.arrowsHit = data[`arrows_hit_${kitName}`] || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot); - /** - * Damage Delt - * @type {number} - */ - this.damage = data[`damage_${kitName}`] || 0; - /** - * Damage Taken - * @type {number} - */ - this.damageTaken = data[`damage_taken_${kitName}`] || 0; - /** - * Potions Drunk - * @type {number} - */ - this.potionsDrunk = data[`potions_drunk_${kitName}`] || 0; - /** - * Potions Thrown - * @type {number} - */ - this.potionsThrown = data[`potions_thrown_${kitName}`] || 0; - /** - * Time Played (In seconds) - * @type {number} - */ - this.playTime = data[`time_played_${kitName}`] || 0; - /** - * Mobs Spawned - * @type {number} - */ - this.mobsSpawned = data[`mobs_spawned_${kitName}`] || 0; - /** - * Chests Opened - * @type {number} - */ - this.chestsOpened = data[`chests_opened_${kitName}`] || 0; - } -} - -/** - * Blitz SG class - */ -class BlitzSurvivalGames { - /** - * @param {object} data Blitz SG data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Kit - * @type {string} - */ - this.kit = data.defaultkit || ''; - /** - * Solo Kills - * @type {number} - */ - this.killsSolo = data.kills_solo_normal || 0; - /** - * Teams Kills - * @type {number} - */ - this.killsTeams = data.kills_teams_normal || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Solo wins - * @type {number} - */ - this.winsSolo = data.wins_solo_normal || 0; - /** - * Team wins - * @type {number} - */ - this.winsTeam = data.wins_teams || 0; - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data.games_played || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Arrows Shot - * @type {number} - */ - this.arrowsShot = data.arrows_fired || 0; - /** - * Arrows Hit - * @type {number} - */ - this.arrowsHit = data.arrows_hit || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot); - /** - * Damage Delt - * @type {number} - */ - this.damage = data.damage || 0; - /** - * Damage Taken - * @type {number} - */ - this.damageTaken = data.damage_taken || 0; - /** - * Potions Drunk - * @type {number} - */ - this.potionsDrunk = data.potions_drunk || 0; - /** - * Potions Thrown - * @type {number} - */ - this.potionsThrown = data.potions_thrown || 0; - /** - * Mobs Spawned - * @type {number} - */ - this.mobsSpawned = data.mobs_spawned || 0; - /** - * Time Played (In seconds) - * @type {number} - */ - this.playTime = data.time_played || 0; - /** - * Blitz Uses - * @type {number} - */ - this.blitzUses = data.blitz_uses || 0; - /** - * Chests Opened - * @type {number} - */ - this.chestsOpened = data.chests_opened || 0; - - /** - * Archer Kit Stats - * @type {BlitzSGKit} - */ - this.archer = new BlitzSGKit(data, 'archer'); - /** - * Meatmaster Kit Stats - * @type {BlitzSGKit} - */ - this.meatmaster = new BlitzSGKit(data, 'meatmaster'); - /** - * Speleologist Kit Stats - * @type {BlitzSGKit} - */ - this.speleologist = new BlitzSGKit(data, 'speleologist'); - /** - * Baker Kit Stats - * @type {BlitzSGKit} - */ - this.baker = new BlitzSGKit(data, 'baker'); - /** - * Knight Kit Stats - * @type {BlitzSGKit} - */ - this.knight = new BlitzSGKit(data, 'knight'); - /** - * Guardian Kit Stats - * @type {BlitzSGKit} - */ - this.guardian = new BlitzSGKit(data, 'guardian'); - /** - * Scout Kit Stats - * @type {BlitzSGKit} - */ - this.scout = new BlitzSGKit(data, 'scout'); - /** - * Hunter Kit Stats - * @type {BlitzSGKit} - */ - this.hunter = new BlitzSGKit(data, 'hunter'); - /** - * Hype Train Kit Stats - * @type {BlitzSGKit} - */ - this.hypeTrain = new BlitzSGKit(data, 'hype train'); - /** - * Fisherman Kit Stats - * @type {BlitzSGKit} - */ - this.fisherman = new BlitzSGKit(data, 'fisherman'); - /** - * Armorer Kit Stats - * @type {BlitzSGKit} - */ - this.armorer = new BlitzSGKit(data, 'armorer'); - /** - * Horsetamer Kit Stats - * @type {BlitzSGKit} - */ - this.horsetamer = new BlitzSGKit(data, 'horsetamer'); - /** - * Astronaut Kit Stats - * @type {BlitzSGKit} - */ - this.astronaut = new BlitzSGKit(data, 'astronaut'); - /** - * Troll Kit Stats - * @type {BlitzSGKit} - */ - this.troll = new BlitzSGKit(data, 'troll'); - /** - * Reaper Kit Stats - * @type {BlitzSGKit} - */ - this.reaper = new BlitzSGKit(data, 'reaper'); - /** - * Shark Kit Stats - * @type {BlitzSGKit} - */ - this.shark = new BlitzSGKit(data, 'shark'); - /** - * Reddragon Kit Stats - * @type {BlitzSGKit} - */ - this.reddragon = new BlitzSGKit(data, 'reddragon'); - /** - * Toxicologist Kit Stats - * @type {BlitzSGKit} - */ - this.toxicologist = new BlitzSGKit(data, 'toxicologist'); - /** - * Rogue Kit Stats - * @type {BlitzSGKit} - */ - this.rogue = new BlitzSGKit(data, 'rogue'); - /** - * Warlock Kit Stats - * @type {BlitzSGKit} - */ - this.warlock = new BlitzSGKit(data, 'warlock'); - /** - * Slimeyslime Kit Stats - * @type {BlitzSGKit} - */ - this.slimeyslime = new BlitzSGKit(data, 'slimeyslime'); - /** - * Jockey Kit Stats - * @type {BlitzSGKit} - */ - this.jockey = new BlitzSGKit(data, 'jockey'); - /** - * Golem Kit Stats - * @type {BlitzSGKit} - */ - this.golem = new BlitzSGKit(data, 'golem'); - /** - * Viking Kit Stats - * @type {BlitzSGKit} - */ - this.viking = new BlitzSGKit(data, 'viking'); - /** - * Shadow Knight Kit Stats - * @type {BlitzSGKit} - */ - this.shadowKnight = new BlitzSGKit(data, 'shadow knight'); - /** - * Pigman Kit Stats - * @type {BlitzSGKit} - */ - this.pigman = new BlitzSGKit(data, 'pigman'); - /** - * Paladin Kit Stats - * @type {BlitzSGKit} - */ - this.paladin = new BlitzSGKit(data, 'paladin'); - /** - * Necromancer Kit Stats - * @type {BlitzSGKit} - */ - this.necromancer = new BlitzSGKit(data, 'necromancer'); - /** - * Florist Kit Stats - * @type {BlitzSGKit} - */ - this.florist = new BlitzSGKit(data, 'florist'); - /** - * Diver Kit Stats - * @type {BlitzSGKit} - */ - this.diver = new BlitzSGKit(data, 'diver'); - /** - * Arachnologist Kit Stats - * @type {BlitzSGKit} - */ - this.arachnologist = new BlitzSGKit(data, 'arachnologist'); - /** - * Blaze Kit Stats - * @type {BlitzSGKit} - */ - this.blaze = new BlitzSGKit(data, 'blaze'); - /** - * Wolftamer Kit Stats - * @type {BlitzSGKit} - */ - this.wolftamer = new BlitzSGKit(data, 'wolftamer'); - /** - * Tim Kit Stats - * @type {BlitzSGKit} - */ - this.tim = new BlitzSGKit(data, 'tim'); - /** - * Farmer Kit Stats - * @type {BlitzSGKit} - */ - this.farmer = new BlitzSGKit(data, 'farmer'); - /** - * Creepertamer Kit Stats - * @type {BlitzSGKit} - */ - this.creepertamer = new BlitzSGKit(data, 'creepertamer'); - /** - * Snowman Kit Stats - * @type {BlitzSGKit} - */ - this.snowman = new BlitzSGKit(data, 'snowman'); - } -} - -module.exports = BlitzSurvivalGames; diff --git a/src/structures/MiniGames/BuildBattle.js b/src/structures/MiniGames/BuildBattle.js deleted file mode 100644 index 6761e8a7e..000000000 --- a/src/structures/MiniGames/BuildBattle.js +++ /dev/null @@ -1,64 +0,0 @@ -const divide = require('../../utils/divide'); -/** - * BuildBattle class - */ -class BuildBattle { - /** - * @param {object} data BuildBattle data - */ - constructor(data) { - /** - * Score - * @type {number} - */ - this.score = data.score || 0; - /** - * Total wins - * @type {number} - */ - this.totalWins = data.wins || 0; - /** - * Played games - * @type {number} - */ - this.games = data.games_played || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.totalWins, this.games); - /** - * Amount of super votes the player has - * @type {number} - */ - this.superVotes = data.super_votes || 0; - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Total votes - * @type {number} - */ - this.totalVotes = data.total_votes || 0; - /** - * Wins for each mode - * @type {BuildBattleWins} - */ - this.wins = { - solo: data.wins_solo_normal || 0, - teams: data.wins_teams_normal || 0, - pro: data.wins_solo_pro || 0, - gtb: data.wins_guess_the_build || 0 - }; - } -} -/** - * @typedef {object} BuildBattleWins - * @property {number} solo BuildBattle Solo wins - * @property {number} teams BuildBattle Team wins - * @property {number} pro BuildBattle Pro wins - * @property {number} gtb BuildBattle Guess The Build wins - */ -module.exports = BuildBattle; diff --git a/src/structures/MiniGames/CopsAndCrims.js b/src/structures/MiniGames/CopsAndCrims.js deleted file mode 100644 index 3437713c3..000000000 --- a/src/structures/MiniGames/CopsAndCrims.js +++ /dev/null @@ -1,318 +0,0 @@ -const divide = require('../../utils/divide'); -/** - * Cops and crims Defusal class - */ -class CopsAndCrimsDefusal { - /** - * @param {object} data Cops and crims data - - */ - constructor(data) { - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Headshot kills - * @type {number} - */ - this.headshotKills = data.headshot_kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.game_wins || 0; - /** - * Games played - * @type {number} - */ - this.gamesPlayed = data.game_plays || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Round wins - * @type {number} - */ - this.roundWins = data.round_wins || 0; - /** - * Shows fired - * @type {number} - */ - this.shotsFired = data.shots_fired || 0; - /** - * Bombs defused - * @type {number} - */ - this.bombsDefused = data.bombs_defused || 0; - /** - * Bombs planted - * @type {number} - */ - this.bombsPlanted = data.bombs_planted || 0; - /** - * Kills as Crim - * @type {number} - */ - this.killsAsCrim = data.criminal_kills || 0; - /** - * Kills as Cop - * @type {number} - */ - this.killsAsCop = data.cop_kills || 0; - } -} -/** - * Cops and crims Deathmatch class - */ -class CopsAndCrimsDeathmatch { - /** - * @param {object} data Cops and crims data - - */ - constructor(data) { - /** - * Kills - * @type {number} - */ - this.kills = data.kills_deathmatch || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists_deathmatch || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_deathmatch || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.game_wins_deathmatch || 0; - /** - * Games played - * @type {number} - */ - this.gamesPlayed = data.game_plays_deathmatch || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Kills as Crim - * @type {number} - */ - this.killsAsCrim = data.criminal_kills_deathmatch || 0; - /** - * Kills as Cop - * @type {number} - */ - this.killsAsCop = data.cop_kills_deathmatch || 0; - } -} -/** - * Cops and crims Gun Game class - */ -class CopsAndCrimsGunGame { - /** - * @param {object} data Cops and crims data - - */ - constructor(data) { - /** - * Kills - * @type {number} - */ - this.kills = data.kills_gungame || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists_gungame || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_gungame || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.game_wins_gungame || 0; - /** - * Games played - * @type {number} - */ - this.gamesPlayed = data.game_plays_gungame || 0; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Kills as Crim - * @type {number} - */ - this.killsAsCrim = data.criminal_kills_gungame || 0; - /** - * Kills as Cop - * @type {number} - */ - this.killsAsCop = data.cop_kills_gungame || 0; - /** - * Fastest Win - * ! WARNING This number is most likely wrong as it can be negative - * @type {number} - */ - this.fastestWin = data.fastest_win_gungame || 0; - } -} -/** - * Cops and crims class - */ -class CopsAndCrims { - /** - * @param {object} data Cops and crims data - - */ - constructor(data) { - /** - * Defusal stats - * @type {CopsAndCrimsDefusal} - */ - this.defusal = new CopsAndCrimsDefusal(data); - /** - * Deathmatch stats - * @type {CopsAndCrimsDeathmatch} - */ - this.deathmath = new CopsAndCrimsDeathmatch(data); - /** - * Gun Game stats - * @type {CopsAndCrimsGunGame} - */ - this.gunGame = new CopsAndCrimsGunGame(data); - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = this.defusal.kills + this.deathmath.kills + this.gunGame.kills; - /** - * Assists - * @type {number} - */ - this.assists = this.defusal.assists + this.deathmath.assists + this.gunGame.assists; - /** - * Deaths - * @type {number} - */ - this.deaths = this.defusal.deaths + this.deathmath.deaths + this.gunGame.deaths; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.defusal.wins + this.deathmath.wins + this.gunGame.wins; - /** - * Games played - * @type {number} - */ - this.gamesPlayed = this.defusal.gamesPlayed + this.deathmath.gamesPlayed + this.gunGame.gamesPlayed; - /** - * Losses - * @type {number} - */ - this.losses = this.gamesPlayed - this.wins; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Kills as Crim - * @type {number} - */ - this.killsAsCrim = this.defusal.killsAsCrim + this.deathmath.killsAsCrim + this.gunGame.killsAsCrim; - /** - * Kills as Cop - * @type {number} - */ - this.killsAsCop = this.defusal.killsAsCop + this.deathmath.killsAsCop + this.gunGame.killsAsCop; - /** - * Prefix Color - * @type {string} - */ - this.prefixColor = data.lobbyPrefixColor || ''; - /** - * Show Prefix - * @type {boolean} - */ - this.showPrefix = data.show_lobby_prefix || false; - /** - * Selected Prefix - * @type {string} - */ - this.selectedPrefix = data.selected_lobby_prefix || ''; - /** - * Kills In Prefix - * @type {boolean} - */ - this.killsInPrefix = data.show_kills_in_prefix || false; - } -} - -module.exports = CopsAndCrims; diff --git a/src/structures/MiniGames/Duels.js b/src/structures/MiniGames/Duels.js deleted file mode 100644 index f9ce96145..000000000 --- a/src/structures/MiniGames/Duels.js +++ /dev/null @@ -1,1013 +0,0 @@ -const { duelsDivisions } = require('../../utils/Constants'); -const romanize = require('../../utils/romanize'); -const divide = require('../../utils/divide'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function getTitle(data, mode = null) { - for (const div of duelsDivisions.slice().reverse()) { - const prestige = data[`${mode ? mode : 'all_modes'}_${div.key}_title_prestige`]; - if (prestige) { - return `${div.name} ${romanize(prestige)}`; - } - } - return null; -} - -class DuelsGamemode { - /** - * @param {object} data Duels data - */ - constructor(data, mode, title = '') { - /** - * Title - * @type {string} - */ - this.title = title; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data[`current_winstreak_mode_${mode}`] || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data[`best_winstreak_mode_${mode}`] || 0; - /** - * Kills - * @type {number} - */ - this.kills = data[`${mode}_kills`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`${mode}_deaths`] || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`${mode}_wins`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`${mode}_losses`] || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = data[`${mode}_rounds_played`] || 0; - /** - * Swings - * @type {number} - */ - this.swings = data[`${mode}_melee_swings`] || 0; - /** - * Hits - * @type {number} - */ - this.hits = data[`${mode}_melee_hits`] || 0; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.swings, this.hits); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = data[`${mode}_bow_shots`] || 0; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = data[`${mode}_bow_hits`] || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowShots, this.bowHits); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data[`${mode}_blocks_placed`] || 0; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = data[`${mode}_health_regenerated`] || 0; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = data[`${mode}_golden_apples_eaten`] || 0; - /** - * Goals (only shows up in bridge) - * @type {number} - */ - this.goals = data[`${mode}_goals`] || 0; - } -} - -class DuelsUHC { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = getTitle(data, 'uhc'); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.current_uhc_winstreak || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data.best_uhc_winstreak || 0; - /** - * Solo Game Mode Stats - * @type {DuelsGamemode} - */ - this.solo = new DuelsGamemode(data, 'uhc_duel', this.title); - /** - * Doubles Game Mode Stats - * @type {DuelsGamemode} - */ - this.doubles = new DuelsGamemode(data, 'uhc_doubles', this.title); - /** - * Fours Game Mode Stats - * @type {DuelsGamemode} - */ - this.fours = new DuelsGamemode(data, 'uhc_four', this.title); - /** - * Deathmatch Game Mode Stats - * @type {DuelsGamemode} - */ - this.deathmatch = new DuelsGamemode(data, 'uhc_meetup', this.title); - /** - * Kills - * @type {number} - */ - this.kills = this.solo.kills + this.doubles.kills + this.fours.kills + this.deathmatch.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.solo.deaths + this.doubles.deaths + this.fours.deaths + this.deathmatch.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.solo.wins + this.doubles.wins + this.fours.wins + this.deathmatch.wins; - /** - * Losses - * @type {number} - */ - this.losses = this.solo.losses + this.doubles.losses + this.fours.losses + this.deathmatch.losses; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = - this.solo.playedGames + this.doubles.playedGames + this.fours.playedGames + this.deathmatch.playedGames; - /** - * Swings - * @type {number} - */ - this.swings = this.solo.swings + this.doubles.swings + this.fours.swings + this.deathmatch.swings; - /** - * Hits - * @type {number} - */ - this.hits = this.solo.hits + this.doubles.hits + this.fours.hits + this.deathmatch.hits; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = this.solo.bowShots + this.doubles.bowShots + this.fours.bowShots + this.deathmatch.bowShots; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = this.solo.bowHits + this.doubles.bowHits + this.fours.bowHits + this.deathmatch.bowHits; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = - this.solo.blocksPlaced + this.doubles.blocksPlaced + this.fours.blocksPlaced + this.deathmatch.blocksPlaced; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = - this.solo.healthRegenerated + - this.doubles.healthRegenerated + - this.fours.healthRegenerated + - this.deathmatch.healthRegenerated; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = - this.solo.goldenApplesEatan + - this.doubles.goldenApplesEatan + - this.fours.goldenApplesEatan + - this.deathmatch.goldenApplesEatan; - } -} -class DuelsSkyWars { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = getTitle(data, 'sw'); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.current_sw_winstreak || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data.best_sw_winstreak || 0; - /** - * Solo Game Mode Stats - * @type {DuelsGamemode} - */ - this.solo = new DuelsGamemode(data, 'sw_duel', this.title); - /** - * Doubles Game Mode Stats - * @type {DuelsGamemode} - */ - this.doubles = new DuelsGamemode(data, 'sw_doubles', this.title); - /** - * Kills - * @type {number} - */ - this.kills = this.solo.kills + this.doubles.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.solo.deaths + this.doubles.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.solo.wins + this.doubles.wins; - /** - * Losses - * @type {number} - */ - this.losses = this.solo.losses + this.doubles.losses; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = this.solo.playedGames + this.doubles.playedGames; - /** - * Swings - * @type {number} - */ - this.swings = this.solo.swings + this.doubles.swings; - /** - * Hits - * @type {number} - */ - this.hits = this.solo.hits + this.doubles.hits; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = this.solo.bowShots + this.doubles.bowShots; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = this.solo.bowHits + this.doubles.bowHits; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = this.solo.goldenApplesEatan + this.doubles.goldenApplesEatan; - } -} -class DuelsMegaWalls { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = getTitle(data, 'mega_walls'); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.current_mega_walls_winstreak || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data.best_mega_walls_winstreak || 0; - /** - * Solo Game Mode Stats - * @type {DuelsGamemode} - */ - this.solo = new DuelsGamemode(data, 'mw_duel', this.title); - /** - * Doubles Game Mode Stats - * @type {DuelsGamemode} - */ - this.doubles = new DuelsGamemode(data, 'mw_doubles', this.title); - /** - * Kills - * @type {number} - */ - this.kills = this.solo.kills + this.doubles.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.solo.deaths + this.doubles.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.solo.wins + this.doubles.wins; - /** - * Losses - * @type {number} - */ - this.losses = this.solo.losses + this.doubles.losses; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = this.solo.playedGames + this.doubles.playedGames; - /** - * Swings - * @type {number} - */ - this.swings = this.solo.swings + this.doubles.swings; - /** - * Hits - * @type {number} - */ - this.hits = this.solo.hits + this.doubles.hits; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = this.solo.bowShots + this.doubles.bowShots; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = this.solo.bowHits + this.doubles.bowHits; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = this.solo.goldenApplesEatan + this.doubles.goldenApplesEatan; - } -} -class DuelsOP { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = getTitle(data, 'op'); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.current_op_winstreak || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data.best_op_winstreak || 0; - /** - * Solo Game Mode Stats - * @type {DuelsGamemode} - */ - this.solo = new DuelsGamemode(data, 'op_duel', this.title); - /** - * Doubles Game Mode Stats - * @type {DuelsGamemode} - */ - this.doubles = new DuelsGamemode(data, 'op_doubles', this.title); - /** - * Kills - * @type {number} - */ - this.kills = this.solo.kills + this.doubles.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.solo.deaths + this.doubles.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.solo.wins + this.doubles.wins; - /** - * Losses - * @type {number} - */ - this.losses = this.solo.losses + this.doubles.losses; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = this.solo.playedGames + this.doubles.playedGames; - /** - * Swings - * @type {number} - */ - this.swings = this.solo.swings + this.doubles.swings; - /** - * Hits - * @type {number} - */ - this.hits = this.solo.hits + this.doubles.hits; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = this.solo.bowShots + this.doubles.bowShots; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = this.solo.bowHits + this.doubles.bowHits; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = this.solo.blocksPlaced + this.doubles.blocksPlaced; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = this.solo.healthRegenerated + this.doubles.healthRegenerated; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = this.solo.goldenApplesEatan + this.doubles.goldenApplesEatan; - } -} -class DuelsBridge { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = getTitle(data, 'bridge'); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.current_bridge_winstreak || 0; - /** - * Best Winstreak - * @type {number} - */ - this.bestWinstreak = data.best_bridge_winstreak || 0; - /** - * Solo Game Mode Stats - * @type {DuelsGamemode} - */ - this.solo = new DuelsGamemode(data, 'bridge_duel', this.title); - /** - * Doubles Game Mode Stats - * @type {DuelsGamemode} - */ - this.doubles = new DuelsGamemode(data, 'bridge_doubles', this.title); - /** - * Threes Game Mode Stats - * @type {DuelsGamemode} - */ - this.threes = new DuelsGamemode(data, 'bridge_threes', this.title); - /** - * Fours Game Mode Stats - * @type {DuelsGamemode} - */ - this.fours = new DuelsGamemode(data, 'bridge_fours', this.title); - /** - * 2v2v2v2 Game Mode Stats - * @type {DuelsGamemode} - */ - this['2v2v2v2'] = new DuelsGamemode(data, '2v2v2v2', this.title); - /** - * 3v3v3v3 Game Mode Stats - * @type {DuelsGamemode} - */ - this['3v3v3v3'] = new DuelsGamemode(data, '3v3v3v3', this.title); - /** - * Capture The Flag Game Mode Stats - * @type {DuelsGamemode} - */ - this.ctf = new DuelsGamemode(data, 'capture_threes', this.title); - /** - * Kills - * @type {number} - */ - this.kills = - this.solo.kills + - this.doubles.kills + - this.threes.kills + - this.fours.kills + - this['2v2v2v2'].kills + - this['3v3v3v3'].kills + - this.ctf.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = - this.solo.deaths + - this.doubles.deaths + - this.threes.deaths + - this.fours.deaths + - this['2v2v2v2'].deaths + - this['3v3v3v3'].deaths + - this.ctf.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = - this.solo.wins + - this.doubles.wins + - this.threes.wins + - this.fours.wins + - this['2v2v2v2'].wins + - this['3v3v3v3'].wins + - this.ctf.wins; - /** - * Losses - * @type {number} - */ - this.losses = - this.solo.losses + - this.doubles.losses + - this.threes.losses + - this.fours.losses + - this['2v2v2v2'].losses + - this['3v3v3v3'].losses + - this.ctf.losses; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played Games - * @type {number} - */ - this.playedGames = - this.solo.playedGames + - this.doubles.playedGames + - this.threes.playedGames + - this.fours.playedGames + - this['2v2v2v2'].playedGames + - this['3v3v3v3'].playedGames + - this.ctf.playedGames; - /** - * Swings - * @type {number} - */ - this.swings = - this.solo.swings + - this.doubles.swings + - this.threes.swings + - this.fours.swings + - this['2v2v2v2'].swings + - this['3v3v3v3'].swings + - this.ctf.swings; - /** - * Hits - * @type {number} - */ - this.hits = - this.solo.hits + - this.doubles.hits + - this.threes.hits + - this.fours.hits + - this['2v2v2v2'].hits + - this['3v3v3v3'].hits + - this.ctf.hits; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = - this.solo.bowShots + - this.doubles.bowShots + - this.threes.bowShots + - this.fours.bowShots + - this['2v2v2v2'].bowShots + - this['3v3v3v3'].bowShots + - this.ctf.bowShots; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = - this.solo.bowHits + - this.doubles.bowHits + - this.threes.bowHits + - this.fours.bowHits + - this['2v2v2v2'].bowHits + - this['3v3v3v3'].bowHits + - this.ctf.bowHits; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = - this.solo.blocksPlaced + - this.doubles.blocksPlaced + - this.threes.blocksPlaced + - this.fours.blocksPlaced + - this['2v2v2v2'].blocksPlaced + - this['3v3v3v3'].blocksPlaced + - this.ctf.blocksPlaced; - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = - this.solo.healthRegenerated + - this.doubles.healthRegenerated + - this.threes.healthRegenerated + - this.fours.healthRegenerated + - this['2v2v2v2'].healthRegenerated + - this['3v3v3v3'].healthRegenerated + - this.ctf.healthRegenerated; - /** - * Golden Apples Eatan - * @type {number} - */ - this.goldenApplesEatan = - this.solo.goldenApplesEatan + - this.doubles.goldenApplesEatan + - this.threes.goldenApplesEatan + - this.fours.goldenApplesEatan + - this['2v2v2v2'].goldenApplesEatan + - this['3v3v3v3'].goldenApplesEatan + - this.ctf.goldenApplesEatan; - /** - * Goals - * @type {number} - */ - this.goals = - this.solo.goals + - this.doubles.goals + - this.threes.goals + - this.fours.goals + - this['2v2v2v2'].goals + - this['3v3v3v3'].goals + - this.ctf.goals; - } -} - -/** - * Duels class - */ -class Duels { - /** - * @param {object} data Duels data - */ - constructor(data) { - /** - * Tokens - * @type {number} - */ - this.tokens = data.coins || 0; - /** - * All modes Title - * @type {string|null} - */ - this.title = getTitle(data); - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played games - * @type {number} - */ - this.playedGames = data.games_played_duels || 0; - /** - * Current winstreak - * @type {number} - */ - this.winstreak = data.current_winstreak || 0; - /** - * Best overall winstreak - * @type {number} - */ - this.bestWinstreak = data.best_overall_winstreak || 0; - /** - * Ping Range Preference - * @type {number} - */ - this.ping = data.pingPreference || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data.blocks_placed || 0; - /** - * Swings - * @type {number} - */ - this.swings = data.melee_swings || 0; - /** - * Hits - * @type {number} - */ - this.hits = data.melee_hits || 0; - /** - * Melee Accuracy - * @type {number} - */ - this.meleeAccuracy = divide(this.hits, this.swings); - /** - * Bow Shots - * @type {number} - */ - this.bowShots = data.bow_shots || 0; - /** - * Bow Hits - * @type {number} - */ - this.bowHits = data.bow_hits || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.bowHits, this.bowShots); - /** - * Health Regenerated - * @type {number} - */ - this.healthRegenerated = data.health_regenerated || 0; - /** - * Golden Apples Eaten - * @type {number} - */ - this.goldenApplesEatan = data.golden_apples_eaten || 0; - /** - * UHC duels stats - * @type {DuelsUHC} - */ - this.uhc = new DuelsUHC(data); - - /** - * SkyWars duels stats - * @type {DuelsSkyWars} - */ - this.skywars = new DuelsSkyWars(data); - /** - * MegaWalls duels stats - * @type {DuelsMegaWalls} - */ - this.megawalls = new DuelsMegaWalls(data); - /** - * Blitz duel stats - * @type {DuelsGamemode} - */ - this.blitz = new DuelsGamemode(data, 'blitz_duel', getTitle(data, 'blitz')); - /** - * OP duels stats - * @type {DuelsOP} - */ - this.op = new DuelsOP(data); - /** - * Classic duels stats - * @type {DuelsGamemode} - */ - this.classic = new DuelsGamemode(data, 'classic_duel', getTitle(data, 'classic')); - /** - * Bow duels stats - * @type {DuelsGamemode} - */ - this.bow = new DuelsGamemode(data, 'bow_duel', getTitle(data, 'bow')); - /** - * No Debuff duels stats - * @type {DuelsGamemode} - */ - this.noDebuff = new DuelsGamemode(data, 'potion_duel', getTitle(data, 'no_debuff')); - /** - * Combo duels stats - * @type {DuelsGamemode} - */ - this.combo = new DuelsGamemode(data, 'combo_duel', getTitle(data, 'combo')); - /** - * Bow Spleef duels stats - * @type {DuelsGamemode} - */ - this.bowSpleef = new DuelsGamemode(data, 'bowspleef_duel', getTitle(data, 'tnt_games')); - /** - * Sumo duels stats - * @type {DuelsGamemode} - */ - this.sumo = new DuelsGamemode(data, 'sumo_duel', getTitle(data, 'sumo')); - /** - * Bridge duels stats - * @type {DuelsBridge} - */ - this.bridge = new DuelsBridge(data); - /** - * Parkour duels stats - * @type {DuelsGamemode} - */ - this.parkour = new DuelsGamemode(data, 'parkour_eight', getTitle(data, 'parkour')); - /** - * Arena duels stats - * @type {DuelsGamemode} - */ - this.arena = new DuelsGamemode(data, 'duel_arena'); - } -} - -module.exports = Duels; diff --git a/src/structures/MiniGames/MegaWalls.js b/src/structures/MiniGames/MegaWalls.js deleted file mode 100644 index 5953df25c..000000000 --- a/src/structures/MiniGames/MegaWalls.js +++ /dev/null @@ -1,478 +0,0 @@ -const divide = require('../../utils/divide'); - -class MegaWallsModeStats { - /** - * @param {object} data MegaWalls data - * @param {string} mode MegaWalls Mode - * @param {string} kit MegaWalls Kit - */ - constructor(data, mode, kit) { - if (kit) kit = `${kit}_`; - /** - * Kills - * @type {number} - */ - this.kills = data[`${kit}kills_${mode}`] || 0; - /** - * Assists - * @type {number} - */ - this.assists = data[`${kit}assists_${mode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`${kit}deaths_${mode}`] || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`${kit}wins_${mode}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`${kit}losses_${mode}`] || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Final kills - * @type {number} - */ - this.finalKills = data[`${kit}final_kills_${mode}`] || 0; - /** - * Final assists - * @type {number} - */ - this.finalAssists = data[`${kit}final_assists_${mode}`] || 0; - /** - * Final deaths - * @type {number} - */ - this.finalDeaths = data[`${kit}final_deaths_${mode}`] || 0; - /** - * Final Kill Death ratio - * @type {number} - */ - this.finalKDRatio = divide(this.finalKills, this.finalDeaths); - /** - * Played games - * @type {number} - */ - this.playedGames = data[`${kit}games_played_${mode}`] || 0; - /** - * Wither damage - * @type {number} - */ - this.witherDamage = data[`${kit}wither_damage_${mode}`] || 0; - /** - * Defender kills - * @type {number} - */ - this.defenderKills = data[`${kit}defender_kills_${mode}`] || 0; - /** - * Walked - * @type {number} - */ - this.walked = data[`${kit}meters_walked_${mode}`] || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data[`${kit}blocks_placed_${mode}`] || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data[`${kit}blocks_broken_${mode}`] || 0; - /** - * Melee Kills - * @type {number} - */ - this.meleeKills = data[`${kit}kills_melee_${mode}`] || 0; - /** - * Damage Delt - * @type {number} - */ - this.damageDealt = data[`${kit}damage_dealt_${mode}`] || 0; - } -} -class MegaWallsKitStats { - /** - * @param {object} data MegaWalls data - * @param {string} kit MegaWalls Kit - */ - constructor(data, kit) { - /** - * Kills - * @type {number} - */ - this.kills = data[`${kit}_kills`] || 0; - /** - * Assists - * @type {number} - */ - this.assists = data[`${kit}_assists`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`${kit}_deaths`] || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`${kit}_wins`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`${kit}_losses`] || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Final kills - * @type {number} - */ - this.finalKills = data[`${kit}_final_kills`] || 0; - /** - * Final assists - * @type {number} - */ - this.finalAssists = data[`${kit}_final_assists`] || 0; - /** - * Final deaths - * @type {number} - */ - this.finalDeaths = data[`${kit}_final_deaths`] || 0; - /** - * Final Kill Death ratio - * @type {number} - */ - this.finalKDRatio = divide(this.finalKills, this.finalDeaths); - /** - * Played games - * @type {number} - */ - this.playedGames = data[`${kit}_games_played`] || 0; - /** - * Wither damage - * @type {number} - */ - this.witherDamage = data[`${kit}_wither_damage`] || 0; - /** - * Defender kills - * @type {number} - */ - this.defenderKills = data[`${kit}_defender_kills`] || 0; - /** - * Walked - * @type {number} - */ - this.walked = data[`${kit}_meters_walked`] || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data[`${kit}_blocks_placed`] || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data[`${kit}_blocks_broken`] || 0; - /** - * Melee Kills - * @type {number} - */ - this.meleeKills = data[`${kit}_kills_melee`] || 0; - /** - * Damage Delt - * @type {number} - */ - this.damageDealt = data[`${kit}_damage_dealt`] || 0; - /** - * Stats for each mode - * @type {MegaWallsModeStats} - */ - this.faceOff = new MegaWallsModeStats(data, 'face_off', kit); - /** - * Stats for each mode - * @type {MegaWallsModeStats} - */ - this.casualBrawl = new MegaWallsModeStats(data, 'gvg', kit); - } -} - -/** - * MegaWalls class - */ -class MegaWalls { - /** - * @param {object} data MegaWalls data - */ - constructor(data) { - /** - * Selected class - * @type {string|null} - */ - this.selectedClass = data.chosen_class || null; - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Final kills - * @type {number} - */ - this.finalKills = (data.final_kills || 0) + (data.finalkills || 0); - /** - * Final assists - * @type {number} - */ - this.finalAssists = (data.final_assists || 0) + (data.finalassists || 0); - /** - * Final deaths - * @type {number} - */ - this.finalDeaths = (data.final_deaths || 0) + (data.finalDeaths || 0); - /** - * Final Kill Death ratio - * @type {number} - */ - this.finalKDRatio = divide(this.finalKills, this.finalDeaths); - /** - * Played games - * @type {number} - */ - this.playedGames = data.games_played || 0; - /** - * Wither damage - * @type {number} - */ - this.witherDamage = (data.wither_damage || 0) + (data.witherDamager || 0); - /** - * Defender kills - * @type {number} - */ - this.defenderKills = data.defender_kills || 0; - /** - * Walked - * @type {number} - */ - this.walked = data.meters_walked || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data.blocks_placed || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data.blocks_broken || 0; - /** - * Melee Kills - * @type {number} - */ - this.meleeKills = data.kills_melee || 0; - /** - * Damage Delt - * @type {number} - */ - this.damageDealt = data.damage_dealt || 0; - /** - * Stats for each mode - * @type {MegaWallsModeStats} - */ - this.faceOff = new MegaWallsModeStats(data, 'face_off'); - /** - * Stats for each mode - * @type {MegaWallsModeStats} - */ - this.casualBrawl = new MegaWallsModeStats(data, 'gvg'); - /** - * cow kit stats - * @type {MegaWallsKitStats} - */ - this.cow = new MegaWallsKitStats(data, 'cow'); - /** - * hunter kit stats - * @type {MegaWallsKitStats} - */ - this.hunter = new MegaWallsKitStats(data, 'hunter'); - /** - * shark kit stats - * @type {MegaWallsKitStats} - */ - this.shark = new MegaWallsKitStats(data, 'shark'); - /** - * arcanist kit stats - * @type {MegaWallsKitStats} - */ - this.arcanist = new MegaWallsKitStats(data, 'arcanist'); - /** - * deadlord kit stats - * @type {MegaWallsKitStats} - */ - this.deadlord = new MegaWallsKitStats(data, 'deadlord'); - /** - * golem kit stats - * @type {MegaWallsKitStats} - */ - this.golem = new MegaWallsKitStats(data, 'golem'); - /** - * herobrine kit stats - * @type {MegaWallsKitStats} - */ - this.herobrine = new MegaWallsKitStats(data, 'herobrine'); - /** - * pigman kit stats - * @type {MegaWallsKitStats} - */ - this.pigman = new MegaWallsKitStats(data, 'pigman'); - /** - * zombie kit stats - * @type {MegaWallsKitStats} - */ - this.zombie = new MegaWallsKitStats(data, 'zombie'); - /** - * blaze kit stats - * @type {MegaWallsKitStats} - */ - this.blaze = new MegaWallsKitStats(data, 'blaze'); - /** - * enderman kit stats - * @type {MegaWallsKitStats} - */ - this.enderman = new MegaWallsKitStats(data, 'enderman'); - /** - * shaman kit stats - * @type {MegaWallsKitStats} - */ - this.shaman = new MegaWallsKitStats(data, 'shaman'); - /** - * squid kit stats - * @type {MegaWallsKitStats} - */ - this.squid = new MegaWallsKitStats(data, 'squid'); - /** - * creeper kit stats - * @type {MegaWallsKitStats} - */ - this.creeper = new MegaWallsKitStats(data, 'creeper'); - /** - * pirate kit stats - * @type {MegaWallsKitStats} - */ - this.pirate = new MegaWallsKitStats(data, 'pirate'); - /** - * sheep kit stats - * @type {MegaWallsKitStats} - */ - this.sheep = new MegaWallsKitStats(data, 'sheep'); - /** - * skeleton kit stats - * @type {MegaWallsKitStats} - */ - this.skeleton = new MegaWallsKitStats(data, 'skeleton'); - /** - * spider kit stats - * @type {MegaWallsKitStats} - */ - this.spider = new MegaWallsKitStats(data, 'spider'); - /** - * werewolf kit stats - * @type {MegaWallsKitStats} - */ - this.werewolf = new MegaWallsKitStats(data, 'werewolf'); - /** - * angel kit stats - * @type {MegaWallsKitStats} - */ - this.angel = new MegaWallsKitStats(data, 'angel'); - /** - * assassin kit stats - * @type {MegaWallsKitStats} - */ - this.assassin = new MegaWallsKitStats(data, 'assassin'); - /** - * automaton kit stats - * @type {MegaWallsKitStats} - */ - this.automaton = new MegaWallsKitStats(data, 'automaton'); - /** - * moleman kit stats - * @type {MegaWallsKitStats} - */ - this.moleman = new MegaWallsKitStats(data, 'moleman'); - /** - * phoenix kit stats - * @type {MegaWallsKitStats} - */ - this.phoenix = new MegaWallsKitStats(data, 'phoenix'); - /** - * renegade kit stats - * @type {MegaWallsKitStats} - */ - this.renegade = new MegaWallsKitStats(data, 'renegade'); - /** - * snowman kit stats - * @type {MegaWallsKitStats} - */ - this.snowman = new MegaWallsKitStats(data, 'snowman'); - } -} - -module.exports = MegaWalls; diff --git a/src/structures/MiniGames/MurderMystery.js b/src/structures/MiniGames/MurderMystery.js deleted file mode 100644 index 6da7df1c6..000000000 --- a/src/structures/MiniGames/MurderMystery.js +++ /dev/null @@ -1,214 +0,0 @@ -const divide = require('../../utils/divide'); - -/** - * MurderMystery stats by gamemode - */ -class MurderMysteryModeStats { - /** - * Constructor - * @param {Object} data Data from API - * @param {string} gamemode String gamemode name - */ - constructor(data, gamemode) { - /** - * Amount of gold picked up in games - * @type {number} - */ - this.goldPickedUp = data[`coins_pickedup_${gamemode}`] || 0; - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${gamemode}`] || 0; - /** - * Thrown Knife Kills - * @type {number} - */ - this.thrownKnifeKills = data[`thrown_knife_kills_${gamemode}`] || 0; - /** - * Knife Kills - * @type {number} - */ - this.knifeKills = data[`knife_kills_${gamemode}`] || 0; - /** - * Bow Kills - * @type {number} - */ - this.bowKills = data[`bow_kills_${gamemode}`] || 0; - /** - * Trap Kills - * @type {number} - */ - this.trapKills = data[`trap_kills_${gamemode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${gamemode}`] || 0; - /** - * Suicides - * @type {number} - */ - this.suicides = data[`suicides_${gamemode}`] || 0; - - /** - * Kill/Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins as Murderer - * @type {number} - */ - this.wins = data[`wins_${gamemode}`] || 0; - /** - * Wins as Detective - * @type {number} - */ - this.winsAsDetective = data[`detective_wins_${gamemode}`] || 0; - /** - * Wins as Murderer - * @type {number} - */ - this.winsAsMurderer = data[`murderer_wins_${gamemode}`] || 0; - /** - * Wins as Hero - * @type {number} - */ - this.winsAsHero = data[`was_hero_${gamemode}`] || 0; - /** - * Played games - * @type {number} - */ - this.playedGames = data[`games_${gamemode}`] || 0; - } -} - -/** - * MurderMystery class - */ -class MurderMystery { - /** - * @param {object} data MurderMystery data - */ - constructor(data) { - /** - * Tokens - * @type {number} - */ - this.tokens = data.coins || 0; - /** - * Amount of gold picked up in games - * @type {number} - */ - this.goldPickedUp = data.coins_pickedup || 0; - /** - * Played games - * @type {number} - */ - this.playedGames = data.games || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Thrown Knife Kills - * @type {number} - */ - this.thrownKnifeKills = data.thrown_knife_kills || 0; - /** - * Knife Kills - * @type {number} - */ - this.knifeKills = data.knife_kills || 0; - /** - * Trap Kills - * @type {number} - */ - this.trapKills = data.trap_kills || 0; - /** - * Bow Kills - * @type {number} - */ - this.bowKills = data.bow_kills || 0; - /** - * Kills As Murderer - * @type {number} - */ - this.killsAsMurderer = data.kills_as_murderer || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill/Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins as Murderer - * @type {number} - */ - this.winsAsMurderer = data.murderer_wins || 0; - /** - * Wins as Detective - * @type {number} - */ - this.winsAsDetective = data.detective_wins || 0; - /** - * Wins as Hero - * @type {number} - */ - this.winsAsHero = data.was_hero || 0; - /** - * Fastest win as the Murderer (Time in seconds) - * @type {number} - */ - this.fastestWinAsMurderer = data.quickest_murderer_win_time_seconds || 0; - /** - * Fastest win as the Detective (Time in seconds) - * @type {number} - */ - this.fastestWinAsDetective = data.quickest_detective_win_time_seconds || 0; - /** - * Total time Survived (Time in seconds) - * @type {number} - */ - this.totalTimeSurvived = data.total_time_survived_seconds || 0; - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Suicides - * @type {number} - */ - this.suicides = data.suicides || 0; - /** - * Classic - * @type {MurderMysteryModeStats} - */ - this.classic = new MurderMysteryModeStats(data, 'MURDER_CLASSIC'); - /** - * Assasins - * @type {MurderMysteryModeStats} - */ - this.assassins = new MurderMysteryModeStats(data, 'MURDER_ASSASSINS'); - /** - * Double Up - * @type {MurderMysteryModeStats} - */ - this.doubleUp = new MurderMysteryModeStats(data, 'MURDER_DOUBLE_UP'); - - /** - * Infection - * @type {MurderMysteryModeStats} - */ - this.infection = new MurderMysteryModeStats(data, 'MURDER_INFECTION'); - } -} - -module.exports = MurderMystery; diff --git a/src/structures/MiniGames/Paintball.js b/src/structures/MiniGames/Paintball.js deleted file mode 100644 index 41840e307..000000000 --- a/src/structures/MiniGames/Paintball.js +++ /dev/null @@ -1,87 +0,0 @@ -const divide = require('../../utils/divide'); -/** - * Paintball class - */ -class Paintball { - /** - * @param {object} data Paintball data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Shots fired - * @type {number} - */ - this.shotsFired = data.shots_fired || 0; - /** - * Kill streaks - * @type {number} - */ - this.killstreaks = data.killstreaks || 0; - /** - * Forcefield Time - * @type {number} - */ - this.forceFieldTime = data.forcefieldTime || 0; - /** - * Hat - * @type {string} - */ - this.hat = data.hat || 'None'; - /** - * Adrenaline Perk Level - * @type {number} - */ - this.adrenaline = data.adrenaline || 0; - /** - * Endurance Perk Level - * @type {number} - */ - this.endurance = data.endurance || 0; - /** - * Fortune Perk Level - * @type {number} - */ - this.fortune = data.fortune || 0; - /** - * Godfather Perk Level - * @type {number} - */ - this.godfather = data.godfather || 0; - /** - * Superluck Perk Level - * @type {number} - */ - this.superluck = data.superluck || 0; - /** - * Transfusion Perk Level - * @type {number} - */ - this.transfusion = data.transfusion || 0; - } -} -module.exports = Paintball; diff --git a/src/structures/MiniGames/Pit.js b/src/structures/MiniGames/Pit.js deleted file mode 100644 index d533359fb..000000000 --- a/src/structures/MiniGames/Pit.js +++ /dev/null @@ -1,247 +0,0 @@ -const { decode } = require('../../utils/SkyblockUtils'); -const PitInventoryItem = require('./PitInventoryItem'); -const { divide } = require('../../utils'); -const { - pit: { Levels, Prestiges } -} = require('../../utils/Constants'); - -/** - * Pit Class - */ -class Pit { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data) { - const stats = data.pit_stats_ptl || {}; - /** - * Prestige - * @type {number} - */ - this.prestige = data.profile?.prestiges?.[data.profile?.prestiges?.length - 1].index || 0; - /** - * Xp - * @type {number} - */ - this.xp = data.profile?.xp || 0; - /** - * Level - * @type {number} - */ - this.level = - Pit.calcLevel(this.prestige, 0 < this.prestige ? this.xp - Prestiges[this.prestige - 1].SumXp : this.xp).level ?? - 0; - /** - * Kills - * @type {number} - */ - this.kills = stats.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = stats.deaths || 0; - /** - * KDR - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Assists - * @type {number} - */ - this.assists = stats.assists || 0; - /** - * Max kill streak - * @type {number} - */ - this.maxKillStreak = stats.max_streak || 0; - /** - * Playtime in SECONDS - * @type {number} - */ - this.playtime = (stats.playtime_minutes || 0) * 60; - /** - * Times the played joined Pit - * @type {number} - */ - this.joins = stats.joins || 0; - - // Damage section (overall) - /** - * Damage received overall - * @type {number} - */ - this.damageReceived = stats.damage_received || 0; - /** - * Damage dealt overall - * @type {number} - */ - this.damageDealt = stats.damage_dealt || 0; - /** - * Damage dealt to damage received ratio - * @type {number} - */ - this.damageRatio = divide(this.damageDealt, this.damageReceived); - // Melee damage - /** - * Damage received in melee - * @type {number} - */ - this.meleeDamageReceived = stats.melee_damage_received || 0; - /** - * Damage dealt in melee - * @type {number} - */ - this.meleeDamageDealt = stats.melee_damage_dealt || 0; - /** - * Sword hits - * @type {number} - */ - this.swordHits = stats.sword_hits || 0; - /** - * Left Clicks (sword clicks, hit or miss) - * @type {number} - */ - this.leftClicks = stats.left_clicks || 0; - /** - * Hits divided by left clicks - * @type {number} - */ - this.meleeAccuracy = divide(this.swordHits, this.leftClicks); - /** - * Damage dealt to damage received ratio in melee - * @type {number} - */ - this.meleeDamageRatio = divide(this.meleeDamageDealt, this.meleeDamageReceived); - // Arrow damage - /** - * Damage received by arrow - * @type {number} - */ - this.bowDamageReceived = stats.bow_damage_received || 0; - /** - * Damage dealt with bow - * @type {number} - */ - this.bowDamageDealt = stats.bow_damage_dealt || 0; - /** - * Arrows hit - * @type {number} - */ - this.arrowsHit = stats.arrow_hits || 0; - /** - * Arrows fired (hit + missed) - * @type {number} - */ - this.arrowsFired = stats.arrows_fired || 0; - /** - * Hit divided by Fired - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsFired); - /** - * Damage dealt to damage received ratio in ranged (bow/arrow) - * @type {number} - */ - this.bowDamageRatio = divide(this.bowDamageDealt, this.bowDamageReceived); - /** - * Golden Heads eaten - * @type {number} - */ - this.goldenHeadsEaten = stats.ghead_eaten || 0; - /** - * Pit Player Inv - * @return {Promise} - */ - this.getInventory = async () => { - let inventory = data.profile.inv_contents; - if (!inventory) return []; - - try { - inventory = await decode(inventory.data); - const edited = []; - for (let i = 1; i < inventory.length; i++) { - if (!inventory[i].id) { - continue; - } - edited.push(new PitInventoryItem(inventory[i])); - } - return edited; - } catch { - return []; - } - }; - /** - * Pit Player Ender Chest - * @return {Promise} - */ - this.getEnterChest = async () => { - let chest = data.profile.inv_enderchest; - if (!chest) return []; - - try { - chest = await decode(chest.data); - const edited = []; - for (let i = 1; i < chest.length; i++) { - if (!chest[i].id) { - continue; - } - edited.push(new PitInventoryItem(chest[i])); - } - return edited; - } catch { - return []; - } - }; - /** - * Pit Player Armor - * @return {Promise} - */ - this.getArmor = async () => { - const base64 = data.profile.inv_armor; - const decoded = await decode(base64.data); - const armor = { - helmet: decoded[3].id ? new PitInventoryItem(decoded[3]) : null, - chestplate: decoded[2].id ? new PitInventoryItem(decoded[2]) : null, - leggings: decoded[1].id ? new PitInventoryItem(decoded[1]) : null, - boots: decoded[0].id ? new PitInventoryItem(decoded[0]) : null - }; - return armor; - }; - } - // Credit https://github.com/PitPanda/PitPandaProduction/blob/b1971f56ea1aa8c829b722cbb33247c96591c0cb/structures/Pit.js - /** - * Converts XP to Level - * @param {number} prestige Prestige Level - * @param {number} xp Current xp into the prestige - * @return {number} - */ - static calcLevel(prestige, xp) { - const multiplier = Prestiges[prestige].Multiplier; - let level = 0; - while (0 < xp && 120 > level) { - const levelXp = Levels[Math.floor(level / 10)].Xp * multiplier; - if (xp >= levelXp * 10) { - xp -= levelXp * 10; - level += 10; - } else { - const gain = Math.floor(xp / levelXp); - level += gain; - xp = 0; - } - } - return level; - } -} - -/** - * @typedef {object} PitArmor Equipped armor - * @property {PitInventoryItem|null} helmet Helmet - * @property {PitInventoryItem|null} chestplate Chestplate - * @property {PitInventoryItem|null} leggings Leggings - * @property {PitInventoryItem|null} boots Boots - */ - -module.exports = Pit; diff --git a/src/structures/MiniGames/PitInventoryItem.js b/src/structures/MiniGames/PitInventoryItem.js deleted file mode 100644 index 411b73900..000000000 --- a/src/structures/MiniGames/PitInventoryItem.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Item class - */ -class PitInventoryItem { - /** - * @param {object} data Item data - */ - constructor(data) { - /** - * Item ID - * @type {number} - */ - this.itemId = data.id || 0; - /** - * Item count - * @type {number} - */ - this.count = data.Count || 0; - /** - * Item name - * @type {string|null} - */ - this.name = data?.tag?.display?.Name ? data.tag.display.Name.toString().replace(/§([1-9]|[a-f])|§/gm, '') : null; - /** - * Item lore - * @type {string|null} - */ - this.lore = data?.tag?.display?.Lore ? data.tag.display.Lore.join('\n') : null; - /** - * Item lore - * @type {string[]} - */ - this.loreArray = data?.tag?.display?.Lore ?? []; - /** - * Item Extra Attributes - * @type {object|null} - */ - - this.extraAttributes = data?.tag?.ExtraAttributes ?? null; - } -} - -module.exports = PitInventoryItem; diff --git a/src/structures/MiniGames/Quakecraft.js b/src/structures/MiniGames/Quakecraft.js deleted file mode 100644 index 201171f93..000000000 --- a/src/structures/MiniGames/Quakecraft.js +++ /dev/null @@ -1,164 +0,0 @@ -const divide = require('../../utils/divide'); - -class QuakecraftMode { - /** - * @param {object} data Quakecraft data - * @param {string} gamemode Gamemode Name - */ - constructor(data, gamemode) { - if (gamemode) gamemode = `_${gamemode}`; - /** - * Wins - * @type {number} - */ - this.wins = data[`wins${gamemode}`] || 0; - /** - * Kills - * @type {number} - */ - this.kills = data[`kills${gamemode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths${gamemode}`] || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Kill streaks - * @type {number} - */ - this.killstreaks = data[`killstreaks${gamemode}`] || 0; - /** - * Distance travelled - * @type {number} - */ - this.distanceTravelled = data[`distance_travelled${gamemode}`] || 0; - /** - * Shots fired - * @type {number} - */ - this.shotsFired = data[`shots_fired${gamemode}`] || 0; - /** - * Headshots - * @type {number} - */ - this.headshots = data[`headshots${gamemode}`] || 0; - } -} - -/** - * Quakecraft class - */ -class Quakecraft { - /** - * @param {object} data Quakecraft data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Solo Quakecraft stats - * @type {QuakecraftMode} - */ - this.solo = new QuakecraftMode(data); - /** - * Teams Quakecraft stats - * @type {QuakecraftMode} - */ - this.teams = new QuakecraftMode(data, 'teams'); - /** - * Wins - * @type {number} - */ - this.wins = this.solo.wins + this.teams.wins; - /** - * Kills - * @type {number} - */ - this.kills = this.solo.kills + this.teams.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.solo.deaths + this.teams.deaths; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Kill streaks - * @type {number} - */ - this.killstreaks = this.solo.killstreaks + this.teams.killstreaks; - /** - * Distance travelled - * @type {number} - */ - this.distanceTravelled = this.solo.distanceTravelled + this.teams.distanceTravelled; - /** - * Shots fired - * @type {number} - */ - this.shotsFired = this.solo.shotsFired + this.teams.shotsFired; - /** - * Headshots - * @type {number} - */ - this.headshots = this.solo.headshots + this.teams.headshots; - /** - * Instant Respawn - * @type {boolean} - */ - this.instantRespawn = data.instantRespawn || false; - /** - * Kill Prefix Color - * @type {string} - */ - this.killPrefixColor = data.selectedKillPrefix || ''; - /** - * Show Prefix - * @type {boolean} - */ - this.showPrefix = data.showKillPrefix || false; - /** - * Kill Sound - * @type {string} - */ - this.killSound = data.killsound || ''; - /** - * Barrel - * @type {string} - */ - this.barrel = data.barrel || ''; - /** - * Case - * @type {string} - */ - this.case = data.case || ''; - /** - * Muzzle - * @type {string} - */ - this.muzzle = data.muzzle || ''; - /** - * Sight - * @type {string} - */ - this.sight = data.sight || ''; - /** - * Trigger - * @type {string} - */ - this.trigger = data.trigger || ''; - } -} - -module.exports = Quakecraft; diff --git a/src/structures/MiniGames/SkyWars.js b/src/structures/MiniGames/SkyWars.js deleted file mode 100644 index 8ca5b721d..000000000 --- a/src/structures/MiniGames/SkyWars.js +++ /dev/null @@ -1,669 +0,0 @@ -const { removeSnakeCaseString } = require('../../utils/removeSnakeCase'); -const { SkyWarsPrestigeIcons } = require('../../utils/Constants'); -const divide = require('../../utils/divide'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function getSkyWarsPrestige(level) { - if (60 <= level) return 'Mythic'; - return ( - ['Iron', 'Iron', 'Gold', 'Diamond', 'Emerald', 'Sapphire', 'Ruby', 'Crystal', 'Opal', 'Amethyst', 'Rainbow'][ - Math.floor(level / 5) - ] || 'Iron' - ); -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function getSkyWarsLevel(xp) { - const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500]; - if (15000 <= xp) return Math.floor((xp - 15000) / 10000 + 12); - const level = totalXp.findIndex((x) => 0 < x * 10 - xp); - return level; -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function getSkyWarsLevelProgress(xp) { - const totalXp = [0, 2, 7, 15, 25, 50, 100, 200, 350, 600, 1000, 1500]; - const xpToNextLvl = [0, 2, 5, 8, 10, 25, 50, 100, 150, 250, 400, 500]; - let percent; - let xpToNextLevel; - let currentLevelXp = xp; - if (15000 <= xp) { - currentLevelXp -= 15000; - if (0 === currentLevelXp) return { currentLevelXp: 0, xpToNextLevel: 10000, percent: 0, xpNextLevel: 10000 }; - if (10000 < currentLevelXp) { - do { - currentLevelXp -= 10000; - } while (10000 <= currentLevelXp); - } - xpToNextLevel = 10000 - currentLevelXp; - percent = Math.round(currentLevelXp) / 100; - const percentRemaining = Math.round((100 - percent) * 100) / 100; - return { - currentLevelXp, - xpToNextLevel, - percent, - xpNextLevel: 10000, - percentRemaining - }; - } - const totalXptoNextLevel = xpToNextLvl[totalXp.findIndex((x) => 0 < x * 10 - xp)] * 10; - for (let i = 0; i < xpToNextLvl.length; i++) { - if (0 > currentLevelXp - xpToNextLvl[i] * 10) break; - currentLevelXp -= xpToNextLvl[i] * 10; - } - xpToNextLevel = totalXptoNextLevel - currentLevelXp; - percent = Math.round((currentLevelXp / totalXptoNextLevel) * 10000) / 100; - return { - currentLevelXp, - xpToNextLevel, - percent, - xpNextLevel: totalXptoNextLevel - }; -} - -class SkywarsMode { - /** - * @param {object} data Skywars data - * @param {string} gamemode Gamemode Name - */ - constructor(data, gamemode) { - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${gamemode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${gamemode}`] || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(data.kills, data.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${gamemode}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`losses_${gamemode}`] || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(data.wins, data.losses); - } -} -class SkywarsModeStats { - /** - * @param {object} data Skywars data - * @param {string} gamemode Gamemode Name - */ - constructor(data, gamemode) { - /** - * Active Kit - * @type {string} - */ - this.activeKit = data[`activeKit_${gamemode.toUpperCase()}`] || ''; - /** - * Kill Streak - * @type {number} - */ - this.killstreak = data[`killstreak_${gamemode}`] || 0; - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${gamemode}`] || 0; - /** - * Void Kills - * @type {number} - */ - this.voidKills = data[`void_kills_${gamemode}`] || 0; - /** - * Melee Kills - * @type {number} - */ - this.meleeKills = data[`melee_kills_${gamemode}`] || 0; - /** - * Bow Kills - * @type {number} - */ - this.bowKills = data[`bow_kills_${gamemode}`] || 0; - /** - * Mob Kills - * @type {number} - */ - this.mobKills = data[`mob_kills_${gamemode}`] || 0; - /** - * Assists - * @type {number} - */ - this.assists = data[`assists_${gamemode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${gamemode}`] || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(data.kills, data.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${gamemode}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`losses_${gamemode}`] || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(data.wins, data.losses); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data[`games_${gamemode}`] || 0; - /** - * Survived Players - * @type {number} - */ - this.survivedPlayers = data[`survived_players_${gamemode}`] || 0; - /** - * Chests Opened - * @type {number} - */ - this.chestsOpened = data[`chests_opened_${gamemode}`] || 0; - /** - * Time Played (In Seconds) - * @type {number} - */ - this.timePlayed = data[`time_played_${gamemode}`] || 0; - /** - * Shard - * @type {number} - */ - this.shard = data[`shard_${gamemode}`] || 0; - /** - * Longest Bow Shot - * @type {number} - */ - this.longestBowShot = data[`longest_bow_shot_${gamemode}`] || 0; - /** - * Arrows Shot - * @type {number} - */ - this.arrowsShot = data[`arrows_shot_${gamemode}`] || 0; - /** - * Arrows Hit - * @type {number} - */ - this.arrowsHit = data[`arrows_hit_${gamemode}`] || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot); - /** - * Fastest Win (In Seconds) - * @type {number} - */ - this.fastestWin = data[`fastest_win_${gamemode}`] || 0; - /** - * Heads - * @type {number} - */ - this.heads = data[`heads_${gamemode}`] || 0; - } -} - -/** - * Parses SkyWars Kit - */ -class SkywarsKit { - /** - * Constructor - * @param {string} kit Kit -w */ - constructor(kit) { - /** - * Kit data - * @private - * @type {string[] | null} - */ - this.kitData = kit.match(/^kit_([a-z]+)_([a-z]+)_([a-z]+)$/); - /** - * Is this a kit - * @type {boolean} - */ - this.isKit = Boolean(this.kitData); - if (!this.kitData) return; - /** - * Game mode the kit is for - * @type {KitGameModes} - */ - this.gameMode = this.kitData[2]; - /** - * Kit type - * @type {KitType} - */ - this.kitType = this.kitData[1]; - /** - * Kit name in camelCase - * @type {string} - */ - this.kitName = removeSnakeCaseString(this.kitData[3]); - } -} - -/** - * Parses SkyWars Kits - */ -class SkywarsKits { - /** - * Constructor - * @param {SkywarsKit[]} kits Potential Kits -w */ - constructor(kits) { - this.kits = kits.map((kit) => new SkywarsKit(kit)).filter((kit) => kit.isKit); - } - /** - * Get kit by type/gameMode - * @param {KitGameModes} [gameMode] Kits in said game mode - * @param {KitType} [type] Kits corresponding to this type - * @returns {SkywarsKit[]} -w */ - get(gameMode = '', type = '') { - return this.kits.filter((kit) => kit.gameMode.startsWith(gameMode) && kit.kitType.startsWith(type)); - } -} -/** - * Skywars Packages - parses every package player has - */ -class SkywarsPackages { - /** - * Constructor - * @param {string[]} data data from API -w */ - constructor(data) { - // TODO : a lot more - /** - * Raw Packages, as received from the API - * @type {string[]} - */ - this.rawPackages = data; - /** - * Cages - * @type {string[]} - */ - this.cages = this.parseCages(); - /** - * Kits - * @type {SkywarsKits} - */ - this.kits = new SkywarsKits(data); - /** - * Achievements included in packages, under the form of name0 - * @type {string[]} - */ - this.achievements = this.rawPackages - .map((pkg) => pkg.match(/^([A-Za-z]+)_?achievement([0-9]?)$/)) - .filter((x) => x) - .map((x) => x.slice(1).join('')); - } - /** - * Parses cages - * @returns {string[]} -w */ - parseCages() { - return this.rawPackages - .map((pkg) => pkg.match(/^cage_([A-Za-z]+)-cage$/)) - .filter((x) => x) - .map((x) => x[1].replace(/-[a-z]/g, (x) => x[1].toUpperCase())); - } -} - -/** - * @typedef {string} KitType - * * basic - * * supporting - * * mining - * * defending - * * attacking - * * advanced - * * enderchest - */ -/** - * @typedef {string} KitGameModes - * * solo - * * team - */ - -/** - * SkyWars class - */ -class SkyWars { - /** - * @param {object} data SkyWars data -w */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Souls - * @type {number} - */ - this.souls = data.souls || 0; - /** - * Tokens - * @type {number} - */ - this.tokens = data.cosmetic_tokens || 0; - /** - * Experience - * @type {number} - */ - this.experience = data.skywars_experience || 0; - /** - * Level - * @type {number} - */ - this.level = getSkyWarsLevel(data.skywars_experience); - /** - * Level Progress - * @type {LevelProgress} - */ - this.levelProgress = getSkyWarsLevelProgress(data.skywars_experience); - /** - * Formatted Level - * @type {string} - */ - this.levelFormatted = data.levelFormatted - ? data.levelFormatted - .replace(/§l/gm, '**') - .replace(/§([a-f]|[1-9])/gm, '') - .replace(/§r/gm, '') - : null; - /** - * Prestige - * @type {SkyWarsPrestige} - */ - this.prestige = getSkyWarsPrestige(this.level); - /** - * Prestige Icons - * @type {SkyWarsPrestigeIcons} - */ - this.prestigeIcon = data.selected_prestige_icon ? SkyWarsPrestigeIcons[data.selected_prestige_icon] : null; - /** - * Opals - * @type {number} - */ - this.opals = data.opals || 0; - /** - * Avarice - * @type {number} - */ - this.avarice = data.avarice || 0; - /** - * Tenacity - * @type {number} - */ - this.tenacity = data.tenacity || 0; - /** - * Shards - * @type {number} - */ - this.shards = data.shard || 0; - /** - * Angel Of Death Level - * @type {number} - */ - this.angelOfDeathLevel = data.angel_of_death_level || 0; - - /** - * Killstreak - * @type {number} - */ - this.killstreak = data.killstreak || 0; - /** - * kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Void Kills - * @type {number} - */ - this.voidKills = data.void_kills || 0; - /** - * Melee Kills - * @type {number} - */ - this.meleeKills = data.melee_kills || 0; - /** - * Bow Kills - * @type {number} - */ - this.bowKills = data.bow_kills || 0; - /** - * Mob Kills - * @type {number} - */ - this.mobKills = data.mob_kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(data.kills, data.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(data.wins, data.losses); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data.games || 0; - /** - * Survived Players - * @type {number} - */ - this.survivedPlayers = data.survived_players || 0; - /** - * Chests Opened - * @type {number} - */ - this.chestsOpened = data.chests_opened || 0; - /** - * Time Played (In Seconds) - * @type {number} - */ - this.timePlayed = data.time_played || 0; - /** - * Shard - * @type {number} - */ - this.shard = data.shard || 0; - /** - * Longest Bow Shot - * @type {number} - */ - this.longestBowShot = data.longest_bow_shot || 0; - /** - * Arrows Shot - * @type {number} - */ - this.arrowsShot = data.arrows_shot || 0; - /** - * Arrows Hit - * @type {number} - */ - this.arrowsHit = data.arrows_hit || 0; - /** - * Bow Accuracy - * @type {number} - */ - this.bowAccuracy = divide(this.arrowsHit, this.arrowsShot); - /** - * Fastest Win - * @type {number} - */ - this.fastestWin = data.fastest_win || 0; - /** - * Heads - * @type {number} - */ - this.heads = data.heads || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data.blocks_placed || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data.blocks_broken || 0; - /** - * Egg Thrown - * @type {number} - */ - this.eggThrown = data.egg_thrown || 0; - /** - * Enderpearls Thrown - * @type {number} - */ - this.enderpearlsThrown = data.enderpearls_thrown || 0; - - /** - * Solo Skywars Stats - * @type {SkywarsModeStats} - */ - this.solo = new SkywarsModeStats(data, 'solo'); - /** - * Solo Normal Stats - * @type {SkywarsMode} - */ - this.soloNormal = new SkywarsMode(data, 'solo_normal'); - /** - * Solo Insane Stats - * @type {SkywarsMode} - */ - this.soloInsane = new SkywarsMode(data, 'solo_insane'); - /** - * Team Skywars Stats - * @type {SkywarsModeStats} - */ - this.team = new SkywarsModeStats(data, 'team'); - /** - * Team Normal Stats - * @type {SkywarsMode} - */ - this.teamNormal = new SkywarsMode(data, 'team_normal'); - /** - * Team Insane Stats - * @type {SkywarsMode} - */ - this.teamInsane = new SkywarsMode(data, 'team_insane'); - /** - * Mega Skywars Stats - * @type {SkywarsMode} - */ - this.mega = new SkywarsMode(data, 'mega'); - /** - * Mega Doubles Skywars Stats - * @type {SkywarsMode} - */ - this.megaDoubles = new SkywarsMode(data, 'mega_doubles'); - /** - * Skywars Laboratory Stats - * @type {SkywarsMode} - */ - this.lab = new SkywarsMode(data, 'lab'); - /** - * Player Packages, can range from kits to achievement - * @type {SkywarsPackages} - */ - this.packages = new SkywarsPackages(data.packages || []); - } -} -/** - * @typedef {string} SkyWarsPrestige - * * `Iron` - * * `Iron` - * * `Gold` - * * `Diamond` - * * `Emerald` - * * `Sapphire` - * * `Ruby` - * * `Crystal` - * * `Opal` - * * `Amethyst` - * * `Rainbow` - * * `Mythic` - */ -/** - * @typedef {string} SkyWarsPrestigeIcons - * * '⋆' - * * '★' - * * '☆' - * * '⁕', - * * '✶', - * * '✳', - * * '✴', - * * '✷', - * * '❋', - * * '✼', - * * '❂', - * * '❁', - * * '☬', - * * '✙', - * * '❤️', - * * '☠', - * * '✦', - * * '✌', - * * '❦', - * * '✵', - * * '❣', - * * '☯', - * * '✺', - * * 'ಠ_ಠ', - * * '⚔' - */ - -module.exports = SkyWars; diff --git a/src/structures/MiniGames/SmashHeroes.js b/src/structures/MiniGames/SmashHeroes.js deleted file mode 100644 index 6b60a543a..000000000 --- a/src/structures/MiniGames/SmashHeroes.js +++ /dev/null @@ -1,272 +0,0 @@ -const divide = require('../../utils/divide'); - -class SmashHeroesMode { - /** - * @param {object} data SmashHeroes data - * @param {string} mode SmashHeores mode - */ - constructor(data, mode) { - /** - * kills - * @type {number} - */ - this.kills = data[`kills_${mode}`] || 0; - /** - * deaths - * @type {number} - */ - this.deaths = data[`deaths_${mode}`] || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * wins - * @type {number} - */ - this.wins = data[`wins_${mode}`] || 0; - /** - * losses - * @type {number} - */ - this.losses = data[`losses_${mode}`] || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - } -} - -class SmashHeoresHero { - /** - * @param {object} data SmashHeroes data - * @param {string} hero Hero name - */ - constructor(data, hero) { - /** - * Hero Name - * @type {string} - */ - this.name = hero; - /** - * Level - * @type {number} - */ - this.level = data[`lastLevel_${hero}`] || 0; - /** - * Xp - * @type {number} - */ - this.xp = data[`xp_${hero}`] || 0; - /** - * Prestige - * @type {number} - */ - this.prestige = data[`pg_${hero}`] || 0; - /** - * Played Games - * @type {number} - */ - this.playedGames = data.class_stats?.[hero]?.games || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.class_stats?.[hero]?.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.class_stats?.[hero]?.deaths || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.class_stats?.[hero]?.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.class_stats?.[hero]?.losses || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - } -} - -/** - * SmashHeroes class - */ -class SmashHeroes { - /** - * @param {object} data SmashHeroes data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Level - * @type {number} - */ - this.level = data.smash_level_total || 0; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.win_streak || 0; - /** - * Played games - * @type {number} - */ - this.playedGames = data.games || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill/Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win/Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Smashed - * @type {number} - */ - this.smashed = data.smashed || 0; - /** - * Stats for each mode - * @type {SmashHeroesMode} - */ - this['1v1v1v1'] = new SmashHeroesMode(data, 'normal'); - /** - * Stats for each mode - * @type {SmashHeroesMode} - */ - this['2v2'] = new SmashHeroesMode(data, '2v2'); - /** - * Stats for each mode - * @type {SmashHeroesMode} - */ - this['2v2v2'] = new SmashHeroesMode(data, 'teams'); - /** - * Active class - * @type {string} - */ - this.activeClass = data.active_class || null; - /** - * The Bulk - * @type {SmashHeoresHero} - */ - this.theBulk = new SmashHeoresHero(data, 'THE_BULK'); - /** - * Cake Monster - * @type {SmashHeoresHero} - */ - this.cakeMonster = new SmashHeoresHero(data, 'CAKE_MONSTER'); - /** - * General Cluck - * @type {SmashHeoresHero} - */ - this.generalCluck = new SmashHeoresHero(data, 'GENERAL_CLUCK'); - /** - * Botmun - * @type {SmashHeoresHero} - */ - this.botmun = new SmashHeoresHero(data, 'BOTMUN'); - /** - * Marauder - * @type {SmashHeoresHero} - */ - this.marauder = new SmashHeoresHero(data, 'MARAUDER'); - /** - * Pug - * @type {SmashHeoresHero} - */ - this.pug = new SmashHeoresHero(data, 'PUG'); - /** - * Tinman - * @type {SmashHeoresHero} - */ - this.tinman = new SmashHeoresHero(data, 'TINMAN'); - /** - * Spoderman - * @type {SmashHeoresHero} - */ - this.spoderman = new SmashHeoresHero(data, 'SPODERMAN'); - /** - * Frosty - * @type {SmashHeoresHero} - */ - this.frosty = new SmashHeoresHero(data, 'FROSTY'); - /** - * Sergeant Shield - * @type {SmashHeoresHero} - */ - this.sergeantShield = new SmashHeoresHero(data, 'SERGEANT_SHIELD'); - /** - * Skullfire - * @type {SmashHeoresHero} - */ - this.skullfire = new SmashHeoresHero(data, 'SKULLFIRE'); - /** - * Goku - * @type {SmashHeoresHero} - */ - this.goku = new SmashHeoresHero(data, 'GOKU'); - /** - * Sanic - * @type {SmashHeoresHero} - */ - this.sanic = new SmashHeoresHero(data, 'SANIC'); - /** - * Dusk Crawler - * @type {SmashHeoresHero} - */ - this.duskCrawler = new SmashHeoresHero(data, 'DUSK_CRAWLER'); - /** - * Shoop Da Whoop - * @type {SmashHeoresHero} - */ - this.shoopDaWhoop = new SmashHeoresHero(data, 'SHOOP_DA_WHOOP'); - /** - * Green Hood - * @type {SmashHeoresHero} - */ - this.greenHood = new SmashHeoresHero(data, 'GREEN_HOOD'); - } -} - -module.exports = SmashHeroes; diff --git a/src/structures/MiniGames/SpeedUHC.js b/src/structures/MiniGames/SpeedUHC.js deleted file mode 100644 index 6b852d8f5..000000000 --- a/src/structures/MiniGames/SpeedUHC.js +++ /dev/null @@ -1,168 +0,0 @@ -const divide = require('../../utils/divide'); - -class SpeedUHCMode { - /** - * @param {object} data Speed UHC data - * @param {string} data Speed UHC data - */ - constructor(data, mode) { - /** - * Kills - * @type {number} - */ - this.kills = data[`kills_${mode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths_${mode}`] || 0; - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${mode}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`losses_${mode}`] || 0; - /** - * Played Games - * @type {number} - */ - this.playedGames = data[`games_${mode}`] || 0; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data[`win_streak_${mode}`] || 0; - /** - * Kill Streak - * @type {number} - */ - this.killStreak = data[`killstreak_${mode}`] || 0; - /** - * Assists - * @type {number} - */ - this.assists = data[`assists_${mode}`] || 0; - } -} - -/** - * Speed UHC class - */ -class SpeedUHC { - /** - * @param {object} data Speed UHC data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill/Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win/Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Played games - * @type {number} - */ - this.playedGames = data.games || 0; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.win_streak || 0; - /** - * Killstreak - * @type {number} - */ - this.killstreak = data.killstreak || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data.blocks_broken || 0; - /** - * Blocks Placed - * @type {number} - */ - this.blocksPlaced = data.blocks_placed || 0; - /** - * Game Quits - * @type {number} - */ - this.quits = data.quits || 0; - /** - * Items Enchanted - * @type {number} - */ - this.itemsEnchanted = data.items_enchanted || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - /** - * Solo - * @type {SpeedUHCMode} - */ - this.solo = new SpeedUHCMode(data, 'solo'); - /** - * Solo Normal - * @type {SpeedUHCMode} - */ - this.soloNormal = new SpeedUHCMode(data, 'solo_normal'); - /** - * Solo Insane - * @type {SpeedUHCMode} - */ - this.soloInsane = new SpeedUHCMode(data, 'solo_insane'); - /** - * Team - * @type {SpeedUHCMode} - */ - this.team = new SpeedUHCMode(data, 'team'); - /** - * Team Normal - * @type {SpeedUHCMode} - */ - this.teamNormal = new SpeedUHCMode(data, 'team_normal'); - /** - * Team Insane - * @type {SpeedUHCMode} - */ - this.teamInsane = new SpeedUHCMode(data, 'team_insane'); - } -} - -module.exports = SpeedUHC; diff --git a/src/structures/MiniGames/TNTGames.js b/src/structures/MiniGames/TNTGames.js deleted file mode 100644 index 0e4e6ae5b..000000000 --- a/src/structures/MiniGames/TNTGames.js +++ /dev/null @@ -1,285 +0,0 @@ -const divide = require('../../utils/divide'); - -class TNTRun { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_tntrun || 0; - /** - * Best Time (in seconds) - * @type {number} - */ - this.bestTime = data.record_tntrun || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_tntrun || 0; - /** - * Slowness Potion Perk Level - * @type {number} - */ - this.slownessPotions = data.new_tntrun_slowness_potions || 0; - /** - * Speed Potion Perk Level - * @type {number} - */ - this.speedPotions = data.new_tntrun_speed_potions || 0; - /** - * Double Jump Perk Level - * @type {number} - */ - this.doubleJumps = data.new_tntrun_double_jumps || 0; - /** - * prefix - * @type {string} - */ - this.prefix = data.prefix_tntrun || ''; - } -} -class PVPRun { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_pvprun || 0; - /** - * Best Time Alive (in seconds) - * @type {number} - */ - this.bestTime = data.record_pvprun || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_pvprun || 0; - /** - * Daths - * @type {number} - */ - this.deaths = data.deaths_pvprun || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Regeneration Perk Level - * @type {number} - */ - this.regeneration = data.new_pvprun_regeneration || 0; - /** - * Notoriety Perk Level - * @type {number} - */ - this.notoriety = data.new_pvprun_notoriety || 0; - /** - * Fortitude Perk Level - * @type {number} - */ - this.fortitude = data.new_pvprun_fortitude || 0; - /** - * Double Jump Perk level - * @type {number} - */ - this.doubleJumps = data.new_pvprun_double_jumps || 0; - /** - * Prefix - * @type {string} - */ - this.prefix = data.prefix_pvprun || ''; - } -} -class BowSpleef { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * wins - * @type {number} - */ - this.wins = data.wins_bowspleef || 0; - /** - * tags - * @type {number} - */ - this.tags = data.tags_bowspleef || 0; - /** - * deaths - * @type {number} - */ - this.deaths = data.deaths_bowspleef || 0; - /** - * prefix - * @type {string} - */ - this.prefix = data.prefix_bowspleef || ''; - } -} -class TNTTag { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_tntag || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_tntag || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_tntag || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Speed Perk Level - * @type {number} - */ - this.speed = data.new_tntag_speedy || 0; - /** - * Blast Protection Perk Level - * @type {number} - */ - this.blastProtection = data.tag_blastprotection || 0; - /** - * Speed It Up Perk Level - * @type {number} - */ - this.speedItUp = data.tag_speeditup || 0; - /** - * Slow It Down Perk Level - * @type {number} - */ - this.slowItDown = data.tag_slowitdown || 0; - /** - * Prefix - * @type {string} - */ - this.prefix = data.prefix_tntag || ''; - } -} -class TNTWizards { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data.wins_capture || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills_capture || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists_capture || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths_capture || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Points - * @type {number} - */ - this.points = data.points_capture || 0; - /** - * Kinetic Healing - * @type {number} - */ - this.kineticHealing = data.kinetic_healing_capture || 0; - /** - * Air Time (In seconds) - * @type {number} - */ - this.airTime = data.air_time_capture || 0; - /** - * Prefix - * @type {string} - */ - this.prefix = data.prefix_capture || ''; - } -} - -/** - * The TNT Games class - */ -class TNTGames { - /** - * @param {object} data TNT Games data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.winstreak || 0; - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * TNT Run - * @type {TNTRun} - */ - this.tntrun = new TNTRun(data); - /** - * PVP Run - * @type {PVPRun} - */ - this.pvpRun = new PVPRun(data); - /** - * Bowspleef - * @type {BowSpleef} - */ - this.bowSpleef = new BowSpleef(data); - /** - * TNT Tag - * @type {TNTTag} - */ - this.tnttag = new TNTTag(data); - /** - * Wizards - * @type {TNTWizards} - */ - this.wizards = new TNTWizards(data); - } -} - -module.exports = TNTGames; diff --git a/src/structures/MiniGames/TurboKartRacers.js b/src/structures/MiniGames/TurboKartRacers.js deleted file mode 100644 index 898274d1b..000000000 --- a/src/structures/MiniGames/TurboKartRacers.js +++ /dev/null @@ -1,141 +0,0 @@ -class TurboKartRacersMap { - /** - * @param {object} data TurboKartRacers data - * @param {string} mapName TurboKartRacers Map - */ - constructor(data, mapName) { - /** - * Map - * @type {string} - */ - this.map = mapName; - /** - * Plays - * @type {number} - */ - this.plays = data[`${mapName}_plays`] || 0; - /** - * Box Pickups - * @type {number} - */ - this.boxPickups = data[`box_pickups_${mapName}`] || 0; - /** - * Bronze Trophies - * @type {number} - */ - this.bronzeTrophies = data[`bronze_trophy_${mapName}`] || 0; - /** - * Silver Trophies - * @type {number} - */ - this.silverTrophies = data[`silver_trophy_${mapName}`] || 0; - /** - * Gold Trophies - * @type {number} - */ - this.goldTrophies = data[`gold_trophy_${mapName}`] || 0; - } -} - -/** - * TurboKartRacers class - */ -class TurboKartRacers { - /** - * @param {object} data TurboKartRacers data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Completed laps - * @type {number} - */ - this.completedLaps = data.laps_completed || 0; - /** - * Bronze trophies - * @type {number} - */ - this.bronzeTrophies = data.bronze_trophy || 0; - /** - * Silver trophies - * @type {number} - */ - this.silverTrophies = data.silver_trophy || 0; - /** - * Gold trophies - * @type {number} - */ - this.goldTrophies = data.gold_trophy || 0; - /** - * Box pickups - * @type {number} - */ - this.boxPickups = data.box_pickups || 0; - /** - * Horn - * @type {'DEFAULT' | 'SHY' | 'ALIEN' | 'TAXI' | 'KLAXON' | 'TRICYCLE' | 'ALARM' | 'KLOON' | 'TEDDY' | 'TRUCK' | 'JERRY'} - */ - this.horn = data.horn || 'DEFAULT'; - /** - * retro Map Stats - * @type {TurboKartRacersMap} - */ - this.retro = new TurboKartRacersMap(data, 'retro'); - /** - * HypixelHP Map Stats - * @type {TurboKartRacersMap} - */ - this.hypixelgp = new TurboKartRacersMap(data, 'hypixelgp'); - /** - * Olympus Map Stats - * @type {TurboKartRacersMap} - */ - this.olympus = new TurboKartRacersMap(data, 'olympus'); - /** - * Jungle Rush Map Stats - * @type {TurboKartRacersMap} - */ - this.junglerush = new TurboKartRacersMap(data, 'junglerush'); - /** - * Canyon Map Stats - * @type {TurboKartRacersMap} - */ - this.canyon = new TurboKartRacersMap(data, 'canyon'); - /** - * Bananas Recived - * @type {number} - */ - this.bananaHitsReceived = data.banana_hits_received || 0; - /** - * Bananas Sent - * @type {number} - */ - this.bananaHitsSent = data.banana_hits_sent || 0; - /** - * Blue Torpedos Hit - * @type {number} - */ - this.blueTorpedoHit = data.blue_torpedo_hit || 0; - /** - * Grand Prix Status - * @type {boolean} - */ - this.grandPrix = data.grand_prix || 'false'; - /** - * Grand Prix Tokens - * @type {number} - */ - this.grandPrixTokens = data.grand_prix_tokens || 0; - } -} - -module.exports = TurboKartRacers; diff --git a/src/structures/MiniGames/UHC.js b/src/structures/MiniGames/UHC.js deleted file mode 100644 index a3fd79baf..000000000 --- a/src/structures/MiniGames/UHC.js +++ /dev/null @@ -1,193 +0,0 @@ -const divide = require('../../utils/divide'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function getStarLevel(kills, wins) { - const sum = Number(kills) + wins * 10; - let starLevel = 1; - const sums = [0, 1, 6, 21, 46, 96, 171, 271, 521, 1021, 1321, 1621, 1921, 2221, 2521, Infinity]; - starLevel += sums.map((x) => x * 10 - sum).findIndex((x) => 0 < x) - 1; - return starLevel; -} - -class UHCGamemode { - /** - * @param {object} data UHC data - * @param {string} mode UHC Mode Name - */ - constructor(data, mode = '') { - /** - * Kills - * @type {number} - */ - this.kills = data[`kills${mode}`] || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`deaths${mode}`] || 0; - /** - * Wins - * @type {number} - */ - this.wins = data[`wins${mode}`] || 0; - /** - * Golden Heads Eaten - * @type {number} - */ - this.headsEaten = data[`heads_eaten${mode}`] || 0; - /** - * Ultimates Crafted - * @type {number} - */ - this.ultimatesCrafted = data[`ultimates_crafted${mode}`] || 0; - /** - * Extra Ultimates Crafted - * @type {number} - */ - this.extraUltimatesCrafted = data[`extra_ultimates_crafted${mode}`] || 0; - } -} - -/** - * UHC class - */ -class UHC { - /** - * @param {object} data UHC data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Score - * @type {number} - */ - this.score = data.score || 0; - /** - * Selected Kit - * @type {string} - */ - this.kit = data.equippedKit || ''; - /** - * Solo - * @type {UHCGamemode} - */ - this.solo = new UHCGamemode(data, '_solo'); - /** - * Teams - * @type {UHCGamemode} - */ - this.team = new UHCGamemode(data); - /** - * Red vs Blue - * @type {UHCGamemode} - */ - this.redVsBlue = new UHCGamemode(data, '_red_vs_blue'); - /** - * No Diamond - * @type {UHCGamemode} - */ - this.noDiamond = new UHCGamemode(data, '_no_diamonds'); - /** - * Brawl - * @type {UHCGamemode} - */ - this.brawl = new UHCGamemode(data, '_brawl'); - /** - * Solo brawl - * @type {UHCGamemode} - */ - this.soloBrawl = new UHCGamemode(data, '_solo_brawl'); - /** - * Duo Brawl - * @type {UHCGamemode} - */ - this.duoBrawl = new UHCGamemode(data, '_duo_brawl'); - /** - * Wins - * @type {number} - */ - this.wins = - this.solo.wins + - this.team.wins + - this.redVsBlue.wins + - this.noDiamond.wins + - this.brawl.wins + - this.soloBrawl.wins + - this.duoBrawl.wins; - /** - * Kills - * @type {number} - */ - this.kills = - this.solo.kills + - this.team.kills + - this.redVsBlue.kills + - this.noDiamond.kills + - this.brawl.kills + - this.soloBrawl.kills + - this.duoBrawl.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = - this.solo.deaths + - this.team.deaths + - this.redVsBlue.deaths + - this.noDiamond.deaths + - this.brawl.deaths + - this.soloBrawl.deaths + - this.duoBrawl.deaths; - /** - * Kill/Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Heads eaten - * @type {number} - */ - this.headsEaten = - this.solo.headsEaten + - this.team.headsEaten + - this.redVsBlue.headsEaten + - this.noDiamond.headsEaten + - this.brawl.headsEaten + - this.soloBrawl.headsEaten + - this.duoBrawl.headsEaten; - /** - * Ultimates Crafted - * @type {number} - */ - this.ultimatesCrafted = - this.solo.ultimatesCrafted + - this.team.ultimatesCrafted + - this.redVsBlue.ultimatesCrafted + - this.noDiamond.ultimatesCrafted + - this.brawl.ultimatesCrafted + - this.soloBrawl.ultimatesCrafted + - this.duoBrawl.ultimatesCrafted; - /** - * Extra Ultimates Crafted - * @type {number} - */ - this.extraUltimatesCrafted = - this.solo.extraUltimatesCrafted + - this.team.extraUltimatesCrafted + - this.redVsBlue.extraUltimatesCrafted + - this.noDiamond.extraUltimatesCrafted + - this.brawl.extraUltimatesCrafted + - this.soloBrawl.extraUltimatesCrafted + - this.duoBrawl.extraUltimatesCrafted; - /** - * Star level - * @type {number} - */ - this.starLevel = getStarLevel(this.kills, this.wins); - } -} -module.exports = UHC; diff --git a/src/structures/MiniGames/VampireZ.js b/src/structures/MiniGames/VampireZ.js deleted file mode 100644 index 4939ad57e..000000000 --- a/src/structures/MiniGames/VampireZ.js +++ /dev/null @@ -1,93 +0,0 @@ -const divide = require('../../utils/divide'); - -class VampireZRole { - /** - * @param {object} data VampireZ data - * @param {string} role VampireZ Role - */ - constructor(data, role) { - /** - * Kills - * @type {number} - */ - this.kills = data[`${role}_kills`]; - /** - * Deaths - * @type {number} - */ - this.deaths = data[`${role}_deaths`]; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data[`${role}_wins`]; - } -} - -/** - * VampireZ class - */ -class VampireZ { - /** - * @param {object} data VampireZ data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Gold Bought - * @type {number} - */ - this.goldBought = data.gold_bought || 0; - /** - * Blood - * @type {boolean} - */ - this.blood = data.blood || false; - /** - * Zombie Kills - * @type {number} - */ - this.zombieKills = data.zombie_kills || 0; - /** - * Human Stats - * @type {VampireZRole} - */ - this.human = new VampireZRole(data, 'human'); - /** - * Vampire Stats - * @type {VampireZRole} - */ - this.vampire = new VampireZRole(data, 'vampire'); - /** - * Kills - * @type {number} - */ - this.kills = this.human.kills + this.vampire.kills; - /** - * Deaths - * @type {number} - */ - this.deaths = this.human.deaths + this.vampire.deaths; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = this.human.wins + this.vampire.wins; - } -} - -module.exports = VampireZ; diff --git a/src/structures/MiniGames/Walls.js b/src/structures/MiniGames/Walls.js deleted file mode 100644 index 25bcdf60c..000000000 --- a/src/structures/MiniGames/Walls.js +++ /dev/null @@ -1,52 +0,0 @@ -const divide = require('../../utils/divide'); -/** - * Walls class - */ -class Walls { - /** - * @param {object} data Walls data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - } -} -module.exports = Walls; diff --git a/src/structures/MiniGames/Warlords.js b/src/structures/MiniGames/Warlords.js deleted file mode 100644 index da85d499e..000000000 --- a/src/structures/MiniGames/Warlords.js +++ /dev/null @@ -1,187 +0,0 @@ -const divide = require('../../utils/divide'); - -class WarlordsClass { - /** - * @param {object} data Warlords data - * @param {string} className - */ - constructor(data, className) { - /** - * Wins - * @type {number} - */ - this.wins = data[`wins_${className}`] || 0; - /** - * Losses - * @type {number} - */ - this.losses = data[`losses_${className}`] || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data[`${className}_plays`]; - /** - * Damage - * @type {number} - */ - this.damage = data[`damage_${className}`] || 0; - /** - * Heal - * @type {number} - */ - this.heal = data[`heal_${className}`] || 0; - /** - * Damage Prevented - * @type {number} - */ - this.damagePrevented = data[`damage_prevented_${className}`] || 0; - } -} - -/** - * Warlords class - */ -class Warlords { - /** - * @param {object} data Warlords data - */ - constructor(data) { - /** - * Coins - * @type {number} - */ - this.coins = data.coins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data.kills || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data.deaths || 0; - /** - * Kill Death ratio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Wins - * @type {number} - */ - this.wins = data.wins || 0; - /** - * Losses - * @type {number} - */ - this.losses = data.losses || 0; - /** - * Win Loss ratio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Winstreak - * @type {number} - */ - this.winstreak = data.win_streak || 0; - /** - * Assists - * @type {number} - */ - this.assists = data.assists || 0; - /** - * Chosen class - * @type {string} - */ - this.class = data.chosen_class || ''; - /** - * pyromancer - * @type {WarlordsClass} - */ - this.pyromancer = new WarlordsClass(data, 'pyromancer'); - /** - * mage - * @type {WarlordsClass} - */ - this.mage = new WarlordsClass(data, 'mage'); - /** - * thunderlord - * @type {WarlordsClass} - */ - this.thunderlord = new WarlordsClass(data, 'thunderlord'); - /** - * shaman - * @type {WarlordsClass} - */ - this.shaman = new WarlordsClass(data, 'shaman'); - /** - * earthwarden - * @type {WarlordsClass} - */ - this.earthwarden = new WarlordsClass(data, 'earthwarden'); - /** - * aquamancer - * @type {WarlordsClass} - */ - this.aquamancer = new WarlordsClass(data, 'aquamancer'); - /** - * paladin - * @type {WarlordsClass} - */ - this.paladin = new WarlordsClass(data, 'paladin'); - /** - * avenger - * @type {WarlordsClass} - */ - this.avenger = new WarlordsClass(data, 'avenger'); - /** - * warrior - * @type {WarlordsClass} - */ - this.warrior = new WarlordsClass(data, 'warrior'); - /** - * defender - * @type {WarlordsClass} - */ - this.defender = new WarlordsClass(data, 'defender'); - /** - * cryomancer - * @type {WarlordsClass} - */ - this.cryomancer = new WarlordsClass(data, 'cryomancer'); - /** - * crusader - * @type {WarlordsClass} - */ - this.crusader = new WarlordsClass(data, 'crusader'); - /** - * berserker - * @type {WarlordsClass} - */ - this.berserker = new WarlordsClass(data, 'berserker'); - /** - * protector - * @type {WarlordsClass} - */ - this.protector = new WarlordsClass(data, 'protector'); - /** - * revenant - * @type {WarlordsClass} - */ - this.revenant = new WarlordsClass(data, 'revenant'); - /** - * spiritguard - * @type {WarlordsClass} - */ - this.spiritguard = new WarlordsClass(data, 'spiritguard'); - } -} -module.exports = Warlords; diff --git a/src/structures/MiniGames/WoolGames.js b/src/structures/MiniGames/WoolGames.js deleted file mode 100644 index 0a6b828dc..000000000 --- a/src/structures/MiniGames/WoolGames.js +++ /dev/null @@ -1,405 +0,0 @@ -const { divide } = require('../../utils'); - -class WoolWarsClass { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data, className) { - /** - * Wins - * @type {number} - */ - this.wins = data?.[className]?.wins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data?.[className]?.kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data?.[className]?.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data?.[className]?.deaths || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data?.[className]?.games_played || 0; - /** - * Wools Placed - * @type {number} - */ - this.woolsPlaced = data?.[className]?.wool_placed || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data?.[className]?.blocks_broken || 0; - /** - * Place Break Ratio - * @type {number} - */ - this.placeBreakRatio = divide(this.woolsPlaced, this.blocksBroken); - /** - * Powerups Collected - * @type {number} - */ - this.powerups = data?.[className]?.powerups_gotten || 0; - } -} - -/** - * Wool Wars Class - */ -class WoolWars { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data) { - /** - * Selected Class - * @type {'ASSAULT' | 'TANK' | 'GOLEM' | 'SWORDSMAN' | 'ENGINEER' | 'ARCHER' | 'NONE'} - */ - this.selectedClass = data?.selected_class || 'NONE'; - /** - * Wins - * @type {number} - */ - this.wins = data?.stats?.wins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data?.stats?.kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data?.stats?.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data?.stats?.deaths || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data?.stats?.games_played || 0; - /** - * Wools Placed - * @type {number} - */ - this.woolsPlaced = data?.stats?.wool_placed || 0; - /** - * Blocks Broken - * @type {number} - */ - this.blocksBroken = data?.stats?.blocks_broken || 0; - /** - * Place Break Ratio - * @type {number} - */ - this.placeBreakRatio = divide(this.woolsPlaced, this.blocksBroken); - /** - * powerups - * @type {number} - */ - this.powerups = data?.powerups_gotten || 0; - /** - * Assault Class Stats - * @type {WoolWarsClass} - */ - this.assault = new WoolWarsClass(data?.stats?.classes, 'assault'); - /** - * Tank Class Stats - * @type {WoolWarsClass} - */ - this.tank = new WoolWarsClass(data?.stats?.classes, 'tank'); - /** - * Golem Class Stats - * @type {WoolWarsClass} - */ - this.golem = new WoolWarsClass(data?.stats?.classes, 'golem'); - /** - * Swordsman Class Stats - * @type {WoolWarsClass} - */ - this.swordsman = new WoolWarsClass(data?.stats?.classes, 'swordsman'); - /** - * Engineer Class Stats - * @type {WoolWarsClass} - */ - this.engineer = new WoolWarsClass(data?.stats?.classes, 'engineer'); - /** - * Archer Class Stats - * @type {WoolWarsClass} - */ - this.archer = new WoolWarsClass(data?.stats?.classes, 'archer'); - } -} -/** - * Capture The Wool Stats Class - */ -class CaptureTheWool { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data) { - /** - * kills - * @type {number} - */ - this.kills = data?.stats?.kills || 0; - /** - * Assists - * @type {number} - */ - this.assists = data?.stats?.assists || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data?.stats?.deaths || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.kills, this.deaths); - /** - * Kills With Wool - * @type {number} - */ - this.killsWithWool = data?.stats?.kills_with_wool || 0; - /** - * Deaths With Wool - * @type {number} - */ - this.deathsWithWool = data?.stats?.deaths_with_wool || 0; - /** - * KDRatio With Wool - * @type {number} - */ - this.KDRatioWithWool = divide(this.killsWithWool, this.deathsWithWool); - /** - * Wool Captured - * @type {number} - */ - this.woolCaptured = data?.stats?.wools_captured || 0; - /** - * Wool Stolen - * @type {number} - */ - this.woolStolen = data?.stats?.wools_stolen || 0; - /** - * Wool Capture Stolen Ratio - * @type {number} - */ - this.woolCaptureStolenRatio = divide(this.woolCaptured, this.woolStolen); - } -} -/** - * Sheep Wars Stats Class - */ -class SheepWars { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data) { - /** - * Wins - * @type {number} - */ - this.wins = data?.stats?.wins || 0; - /** - * Kills - * @type {number} - */ - this.kills = data?.stats?.kills || 0; - /** - * Kills Void - * @type {number} - */ - this.killsVoid = data?.stats?.kills_void || 0; - /** - K kills Bow - * @type {number} - */ - this.killsBow = data?.stats?.kills_bow || 0; - /** - * Kills Explosive - * @type {number} - */ - this.killsExplosive = data?.stats?.kills_explosive || 0; - /** - * Deaths - * @type {number} - */ - this.deaths = data?.stats?.deaths || 0; - /** - * Deaths Void - * @type {number} - */ - this.deathsVoid = data?.stats?.deaths_void || 0; - /** - * Deaths Melee - * @type {number} - */ - this.deathsMelee = data?.stats?.deaths_melee || 0; - /** - * Deaths Explosive - * @type {number} - */ - this.deathsExplosive = data?.stats?.deaths_explosive || 0; - /** - * KDRatio - * @type {number} - */ - this.KDRatio = divide(this.wins, this.deaths); - /** - * Losses - * @type {number} - */ - this.losses = data?.stats?.losses || 0; - /** - * WLRatio - * @type {number} - */ - this.WLRatio = divide(this.wins, this.losses); - /** - * Games Played - * @type {number} - */ - this.gamesPlayed = data?.stats?.games_played || 0; - /** - * Damage Dealt - * @type {number} - */ - this.damageDealt = data?.stats?.damage_dealt || 0; - /** - * Sheep Thrown - * @type {number} - */ - this.sheepThrown = data?.stats?.sheep_thrown || 0; - /** - * Magic Wool Hit - * @type {number} - */ - this.magicWoolHit = data?.stats?.magic_wool_hit || 0; - } -} - -/** - * WoolGames Stats - */ -class WoolGames { - /** - * Constructor - * @param {Record} data Data from API - */ - constructor(data) { - /** - * Layers - * @type {number} - */ - this.layers = data?.progression?.available_layers || 0; - /** - * XP - * @type {number} - */ - this.xp = data?.progression?.experience || 0; - /** - * Exact Level - * @type {number} - */ - this.exactLevel = this.convertXPToLevel(this.xp); - /** - * Level - * @type {number} - */ - this.level = Math?.floor(this.exactLevel); - /** - * Coins - * @type {number} - */ - this.coins = data?.coins || 0; - /** - * Owned Cosmetics - * @type {string[]} - */ - this.ownedCosmetics = data?.packages || []; - /** - * Private Games Config - * @type {WoolGamesPrivateGamesConfig} - */ - this.privateGamesConfig = data?.privategames || {}; - /** - * Playtime - * @type {number} - */ - this.playtime = data?.playtime || 0; - /** - * Wool Wars - * @type {WoolWars} - */ - this.woolWars = new WoolWars(data?.wool_wars); - /** - * Capture The Wool - * @type {CaptureTheWool} - */ - this.captureTheWool = new CaptureTheWool(data?.capture_the_wool); - /** - * Sheep Wars - * @type {SheepWars} - */ - this.sheepWars = new SheepWars(data?.sheep_wars); - } - - /** - * Converts XP to Level - * @param {number} exp xp - * @return {number} - */ - convertXPToLevel(exp) { - const minimalExp = [0, 1e3, 3e3, 6e3, 1e4, 15e3]; - const baseLevel = minimalExp.length; - const baseExp = minimalExp[minimalExp.length - 1]; - const expToLevel100 = 49e4; - if (exp < baseExp) return minimalExp.findIndex((x) => exp < x); - const theoreticalLevel = (exp - baseExp) / 5e3 + baseLevel; - if (100 < theoreticalLevel) return 100 + this.convertXPToLevel(exp - expToLevel100); - return theoreticalLevel; - } -} - -/** - * @typedef {object} WoolGamesPrivateGamesConfig - * @property {boolean} one_hit_one_kill one hit one kill - * @property {'Enabled' | 'Disabled'} rainbow_wool rainbow wool - * @property {string} health_buff health buff - * @property {string} game_speed game speed - * @property {string} speed speed - * @property {'Enabled' | 'Disabled'} no_class no class - * @property {boolean} respawn_enable respawn enable - */ - -module.exports = WoolGames; diff --git a/src/structures/Pet.js b/src/structures/Pet.js deleted file mode 100644 index 28869d99e..000000000 --- a/src/structures/Pet.js +++ /dev/null @@ -1,96 +0,0 @@ -const Utils = require('../utils'); -/** - * Pet Class - */ -class Pet { - /** - * @param {string} name Name of pet - * @param {object} data data - */ - constructor(name, data) { - /** - * Is Pet Favorite - * @type {boolean} - */ - this.isFavorite = data.vanityFavorites ? Boolean(data.vanityFavorites.includes(name.toUpperCase())) : false; - name = name.replace('pet_', ''); - /** - * Official Name of the pet - * @type {string} - */ - this.name = Utils.removeSnakeCase.recursive(name) || null; - /** - * Is Active Pet - * @type {boolean} - */ - this.active = data.currentPet === name.toUpperCase(); - const stats = data.petStats && data.petStats[name.toUpperCase()]; - /** - * Stats of the pet, if any - * @type {object} - */ - if (!stats) return; - /** - * Hunger value ( 100 is highest ) - * @type {?number} - */ - this.hunger = stats.HUNGER ? stats.HUNGER.value : null; - /** - * Last time the pet was fed ( timestamp ) - * @type {?number} - */ - this.lastFed = stats.HUNGER ? stats.HUNGER.timestamp : null; - /** - * Last time the pet was fed ( Date ) - * @type {?Date} - */ - this.lastFedAt = this.lastFed ? new Date(this.lastFed) : null; - /** - * Thirst value ( 100 is highest ) - * @type {?number} - */ - this.thirst = stats.THIRST ? stats.THIRST.value : null; - /** - * Last time the pet drank ( timestamp ) - * @type {?number} - */ - this.lastDrank = stats.THIRST ? stats.THIRST.timestamp : null; - /** - * Last time the pet drank ( Date ) - * @type {?Date} - */ - this.lastDrankAt = this.lastDrank ? new Date(this.lastDrank) : null; - /** - * Exercise/Entertainment value ( 100 is highest ) - * @type {?number} - */ - this.exercise = stats.EXERCISE ? stats.EXERCISE.value : null; - /** - * Last time the pet was exercised ( timestamp ) - * @type {?number} - */ - this.lastExercised = stats.EXERCISE ? stats.EXERCISE.timestamp : null; - /** - * Last time the pet exercised ( Date ) - * @type {?Date} - */ - this.lastExercisedAt = this.lastExercised ? new Date(this.lastExerciced) : null; - /** - * Raw Nickname, if any - * @type {?string} - */ - this.rawNickname = stats.name || null; - /** - * Nickname in plain text, if any - * @type {?string} - */ - this.nickname = stats.name ? stats.name.replace(/§([0-9]|[a-f])|§/gm, '') : null; - /** - * Pet experience - * @type {number} - */ - this.experience = stats.experience || 0; - } -} - -module.exports = Pet; diff --git a/src/structures/Pets.js b/src/structures/Pets.js deleted file mode 100644 index 445c6f479..000000000 --- a/src/structures/Pets.js +++ /dev/null @@ -1,64 +0,0 @@ -const Pet = require('./Pet'); -/** - * Pets class - */ -class Pets { - /** - * @param {string[]} pets Array of pets - * @param {object} data data - */ - constructor(pets, data) { - /** - * Array of pets - * @type {Pet[]} - */ - this.pets = pets.map((x) => new Pet(x, data)); - /** - * Last Pet Journey ( as timestamp ) - * @type {number|null} - */ - this.lastJourneyTimestamp = data.petJourneyTimestamp || null; - /** - * Last Pet Journey ( as Date ) - * @type {Date|null} - */ - this.lastJourneyAt = this.lastJourneyTimestamp ? new Date(this.lastJourneyTimestamp) : null; - /** - * Pet food/drink/toys - * @type {PetConsumables} - */ - this.petConsumables = data.petConsumables; - } -} -/** - * @typedef {Object} PetConsumables - * @property {number} BAKED_POTATO Food - * @property {number} COOKIE Food - * @property {number} FEATHER Toy - * @property {number} HAY_BLOCK Food - * @property {number} SLIME_BALL Toy - * @property {number} COOKED_BEEF Food - * @property {number} RED_ROSE Food - * @property {number} WATER_BUCKET Drinks - * @property {number} MELON Food - * @property {number} STICK Toy - * @property {number} WOOD_SWORD Toy ( but not irl ) - * @property {number} MILK_BUCKET Drinks - * @property {number} GOLD_RECORD Food - * @property {number} LEASH Toy - * @property {number} LAVA_BUCKET Drinks - * @property {number} BONE Food - * @property {number} MAGMA_CREAM Food - * @property {number} WHEAT Food - * @property {number} MUSHROOM_SOUP Food - * @property {number} BREAD Food - * @property {number} PUMPKIN_PIE Food - * @property {number} APPLE Food - * @property {number} CARROT_ITEM Carrots - * @property {number} RAW_FISH Food - * @property {number} PORK Food - * @property {number} CAKE Food - * @property {number} ROTTEN_FLESH Food - */ - -module.exports = Pets; diff --git a/src/structures/Player.js b/src/structures/Player.js deleted file mode 100644 index 91733a8ec..000000000 --- a/src/structures/Player.js +++ /dev/null @@ -1,346 +0,0 @@ -const { - playerLevelProgress, - parseClaimedRewards, - getSocialMedia, - getPlayerLevel, - getRank -} = require('../utils/Player'); -const SkyWars = require('./MiniGames/SkyWars'); -const BedWars = require('./MiniGames/BedWars'); -const UHC = require('./MiniGames/UHC'); -const SpeedUHC = require('./MiniGames/SpeedUHC'); -const MurderMystery = require('./MiniGames/MurderMystery'); -const Duels = require('./MiniGames/Duels'); -const BuildBattle = require('./MiniGames/BuildBattle'); -const MegaWalls = require('./MiniGames/MegaWalls'); -const CopsAndCrims = require('./MiniGames/CopsAndCrims'); -const TNTGames = require('./MiniGames/TNTGames'); -const SmashHeroes = require('./MiniGames/SmashHeroes'); -const VampireZ = require('./MiniGames/VampireZ'); -const BlitzSurvivalGames = require('./MiniGames/BlitzSurvivalGames'); -const ArenaBrawl = require('./MiniGames/ArenaBrawl'); -const Arcade = require('./MiniGames/Arcade'); -const Color = require('./Color'); -const Game = require('./Game'); -const PlayerCosmetics = require('./PlayerCosmetics'); -const { recursive } = require('../utils/removeSnakeCase'); -const TurboKartRacers = require('./MiniGames/TurboKartRacers'); -const Paintball = require('./MiniGames/Paintball'); -const Quakecraft = require('./MiniGames/Quakecraft'); -const Walls = require('./MiniGames/Walls'); -const Warlords = require('./MiniGames/Warlords'); -const WoolGames = require('./MiniGames/WoolGames'); -const Pit = require('./MiniGames/Pit'); -const Guild = require('./Guild/Guild'); -const RecentGame = require('./RecentGame'); -/** - * Player class - */ -class Player { - /** - * @param {object} data Player data - * @param {Record} extraPayload extra data requested alongside player - */ - constructor(data, extraPayload) { - /** - * Player nickname - * @type {string} - */ - this.nickname = data.displayname; - /** - * Player UUID - * @type {string} - */ - this.uuid = data.uuid; - /** - * Player rank - * @type {PlayerRank} - */ - this.rank = getRank(data); - /** - * Current chat channel, usually ALL, PARTY, or GUILD - * @type {string|null} - */ - this.channel = data.channel || null; - /** - * Timestamp when player last logged in - * @type {number|null} - */ - this.firstLoginTimestamp = data.firstLogin || null; - /** - * Timestamp when player last logged in as Date - * @type {Date|null} - */ - this.firstLogin = data.firstLogin ? new Date(data.firstLogin) : null; - /** - * Timestamp when player last logged in as Date - * @type {Game|null} - */ - this.lastLoginTimestamp = data.lastLogin || null; - /** - * Timestamp when player first logged in unix - * @type {number|null} - */ - this.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null; - /** - * Timestamp when player last logged out as Date - * @type {Date|null} - */ - this.lastLogoutTimestamp = data.lastLogout || null; - /** - * Timestamp when player first logged in unix - * @type {number|null} - */ - this.lastLogout = data.lastLogout ? new Date(data.lastLogout) : null; - /** - * Recently played game - * @type {Game|null} - */ - this.recentlyPlayedGame = data.mostRecentGameType ? new Game(data.mostRecentGameType) : null; - /** - * Player's plus color (must be a MVP+ rank) - * @type {Color|null} - */ - this.plusColor = - 'MVP+' === this.rank || 'MVP++' === this.rank - ? data.rankPlusColor - ? new Color(data.rankPlusColor) - : new Color('RED') - : null; - /** - * MVP++ prefix color - * @type {Color|null} - */ - this.prefixColor = - 'MVP++' === this.rank ? (data.monthlyRankColor ? new Color(data.monthlyRankColor) : new Color('GOLD')) : null; - /** - * Player karma - * @type {number} - */ - this.karma = data.karma || 0; - /** - * Player achievements - * @type {Object} - */ - this.achievements = recursive(data.achievements); - /** - * Player achievement points - * @type {number} - */ - this.achievementPoints = data.achievementPoints || 0; - /** - * Player total experience - * @type {number} - */ - this.totalExperience = data.networkExp || 0; - /** - * Player level - * @type {number} - */ - this.level = getPlayerLevel(this.totalExperience) || 0; - /** - * Player social media, if any - * @type {Array} - */ - this.socialMedia = getSocialMedia(data.socialMedia) || []; - /** - * Amount of gift bundles sent - * @type {number} - */ - this.giftBundlesSent = data.giftingMeta ? data.giftingMeta.realBundlesGiven || 0 : null; - /** - * Amount of gift bundles received - * @type {number} - */ - this.giftBundlesReceived = data.giftingMeta ? data.giftingMeta.realBundlesReceived || 0 : null; - /** - * Amount of gifts sent - * @type {number} - */ - this.giftsSent = data.giftingMeta ? data.giftingMeta.giftsGiven || 0 : null; - /** - * Is player online? - * @type {boolean} - */ - this.isOnline = this.lastLoginTimestamp > this.lastLogoutTimestamp; - /** - * Last time player claimed the daily reward - * @type {Date | null} - */ - this.lastDailyReward = data.lastAdsenseGenerateTime ? new Date(data.lastAdsenseGenerateTime) : null; - /** - * Last time player claimed the daily reward, as timestamp - * @type {number | null} - */ - this.lastDailyRewardTimestamp = data.lastAdsenseGenerateTime || null; - /** - * Total amount of Daily Rewards - * @type {number | null} - */ - this.totalRewards = data.totalRewards || null; - /** - * Total amount of Daily Rewards claimed - * @type {number | null} - */ - this.totalDailyRewards = data.totalDailyRewards || null; - /** - * Honestly no clue what this is specifically - * @type {number | null} - */ - this.rewardStreak = data.rewardStreak || null; - /** - * Current Daily Rewards streak - * @type {number | null} - */ - this.rewardScore = data.rewardScore || null; - /** - * Highest Daily Rewards streak - * @type {number | null} - */ - this.rewardHighScore = data.rewardHighScore || null; - /** - * Player leveling progress. - * @type {LevelProgress} - */ - this.levelProgress = playerLevelProgress(data); - /** - * Player's Guild if requested in options - * @type {Guild|null} - */ - this.guild = extraPayload?.guild || null; - /** - * Recent Games if requested in options - * @type {RecentGame[]|null} - */ - this.recentGames = extraPayload?.recentGames || null; - /** - * Player stats for each mini-game - * @type {PlayerStats} - */ - this.stats = data.stats - ? { - arcade: data.stats.Arcade ? new Arcade({ ...data.stats.Arcade, ...data.achievements }) : null, - arena: data.stats.Arena ? new ArenaBrawl(data.stats.Arena) : null, - bedwars: data.stats.Bedwars ? new BedWars(data.stats.Bedwars) : null, - blitzsg: data.stats.HungerGames ? new BlitzSurvivalGames(data.stats.HungerGames) : null, - buildbattle: data.stats.BuildBattle ? new BuildBattle(data.stats.BuildBattle) : null, - copsandcrims: data.stats.MCGO ? new CopsAndCrims(data.stats.MCGO) : null, - duels: data.stats.Duels ? new Duels(data.stats.Duels) : null, - megawalls: data.stats.Walls3 ? new MegaWalls(data.stats.Walls3) : null, - murdermystery: data.stats.MurderMystery ? new MurderMystery(data.stats.MurderMystery) : null, - paintball: data.stats.Paintball ? new Paintball(data.stats.Paintball) : null, - pit: data.stats.Pit ? new Pit(data.stats.Pit) : null, - quakecraft: data.stats.Quake ? new Quakecraft(data.stats.Quake) : null, - skywars: data.stats.SkyWars ? new SkyWars(data.stats.SkyWars) : null, - smashheroes: data.stats.SuperSmash ? new SmashHeroes(data.stats.SuperSmash) : null, - speeduhc: data.stats.SpeedUHC ? new SpeedUHC(data.stats.SpeedUHC) : null, - tntgames: data.stats.TNTGames ? new TNTGames(data.stats.TNTGames) : null, - turbokartracers: data.stats.GingerBread ? new TurboKartRacers(data.stats.GingerBread) : null, - uhc: data.stats.UHC ? new UHC(data.stats.UHC) : null, - vampirez: data.stats.VampireZ ? new VampireZ(data.stats.VampireZ) : null, - walls: data.stats.Walls ? new Walls(data.stats.Walls) : null, - warlords: data.stats.Battleground ? new Warlords(data.stats.Battleground) : null, - woolgames: data.stats.WoolGames ? new WoolGames(data.stats.WoolGames) : null - } - : null; - /** - * User's current language - * @type {string} - * @default ENGLISH Default to english - */ - this.userLanguage = data.userLanguage || 'ENGLISH'; - /** - * Claimed Leveling Rewards - * @type {number[]} - */ - this.claimedLevelingRewards = parseClaimedRewards(data) || []; - /** - * Global Cosmetics a player owns - * @type {PlayerCosmetics} - */ - this.globalCosmetics = data ? new PlayerCosmetics(data) : null; - /** - * Time at which the ranks were purchased. Can be all null if bought a long time ago, and some values can be null if player bought directly a rank above that - * @type {RanksPurchaseTime} - */ - this.ranksPurchaseTime = { - VIP: data.levelUp_VIP ? new Date(data.levelUp_VIP) : null, - VIP_PLUS: data.levelUp_VIP_PLUS ? new Date(data.levelUp_VIP_PLUS) : null, - MVP: data.levelUp_MVP ? new Date(data.levelUp_MVP) : null, - MVP_PLUS: data.levelUp_MVP_PLUS ? new Date(data.levelUp_MVP_PLUS) : null - }; - } - /** - * Player Name ( at least last known to hypixel ) - * @return {string} - */ - toString() { - return this.nickname; - } -} -/** - * @typedef {string} PlayerRank - * * `Default` - * * `VIP` - * * `VIP+` - * * `MVP` - * * `MVP+` - * * `MVP++` - * * `YouTube` - * * `Game Master` - * * `Admin` - * * `PIG+++` - * * `INNIT` - */ -/** - * @typedef {Object} PlayerSocialMedia - * Player social media object - * @property {string} name Twitter, YouTube, Instagram, Twitch, Hypixel, Discord - * @property {string} link Link to social media - * @property {string} id TWITTER, YOUTUBE, INSTRAGRAM, TWITCH, HYPIXEL, DISCORD - */ -/** - * @typedef {Object|null} PlayerStats - * Player stats for each mini-game. `null` if player has no stats. - *
- * Usage: `.stats.skywars` - * @property {Arcade|null} arcade Arcade - * @property {ArenaBrawl|null} arena Arena Brawl - * @property {BedWars|null} bedwars BedWars - * @property {BlitzSurvivalGames|null} blitzsg Blitz Survival Games - * @property {BuildBattle|null} buildbattle BuildBattle - * @property {CopsAndCrims|null} copsandcrims Cops and Crims - * @property {Duels|null} duels Duels - * @property {MegaWalls|null} megawalls MegaWalls - * @property {MurderMystery|null} murdermystery Murder Mystery - * @property {Paintball|null} paintball Paint Ball - * @property {Pit|null} pit Pit - * @property {Quakecraft|null} quakecraft Quake Craft - * @property {SkyWars|null} skywars SkyWars - * @property {SmashHeroes|null} smashheroes Smash Heroes - * @property {SpeedUHC|null} speedUHC Speed UHC - * @property {TNTGames|null} tntgames The TNT Games - * @property {TurboKartRacers|null} turbokartracers Turbo Kart Racers - * @property {UHC|null} uhc UHC - * @property {VampireZ|null} vampirez VampireZ - * @property {Walls|null} walls Walls - * @property {Warlords|null} warlords Warlords - * @property {WoolGames|null} woolgames Wool Games - */ -/** - * @typedef {Object} RanksPurchaseTime - * Time at which ranks were purchased. Beware, even if a player has MVP+(+), every value here *could* be null - * @property {Date|null} VIP VIP rank - * @property {Date|null} VIP_PLUS VIP+ rank - * @property {Date|null} MVP MVP rank - * @property {Date|null} MVP_PLUS MVP+ rank - */ -/** - * @typedef {Object} LevelProgress - * @property {number} xpToNext Total XP to a player's next level. - * @property {number} remainingXP XP to the player's next level. - * @property {number} currentXP XP the player current has. - * @property {number} percent Player level progress as a percentage. - * @property {number} percentRemaining Remaining percentage of the percent value. - */ -module.exports = Player; diff --git a/src/structures/PlayerCosmetics.js b/src/structures/PlayerCosmetics.js deleted file mode 100644 index a8fdabe93..000000000 --- a/src/structures/PlayerCosmetics.js +++ /dev/null @@ -1,155 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -const { removeSnakeCaseString } = require('../utils/removeSnakeCase'); -const Pets = require('./Pets'); -/** - * Player Cosmetics class - */ -class PlayerCosmetics { - /** - * @param {object} data data - */ - constructor(data) { - /** - * All cosmetics - * @type {string[]} - */ - this.allCosmetics = data?.vanityMeta?.packages || undefined; - /** - * Pets - * @type {Pets|null} - */ - this.petManager = this.allCosmetics - ? new Pets( - this.allCosmetics.filter((x) => x.startsWith('pet_')), - data - ) - : null; - } - /** - * Suits - * @type {string[]} - */ - get suits() { - if (!this._suits) { - this._suits = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('suit_')) - .map((x) => removeSnakeCaseString(x.replace('suit_', ''))) || [] - : []; - } - return this._suits; - } - /** - * Hats - * @type {string[]} - */ - get hats() { - if (!this._hats) { - this._hats = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('hat_')) - .map((x) => removeSnakeCaseString(x.replace('hat_', ''))) || [] - : []; - } - return this._hats; - } - /** - * Gadgets - * @type {string[]} - */ - get gadgets() { - if (!this._gadgets) { - this._gadgets = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('gadget_')) - .map((x) => removeSnakeCaseString(x.replace('gadget_', ''))) || [] - : []; - } - return this._gadgets; - } - /** - * Morphs - * @type {string[]} - */ - get morphs() { - if (!this._morphs) { - this._morphs = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('morph_')) - .map((x) => removeSnakeCaseString(x.replace('morph_', ''))) || [] - : []; - } - return this._morphs; - } - /** - * Cloaks - * @type {string[]} - */ - get cloaks() { - if (!this._cloaks) { - this._cloaks = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('cloak_')) - .map((x) => removeSnakeCaseString(x.replace('cloak_', ''))) || [] - : []; - } - return this._cloaks; - } - /** - * Taunts - * @type {string[]} - */ - get taunts() { - if (!this._taunts) { - this._taunts = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('taunt_')) - .map((x) => removeSnakeCaseString(x.replace('taunt_', ''))) || [] - : []; - } - return this._taunts; - } - /** - * rankColors - * @type {string[]} - */ - get rankColors() { - if (!this._rankColors) { - this._rankColors = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('rankcolor_')) - .map((x) => removeSnakeCaseString(x.replace('rankcolor_', ''))) || [] - : []; - } - return this._rankColors; - } - /** - * Particle Packs - * @type {string[]} - */ - get particlePacks() { - if (!this._particle) { - this._particle = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('particlepack_')) - .map((x) => removeSnakeCaseString(x.replace('particlepack_', ''))) || [] - : []; - } - return this._particlepacks; - } - /** - * Click Effects - * @type {string[]} - */ - get clickEffects() { - if (!this._clickfx) { - this._clickfx = this.allCosmetics - ? this.allCosmetics - .filter((x) => x.startsWith('clickeffects_')) - .map((x) => removeSnakeCaseString(x.replace('clickeffects_', ''))) || [] - : []; - } - return this._clickfx; - } -} -module.exports = PlayerCosmetics; diff --git a/src/structures/RecentGame.js b/src/structures/RecentGame.js deleted file mode 100644 index 21f5fd9a4..000000000 --- a/src/structures/RecentGame.js +++ /dev/null @@ -1,57 +0,0 @@ -const Game = require('./Game'); -/** - * RecentGame class - * @extends {Game} - */ -class RecentGame extends Game { - /** - * @param {object} data Recent game data - */ - constructor(data) { - super(data.gameType); - /** - * Date as timestamp - * @type {number} - */ - this.dateTimestamp = data.date || null; - /** - * Date - * @type {Date} - */ - this.date = data.date ? new Date(data.date) : null; - /** - * Game mode - * @type {string} - */ - this.mode = data.mode || null; - /** - * Map - * @type {string} - */ - this.map = data.map || null; - // Per hypixel API docs : if ended isn't present, the game is ONGOING. - /** - * Is game ongoing? - * @type {boolean} - */ - this.ongoing = Boolean(!data.ended); - /** - * Game ended at as Date - * @type {Date} - */ - this.endedAt = data.ended ? new Date(data.ended) : null; - /** - * Game ended at - * @type {number} - */ - this.endedTimestamp = data.ended ? data.ended : null; - } - /** - * Name of gamemode - * @return {string} - */ - toString() { - return this.mode; - } -} -module.exports = RecentGame; diff --git a/src/structures/ServerInfo.js b/src/structures/ServerInfo.js deleted file mode 100644 index 0ded1a8fb..000000000 --- a/src/structures/ServerInfo.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * Server Info class - parses info obtained from handshaking with hypixel - */ -class ServerInfo { - /** - * Constructor - * @param {Object} data data parsed from packet - * @param {number} ping Ping - */ - constructor(data, ping) { - /** - * Protocol used for retrieving info, should be 736 - * @type {number} - */ - this.protocolUsed = data.version.protocol || 736; - /** - * Version required / Server version used - * @type {string} - */ - this.versionInfo = data.version.name || 'Unknown'; - /** - * Amount of players online and max players - * @type {PlayerInfo} - */ - this.players = { - max: data.players.max || 0, - online: data.players.online || 0, - players: data.players.sample || [], - toString: () => `${this.players.online}/${this.players.max}` - }; - /** - * Server MOTD, as it is received - * @type {string} - */ - this.rawMOTD = data.description || ''; - /** - * Clean MOTD, no color codes - * @type {string} - */ - this.cleanMOTD = this.rawMOTD.replace(/§[a-z0-9]/gi, ''); - /** - * MOTD without surrounding white spaces for centering - * @type {string} - */ - this.textMOTD = this.cleanMOTD.replace(/^\s+/gm, ''); - /** - * base64 Favicon - as it is received - * @type {string} - */ - this.faviconB64 = data.favicon || undefined; - /** - * Favicon as buffer - * @type {Buffer} - */ - this.favicon = Buffer.from(this.faviconB64, 'base64'); - /** - * Ping in ms - * @type {number} - */ - this.ping = parseInt(ping, 10); - } - /** - * toString override - * @returns {string} - */ - toString() { - return `${this.textMOTD} - ${this.players} Players (${this.ping} ms) - ${this.versionInfo}`; - } -} - -/** - * @typedef {Object} PlayerInfo - * @property {number} max Max amount of players online possible for the server - * @property {number} online Current amount of online players - * @property {any[]} players Some or all IGNs of online players, usually not provided by Hypixel - */ - -module.exports = ServerInfo; diff --git a/src/structures/SkyBlock/Auctions/Auction.js b/src/structures/SkyBlock/Auctions/Auction.js deleted file mode 100644 index 06f6c3f61..000000000 --- a/src/structures/SkyBlock/Auctions/Auction.js +++ /dev/null @@ -1,106 +0,0 @@ -const BaseAuction = require('./BaseAuction'); -const Bid = require('./Bid'); -/** - * Auction class - */ -class Auction extends BaseAuction { - /** - * @param {object} data - * @param {boolean} includeItemBytes - */ - constructor(data, includeItemBytes) { - super(data, includeItemBytes); - /** - * Coop members. Array of UUIDs - * @type {string[]} - */ - this.coop = data.coop || []; - /** - * Auction start timestamp - * @type {number|null} - */ - this.auctionStartTimestamp = data.start || null; - /** - * Auction start timestamp as Date - * @type {Date} - */ - this.auctionStart = data.start ? new Date(data.start) : null; - /** - * Auction end timestamp as Date - * @type {Date} - */ - this.auctionEnd = data.end ? new Date(data.end) : null; - /** - * Auction end timestamp as timestamp - * @type {number} - */ - this.auctionEndTimestamp = data.end || null; - /** - * Auction Item Name - * @type {string} - */ - this.item = data.item_name || null; - /** - * Auction Item lore ( plain text ) - * @type {string} - */ - this.itemLore = data.item_lore ? data.item_lore.replace(/§([1-9]|[a-l])|§/gm, '') : null; - /** - * Auctipn Item Lore as it is from the API - * @type {string} - */ - this.itemLoreRaw = data.item_lore || null; - /** - * Rarity of Item - * @type {Rarity} - */ - this.rarity = data.tier || null; - /** - * Auction starting bid, or price for BIN - * @type {number} - */ - this.startingBid = data.starting_bid || 0; - /** - * Auction's highest bid, if it is bidded or price for BIN - * @type {number} - */ - this.highestBid = this.bin ? data.starting_bid : data.highest_bid_amount || 0; - /** - * Auction bids - * @type {Bid[]} - */ - this.bids = data.bids.length ? data.bids.map((b) => new Bid(b)) : []; - /** - * is Auction Claimed - * @type {boolean} - */ - this.claimed = data.claimed || false; - /** - * Which bidders, if any, claimed - * @type {string[]} - */ - this.claimedBidders = this.claimed ? data.claimed_bidders : []; - } - /** - * Item Name - * @return {string} - */ - toString() { - return this.item; - } -} - -/** - * @typedef {string} Rarity - * * `VERY_SPECIAL` - * * `SPECIAL` - * * `SUPREME` - * * `MYTHIC` - * * `LEGENDARY` - * * `EPIC` - * * `RARE` - * * `UNCOMMON` - * * `COMMON` - */ - -module.exports = Auction; diff --git a/src/structures/SkyBlock/Auctions/AuctionInfo.js b/src/structures/SkyBlock/Auctions/AuctionInfo.js deleted file mode 100644 index ca5be4b0b..000000000 --- a/src/structures/SkyBlock/Auctions/AuctionInfo.js +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Auction info class - */ -class AuctionInfo { - /** - * @param {object} data Auction info data - */ - constructor(data) { - /** - * Page number - * @type {number} - */ - this.page = parseInt(data.page, 10) || 0; - /** - * Total pages - * @type {number} - */ - this.totalPages = parseInt(data.totalPages, 10) || 1; - /** - * Total auctions - * @type {number} - */ - this.totalAuctions = parseInt(data.totalAuctions, 10) || 0; - /** - * Last updated timestamp - * @type {number} - */ - this.lastUpdatedTimestamp = data.lastUpdated; - /** - * Last updated timestamp as Date - * @type {Date} - */ - this.lastUpdatedAt = new Date(data.lastUpdated); - /** - * Age - * @type {number} - */ - - // eslint-disable-next-line no-underscore-dangle - this.age = parseInt(data._headers.get('age'), 10) || 0; - } - - _extend(name, value) { - this[name] = value; - return this; - } - /** - * Current Page / Total Page - * @return {string} - */ - toString() { - return `${this.page} / ${this.totalPages}`; - } -} - -module.exports = AuctionInfo; diff --git a/src/structures/SkyBlock/Auctions/BaseAuction.js b/src/structures/SkyBlock/Auctions/BaseAuction.js deleted file mode 100644 index 13923f97f..000000000 --- a/src/structures/SkyBlock/Auctions/BaseAuction.js +++ /dev/null @@ -1,49 +0,0 @@ -const ItemBytes = require('../../ItemBytes'); -/** - * Base auction class - */ -class BaseAuction { - /** - * @param {object} data Base auction data - * @param {boolean} includeItemBytes - */ - constructor(data, includeItemBytes) { - /** - * Auction ID - * @type {string|null} - */ - this.auctionId = data.uuid || data.auction_id || null; - /** - * Auctioneer UUID - * @type {string|null} - */ - this.auctioneerUuid = data.auctioneer || data.seller || null; - /** - * Auctioneer's skyblock profile ID - * @type {string|null} - */ - this.auctioneerProfile = data.profile_id || data.seller_profile || null; - /** - * Bin - * @type {boolean} - */ - this.bin = data.bin || false; - /** - * Item bytes - * @type {ItemBytes|null} - */ - this.itemBytes = - includeItemBytes && data.item_bytes - ? new ItemBytes(data.item_bytes.data ? data.item_bytes.data : data.item_bytes) - : null; - } - /** - * Auction ID - * @return {string} - */ - toString() { - return this.auctionId; - } -} - -module.exports = BaseAuction; diff --git a/src/structures/SkyBlock/Auctions/Bid.js b/src/structures/SkyBlock/Auctions/Bid.js deleted file mode 100644 index dc884522e..000000000 --- a/src/structures/SkyBlock/Auctions/Bid.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Bid class - */ -class Bid { - /** - * @param {object} data Bid data - */ - constructor(data) { - /** - * Auction ID - * @type {string|null} - */ - this.auctionId = data.auction_id || null; - /** - * Skyblock profile ID - * @type {string|null} - */ - this.profileId = data.profile_id || null; - /** - * Amount - * @type {number} - */ - this.amount = data.amount || 0; - /** - * Auction timestamp - * @type {number} - */ - this.timestamp = data.timestamp || null; - /** - * Auction timestamp as Date - * @type {Date} - */ - this.at = data.timestamp ? new Date(data.timestamp) : null; - /** - * Bidder - * @type {string} - */ - this.bidder = data.bidder || null; - } - /** - * Bidder Name - Bid Amount - * @return {string} - */ - toString() { - return `${this.bidder} bid ${this.amount} coins`; - } -} - -module.exports = Bid; diff --git a/src/structures/SkyBlock/Auctions/PartialAuction.js b/src/structures/SkyBlock/Auctions/PartialAuction.js deleted file mode 100644 index a62657103..000000000 --- a/src/structures/SkyBlock/Auctions/PartialAuction.js +++ /dev/null @@ -1,26 +0,0 @@ -const BaseAuction = require('./BaseAuction'); -/** - * Partial auction class - * @extends {BaseAuction} - */ -class PartialAuction extends BaseAuction { - /** - * @param {object} data Partial auction data - * @param {boolean} includeItemBytes - */ - constructor(data, includeItemBytes) { - super(data, includeItemBytes); - /** - * Buyer UUID - * @type {string} - */ - this.buyer = data.buyer || null; - /** - * Price - * @type {number} - */ - this.price = parseInt(data.price, 10) || 0; - } -} - -module.exports = PartialAuction; diff --git a/src/structures/SkyBlock/Bazzar/Order.js b/src/structures/SkyBlock/Bazzar/Order.js deleted file mode 100644 index bd17eff28..000000000 --- a/src/structures/SkyBlock/Bazzar/Order.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Order class - */ -class Order { - /** - * @param {object} data Order data - */ - constructor(data) { - /** - * Amount - * @type {number} - */ - this.amount = data.amount || 0; - /** - * Price per unit - * @type {number} - */ - this.pricePerUnit = data.pricePerUnit || 0; - /** - * Total price - * @type {number} - */ - this.totalPrice = Math.round(this.amount * this.pricePerUnit * 10) / 10; - /** - * Orders - * @type {number} - */ - this.orders = data.orders || 0; - } - /** - * Price as string - * @return {string} - */ - toString() { - return this.totalPrice; - } -} -module.exports = Order; diff --git a/src/structures/SkyBlock/Bazzar/Product.js b/src/structures/SkyBlock/Bazzar/Product.js deleted file mode 100644 index 245aba18f..000000000 --- a/src/structures/SkyBlock/Bazzar/Product.js +++ /dev/null @@ -1,53 +0,0 @@ -const Order = require('./Order'); - -/** - * Product class - */ -class Product { - /** - * @param {object} data Product data - */ - constructor(data) { - /** - * Product ID - * @type {string} - */ - this.productId = data.product_id; - /** - * Product sell orders - * @type {Order[]} - */ - this.sellSummary = data.sell_summary.length ? data.sell_summary.map((sellOrder) => new Order(sellOrder)) : []; - /** - * Product buy orders - * @type {Order[]} - */ - this.buySummary = data.buy_summary.length ? data.buy_summary.map((buyOrder) => new Order(buyOrder)) : []; - /** - * Product status - * @type {ProductStatus} - */ - this.status = { - sellPrice: isNaN(data.quick_status.sellPrice) ? 0 : Math.round(data.quick_status.sellPrice * 100) / 100, - buyPrice: isNaN(data.quick_status.buyPrice) ? 0 : Math.round(data.quick_status.buyPrice * 100) / 100, - sellVolume: isNaN(data.quick_status.sellVolume) ? 0 : data.quick_status.sellVolume, - buyVolume: isNaN(data.quick_status.buyVolume) ? 0 : data.quick_status.buyVolume, - sellMovingWeek: isNaN(data.quick_status.sellMovingWeek) ? 0 : data.quick_status.sellMovingWeek, - buyMovingWeek: isNaN(data.quick_status.buyMovingWeek) ? 0 : data.quick_status.buyMovingWeek, - sellOrders: isNaN(data.quick_status.sellOrders) ? 0 : data.quick_status.sellOrders, - buyOrders: isNaN(data.quick_status.buyOrders) ? 0 : data.quick_status.buyOrders - }; - } -} -/** - * @typedef {object} ProductStatus - * @property {number} sellPrice Sell price - * @property {number} buyPrice Buy price - * @property {number} sellVolume Sell volume - * @property {number} buyVolume Buy volume - * @property {number} sellMovingWeek Sell moving week - * @property {number} buyMovingWeek Sell moving week - * @property {number} sellOrders Sell orders - * @property {number} buyOrders Buy orders - */ -module.exports = Product; diff --git a/src/structures/SkyBlock/News/SkyblockNews.js b/src/structures/SkyBlock/News/SkyblockNews.js deleted file mode 100644 index a8a2ed64a..000000000 --- a/src/structures/SkyBlock/News/SkyblockNews.js +++ /dev/null @@ -1,60 +0,0 @@ -const dateRegExp = /(\d{1,2})(?:st|nd|rd|th|) ([A-Za-z]+) (\d+)/; -const versionRegExp = /v\d+(\.\d+){1,}/; - -// eslint-disable-next-line jsdoc/require-jsdoc -function parseDate(stringDate) { - const matched = stringDate.match(dateRegExp); - if (!matched) return null; - return new Date(matched.slice(1).join(' ')); -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function parseVer(stringVer) { - const matches = versionRegExp.exec(stringVer); - if (!matches?.length) return null; - return matches[0]; -} -/** - * SkyblockNews - */ -class SkyblockNews { - /** - * @param {object} data - */ - constructor(data) { - /** - * Title - * @type {string} - */ - this.title = data.title; - /** - * Thread - * @type {string} - */ - this.link = data.link; - /** - * Raw Date from the API Response - * @type {string} - */ - this.rawDate = data.text; - /** - * Parsed Date - * @type {Date} - */ - this.date = parseDate(data.text); - /** - * The version from the title (Skyblock v0.12.57673856757.327.2 => v0.12.57673856757.327.2) - * @author linearaccelerator - * @type {string | null} - */ - this.version = parseVer(this.title); - } - /** - * News title - * @return {string} - */ - toString() { - return this.title; - } -} -module.exports = SkyblockNews; diff --git a/src/structures/SkyBlock/PlayerBingo.js b/src/structures/SkyBlock/PlayerBingo.js deleted file mode 100644 index 5454c12aa..000000000 --- a/src/structures/SkyBlock/PlayerBingo.js +++ /dev/null @@ -1,49 +0,0 @@ -const { populateGoals } = require('../../utils/SkyblockUtils'); -// eslint-disable-next-line no-unused-vars -const BingoDataType = require('./Static/BingoData.js'); -// eslint-disable-next-line no-unused-vars -const BingoType = require('./Static/Bingo.js'); -/** - * @typedef {BingoDataType} BingoData - * @typedef {BingoType} Bingo - */ - -/** - * Player Bingo Class - */ -class PlayerBingo { - /** - * Constructor - * @param {Object} data data - * @param {BingoData|null} bingoData bingo data - */ - constructor(data, bingoData) { - const events = data.success && Array.isArray(data.events) ? data.events : []; - /** - * Data per event - * @type {PlayerBingoDataPerEvent} - */ - this.dataPerEvent = events.map((eventData) => { - let doneGoals = eventData.completed_goals; - if (!Array.isArray(doneGoals)) doneGoals = []; - const enrichable = parseInt(eventData.key, 10) === bingoData?.id; - if (enrichable) doneGoals = populateGoals(doneGoals, bingoData.goals); - return { - eventId: parseInt(eventData.key, 10) || null, - points: parseInt(eventData.points, 10) || 0, - goalsCompleted: doneGoals, - enrichedGoals: enrichable - }; - }); - } -} - -/** - * @typedef {Object} PlayerBingoDataPerEvent - * @property {number} eventId ID of event - * @property {number} points Points acquired - * @property {boolean} enrichedGoals Whether the goals are enriched (populated with data from static skyblock bingp data) - * @property {Bingo[]|string[]} goalsCompleted Special Bingo Array if enrichedGoals is true. You can however always treat SpecialBingoArray as string[] - */ - -module.exports = PlayerBingo; diff --git a/src/structures/SkyBlock/SkyblockGarden.js b/src/structures/SkyBlock/SkyblockGarden.js deleted file mode 100644 index f4f824a22..000000000 --- a/src/structures/SkyBlock/SkyblockGarden.js +++ /dev/null @@ -1,146 +0,0 @@ -const { getLevelByXp } = require('../../utils/SkyblockUtils'); - -/** - * Skyblock Garden class - */ -class SkyblockGarden { - /** - * @param {object} data Skyblock member data - */ - constructor(data) { - /** - * level - * @type {SkyblockSkillLevel} - */ - this.level = getLevelByXp(data?.garden?.garden_experience || 0, 'garden'); - /** - * Current Barn Skin - * @type {string} - */ - this.barnSkin = data?.garden?.selected_barn_skin || ''; - /** - * Unlocked Plots - * @type {string[]} - */ - this.unlockedPlots = data?.garden?.unlocked_plots_ids || []; - /** - * Visitor Stats - * @type {SkyblockGardenVisitor} - */ - this.visitors = { - visited: data?.garden?.commission_data?.visits || {}, - completed: data?.garden?.commission_data?.completed || {}, - served: { - total: data?.garden?.commission_data?.total_completed || 0, - unique: data?.garden?.commission_data?.unique_npcs_served || 0 - } - }; - /** - * Crop Milestones - * @type {SkyblockGarenCropMilestones} - */ - this.cropMilestones = { - wheat: getLevelByXp(data?.garden?.resources_collected?.WHEAT || 0, 'wheat'), - carrot: getLevelByXp(data?.garden?.resources_collected?.CARROT_ITEM || 0, 'carrot'), - sugarCane: getLevelByXp(data?.garden?.resources_collected?.SUGAR_CANE || 0, 'sugarCane'), - potato: getLevelByXp(data?.garden?.resources_collected?.POTATO_ITEM || 0, 'potato'), - pumpkin: getLevelByXp(data?.garden?.resources_collected?.PUMPKIN || 0, 'pumpkin'), - melon: getLevelByXp(data?.garden?.resources_collected?.MELON || 0, 'melon'), - cactus: getLevelByXp(data?.garden?.resources_collected?.CACTUS || 0, 'cactus'), - cocoaBeans: getLevelByXp(data?.garden?.resources_collected?.['INK_SACK:3'] || 0, 'cocoaBeans'), - mushroom: getLevelByXp(data?.garden?.resources_collected?.MUSHROOM_COLLECTION || 0, 'mushroom'), - netherWart: getLevelByXp(data?.garden?.resources_collected?.NETHER_STALK || 0, 'netherWart') - }; - /** - * Composter - * @type {SkyblockGardenComposter} - */ - this.composter = { - organicMatter: data?.garden?.composter_data?.organic_matter || 0, - fuelUnits: data?.garden?.composter_data?.fuel_units || 0, - compostUnits: data?.garden?.composter_data?.compost_units || 0, - compostItems: data?.garden?.composter_data?.compost_items || 0, - conversionTicks: data?.garden?.composter_data?.conversion_ticks || 0, - upgrades: { - speed: data?.garden?.composter_data?.upgrades?.speed || 0, - multiDrop: data?.garden?.composter_data?.upgrades?.multi_drop || 0, - fuelCap: data?.garden?.composter_data?.upgrades?.fuel_cap || 0, - organicMatterCap: data?.garden?.composter_data?.upgrades?.organic_matter_cap || 0, - costReduction: data?.garden?.composter_data?.upgrades?.cost_reduction || 0 - } - }; - /** - * Crop Upgrades - * @type {SkyblockGarenCrops} - */ - this.cropUpgrades = { - wheat: data?.garden?.crop_upgrade_levels?.WHEAT || 0, - carrot: data?.garden?.crop_upgrade_levels?.CARROT_ITEM || 0, - sugarCane: data?.garden?.crop_upgrade_levels?.SUGAR_CANE || 0, - potato: data?.garden?.crop_upgrade_levels?.POTATO_ITEM || 0, - pumpkin: data?.garden?.crop_upgrade_levels?.PUMPKIN || 0, - melon: data?.garden?.crop_upgrade_levels?.MELON || 0, - cactus: data?.garden?.crop_upgrade_levels?.CACTUS || 0, - cocoaBeans: data?.garden?.crop_upgrade_levels?.['INK_SACK:3'] || 0, - mushroom: data?.garden?.crop_upgrade_levels?.MUSHROOM_COLLECTION || 0, - netherWart: data?.garden?.crop_upgrade_levels?.NETHER_STALK || 0 - }; - } -} - -/** - * @typedef {object} SkyblockGardenVisitor - * @property {Record} visited Visited - * @property {Record} completed Completed - * @property {SkyblockGardenVisitorServed} served served - */ -/** - * @typedef {object} SkyblockGardenVisitorServed - * @property {number} total total - * @property {number} unique unique - */ -/** - * @typedef {object} SkyblockGardenComposter - * @property {number} organicMatter Organic Matter - * @property {number} fuelUnits Fuel Units - * @property {number} compostUnits Compost Units - * @property {number} compostItems Compost Items - * @property {number} conversionTicks Conversion Ticks - * @property {SkyblockGardenComposterUpgrades} upgrades upgrades - */ -/** - * @typedef {object} SkyblockGardenComposterUpgrades - * @property {number} speed Speed - * @property {number} multiDrop Multi Drop - * @property {number} fuelCap Fuel Cap - * @property {number} organicMatterCap Organic Matter Cap - * @property {number} costReduction Cost Reduction - */ -/** - * @typedef {object} SkyblockGarenCrops - * @property {number} wheat Wheat - * @property {number} carrot Carrot - * @property {number} sugarCane Sugar Cane - * @property {number} potato Potato - * @property {number} pumpkin Pumpkin - * @property {number} melon Melon - * @property {number} cactus Cactus - * @property {number} cocoaBeans Cocoa Beans - * @property {number} mushroom Mushroom - * @property {number} netherWart Nether Wart - */ -/** - * @typedef {object} SkyblockGarenCropMilestones - * @property {SkyblockSkillLevel} wheat Wheat - * @property {SkyblockSkillLevel} carrot Carrot - * @property {SkyblockSkillLevel} sugarCane Sugar Cane - * @property {SkyblockSkillLevel} potato Potato - * @property {SkyblockSkillLevel} pumpkin Pumpkin - * @property {SkyblockSkillLevel} melon Melon - * @property {SkyblockSkillLevel} cactus Cactus - * @property {SkyblockSkillLevel} cocoaBeans Cocoa Beans - * @property {SkyblockSkillLevel} mushroom Mushroom - * @property {SkyblockSkillLevel} netherWart Nether Wart - */ - -module.exports = SkyblockGarden; diff --git a/src/structures/SkyBlock/SkyblockInventoryItem.js b/src/structures/SkyBlock/SkyblockInventoryItem.js deleted file mode 100644 index 62ba1ae59..000000000 --- a/src/structures/SkyBlock/SkyblockInventoryItem.js +++ /dev/null @@ -1,168 +0,0 @@ -const { parseRarity, parseGearScore } = require('../../utils/SkyblockUtils'); -/** - * Item class - */ -class SkyblockInventoryItem { - /** - * @param {object} data Item data - */ - constructor(data) { - /** - * Item ID - * @type {number} - */ - this.itemId = data.id || 0; - /** - * Item count - * @type {number} - */ - this.count = data.Count || 0; - /** - * Item name - * @type {string} - */ - this.name = - null !== data.tag.display.Name ? data.tag.display.Name.toString().replace(/§([1-9]|[a-f])|§/gm, '') : null; - /** - * Item lore - * @type {string} - */ - this.lore = data.tag.display.Lore.join('\n'); - /** - * Item lore - * @type {string[]} - */ - this.loreArray = data.tag.display.Lore; - /** - * Item lore for embed - * @type {string} - */ - this.loreForEmbed = this.lore.replace(/§([0-9]|[a-f])|§/gm, '').replace(/
/gm, '\n'); - /** - * Hexadecimal color code of armor - * @type {string|null} - */ - this.color = data.tag.ExtraAttributes.color ?? data.tag.display.color ?? null; - /** - * Item enchantments - * @type {Record} - */ - this.enchantments = data.tag.ExtraAttributes.enchantments ?? null; - /** - * Armor reforge - * @type {string} - */ - this.reforge = data.tag.ExtraAttributes.modifier ?? null; - /** - * Equipment gemstones (if any) - * @type {SkyblockItemGemstone} - */ - this.gemstones = data.tag.ExtraAttributes.gems - ? Object.entries(data.tag.ExtraAttributes.gems).map((gem) => { - return new Object({ type: gem[0].split('_')[0], quality: gem[1] }); - }) - : null; - /** - * Damage - * @type {number} - */ - this.damage = data.Damage || 0; - /** - * What rarity the item has, as an uppercase string - * @author linearaccelerator - * @type {string} - */ - this.rarity = parseRarity(this.loreArray[this.loreArray.length - 1]); - /** - * The amount of dungeon stars the item has (each star equates to a 10% stat boost while in dungeons) - * @type {number} - */ - this.dungeonStars = data.tag.ExtraAttributes.upgrade_level ?? 0; - /** - * Dungeon gear score of the item (or null if not present) - * @author linearaccelerator - * @type {number} - */ - this.gearScore = parseGearScore(this.loreArray) || null; - /** - * UUID of the item - * @type {string} - */ - this.uuid = data.tag.ExtraAttributes.uuid ?? ''; - /** - * Is the item soulbound - * @type {boolean} - */ - this.soulbound = 1 === data.tag.ExtraAttributes.donated_museum; - /** - * Amount of art of war books applied to the item - * @type {number} - */ - this.artOfWar = data.tag.ExtraAttributes.art_of_war_count ?? 0; - /** - * Rune - * @type {object} - */ - this.rune = data.tag.ExtraAttributes.runes ?? null; - /** - * The amount of applied potato books - * @type {number} - */ - this.hotPotatoBooks = data.tag.ExtraAttributes.hot_potato_count ?? 0; - /** - * Is the item recombobulated - * @type {boolean} - */ - this.recombobulated = 1 === data.tag.ExtraAttributes.rarity_upgrades; - /** - * Item attributes - * @type {object} - */ - this.attributes = data.tag.ExtraAttributes.attributes ?? {}; - /** - * Hecatomb runs - * @type {number} - */ - this.hecatomb = data.tag.ExtraAttributes.hecatomb_s_runs ?? 0; - /** - * Champion xp - * @type {number} - */ - this.champion = data.tag.ExtraAttributes.champion_combat_xp ?? 0; - /** - * Cultivating - * @type {number} - */ - this.cultivating = data.tag.ExtraAttributes.farmed_cultivating ?? 0; - /** - * Expertise Kills - * @type {number} - */ - this.expertise = data.tag.ExtraAttributes.expertise_kills ?? 0; - /** - * Compact blocks Mined - * @type {number} - */ - this.compact = data.tag.ExtraAttributes.compact_blocks ?? 0; - /** - * Armadillos Blocks Walked - * @type {number} - */ - this.blocksWalked = data.tag.ExtraAttributes.blocks_walked ?? 0; - } - /** - * Item Name - * @return {string} - */ - toString() { - return this.name; - } -} - -/** - * @typedef {object} SkyblockItemGemstone - * @property {string} type Gemstone type - * @property {string} quality Gemstone quality (rough, flawed, fine, flawless, perfect) - */ - -module.exports = SkyblockInventoryItem; diff --git a/src/structures/SkyBlock/SkyblockMember.js b/src/structures/SkyBlock/SkyblockMember.js deleted file mode 100644 index 0305a80d2..000000000 --- a/src/structures/SkyBlock/SkyblockMember.js +++ /dev/null @@ -1,594 +0,0 @@ -const { - getMemberStats, - decode, - getSkills, - getBestiaryLevel, - getSlayer, - getCrimson, - getDungeons, - getJacobData, - getChocolateFactory, - getPetLevel, - getHOTM -} = require('../../utils/SkyblockUtils'); -const SkyblockInventoryItem = require('./SkyblockInventoryItem'); -const SkyblockMuseum = require('./SkyblockMuseum'); -const SkyblockGarden = require('./SkyblockGarden'); -const Constants = require('../../utils/Constants'); -const skyhelper = require('skyhelper-networth'); -const SkyblockPet = require('./SkyblockPet'); -const Player = require('../Player'); - -/** - * Skyblock member class - */ -class SkyblockMember { - /** - * @param {object} data Skyblock member data - */ - constructor(data) { - /** - * Skyblock member UUID - * @type {string} - */ - this.uuid = data.uuid; - /** - * Skyblock member's player profile - * If `fetchPlayer` option is `true`. - * @type {Player|null} - */ - this.player = data.m.player || null; - /** - * If `getMuseum` option is `true`. - * @type {SkyblockMuseum|null} - */ - this.museum = data.museum || null; - /** - * If `getGarden` option is `true`. - * @type {SkyblockGarden|null} - */ - this.garden = data.garden || null; - /** - * Profile's gamemode - * @type {string|null} - */ - this.gameMode = data.gameMode; - /** - * Profile is selected - * @type {boolean} - */ - this.selected = data.selected; - /** - * Skyblock member's profile name - * @type {string} - */ - this.profileName = data.profileName; - /** - * Skyblock member's profile id - * @type {string} - */ - this.profileId = data.profileId; - /** - * Timestamp when player first joined SkyBlock - * @type {number} - */ - this.firstJoinTimestamp = data.m.profile?.first_join; - /** - * Timestamp when player first joined SkyBlock as Date - * @type {Date} - */ - this.firstJoinAt = new Date(data.m.profile?.first_join); - /** - * Experience - * @type {number} - */ - this.experience = data.m.leveling?.experience ?? 0; - /** - * Skyblock Level - * @type {number} - */ - this.level = this.experience ? this.experience / 100 : 0; - /** - * Heart of the Mountain - MiningSkill - * @type {SkyblockMemberHotm} - */ - this.hotm = getHOTM(data.m); - /** - * The highest magical power **Not current one** - * @type {number} - */ - this.highestMagicalPower = data.m.accessory_bag_storage?.highest_magical_power ?? 0; - /** - * Collected fairy souls - * @type {number} - */ - this.fairySouls = data.m?.fairy_soul?.total_collected ?? 0; - /** - * Amount of fairy soul exchanges - * @type {number} - */ - this.fairyExchanges = data.m?.fairy_soul?.fairy_exchanges ?? 0; - /** - * Skyblock member skills - * @type {SkyblockMemberSkills} - */ - this.skills = getSkills(data.m); - /** - * Bestiary of the user - * @type {number} - */ - this.bestiary = getBestiaryLevel(data.m); - /** - * Skyblock member slayer - * @type {SkyblockMemberSlayer|null} - */ - this.slayer = getSlayer(data.m); - /** - * Skyblock Member Crimson Isle - * @type {SkyblockMemberCrimsonIsle} - */ - this.crimson = getCrimson(data.m); - /** - * Skyblock member dungeons - * @type {SkyblockMemberDungeons|null} - */ - this.dungeons = getDungeons(data.m); - /** - * Skyblock member collections - * @type {object} - */ - this.collections = data.m.collection ? data.m.collection : null; - /** - * Skyblock coins in purse - * @type {number} - */ - this.purse = data.m?.currencies?.coin_purse ?? 0; - /** - * Skyblock member stats - * @type {object} - */ - this.stats = data.m.player_stats ? getMemberStats(data.m.player_stats) : null; - /** - * Skyblock pets - * @type {SkyblockPet[]} - */ - this.pets = data.m?.pets_data?.pets ? data.m.pets_data.pets.map((pet) => new SkyblockPet(pet)) : []; - /** - * Skyblock jacob data - * @type {jacobData} - */ - this.jacob = getJacobData(data.m); - /** - * Skyblock Chocolate Factory - * @type {chocolateFactoryData} - */ - this.chocolate = getChocolateFactory(data.m); - /** - * Equipped armor - * @return {Promise} - */ - this.getArmor = async () => { - const base64 = data.m.inventory.inv_armor; - const decoded = await decode(base64.data); - const armor = { - helmet: decoded[3].id ? new SkyblockInventoryItem(decoded[3]) : null, - chestplate: decoded[2].id ? new SkyblockInventoryItem(decoded[2]) : null, - leggings: decoded[1].id ? new SkyblockInventoryItem(decoded[1]) : null, - boots: decoded[0].id ? new SkyblockInventoryItem(decoded[0]) : null - }; - return armor; - }; - /** - * Wardrobe contents - * @return {Promise} - */ - this.getWardrobe = async () => { - const base64 = data.m?.inventory?.wardrobe_contents?.data; - if (!base64) return []; - const decoded = await decode(base64); - const armor = decoded - .filter((item) => 0 !== Object.keys(item).length) - .map((item) => new SkyblockInventoryItem(item)); - return armor; - }; - /** - * Skyblock member enderchest - * @return {Promise} - */ - this.getEnderChest = async () => { - let chest = data.m.inventory.ender_chest_contents; - if (!chest) return []; - - try { - chest = await decode(chest.data); - const edited = []; - for (let i = 0; i < chest.length; i++) { - if (!chest[i].id) { - continue; - } - edited.push(new SkyblockInventoryItem(chest[i])); - } - return edited; - } catch { - return []; - } - }; - /** - * Skyblock member inventory - * @return {Promise} - */ - this.getInventory = async () => { - let inventory = data.m.inventory.inv_contents; - if (!inventory) return []; - - try { - inventory = await decode(inventory.data); - const edited = []; - for (let i = 0; i < inventory.length; i++) { - if (!inventory[i].id) { - continue; - } - edited.push(new SkyblockInventoryItem(inventory[i])); - } - return edited; - } catch { - return []; - } - }; - /** - * Skyblock Member pet score - * @return {number} - */ - this.getPetScore = () => { - const highestRarity = {}; - for (const pet of data.m.pets_data.pets) { - if (!(pet.type in highestRarity) || Constants.petScore[pet.tier] > highestRarity[pet.type]) { - highestRarity[pet.type] = Constants.petScore[pet.tier]; - if ('PET_ITEM_TIER_BOOST' === pet.heldItem && 'MYTHIC' !== pet.tier) { - highestRarity[pet.type] += 1; - } - } - } - - const highestLevel = {}; - for (const pet of data.m.pets_data.pets) { - const maxLevel = 'GOLDEN_DRAGON' === pet.type ? 200 : 100; - const petLevel = getPetLevel(pet.exp, pet.tier, maxLevel); - - if (!(pet.type in highestLevel) || petLevel.level > highestLevel[pet.type]) { - if (petLevel.level < maxLevel) { - continue; - } - - highestLevel[pet.type] = 1; - } - } - - return ( - Object.values(highestRarity).reduce((a, b) => a + b, 0) + Object.values(highestLevel).reduce((a, b) => a + b, 0) - ); - }; - /** - * Skyblock member equipment - * @return {Promise} - */ - this.getEquipment = async () => { - let equipment = data.m.inventory.equipment_contents; - if (!equipment) return []; - - try { - equipment = await decode(equipment.data); - const playerEquipment = { - gauntlet: equipment[3].id ? new SkyblockInventoryItem(equipment[3]) : null, - belt: equipment[2].id ? new SkyblockInventoryItem(equipment[2]) : null, - cloak: equipment[1].id ? new SkyblockInventoryItem(equipment[1]) : null, - necklace: equipment[0].id ? new SkyblockInventoryItem(equipment[0]) : null - }; - return playerEquipment; - } catch { - return []; - } - }; - /** - * Skyblock member Personal Vault - * @return {Promise} - */ - this.getPersonalVault = async () => { - let vault = data.m.inventory.personal_vault_contents; - if (!vault) return []; - - try { - vault = await decode(vault.data); - const edited = []; - for (let i = 0; i < vault.length; i++) { - if (!vault[i].id) { - continue; - } - edited.push(new SkyblockInventoryItem(vault[i])); - } - return edited; - } catch { - return []; - } - }; - /** - * Skyblock member networth (Credit to skyhelper-networth package) - * @return {Promise} - */ - this.getNetworth = async () => { - try { - const nw = await skyhelper.getNetworth(data.m, data.banking?.balance ?? 0, { - onlyNetworth: true, - v2Endpoint: true, - cache: true, - museumData: data.museum?.raw ?? {} - }); - return nw; - } catch { - return []; - } - }; - } - /** - * UUID - * @return {string} - */ - toString() { - return this.uuid; - } -} -/** - * @typedef {object} SkyblockMemberEquipment - * @property {SkyblockInventoryItem|null} gauntlet Gauntlet - * @property {SkyblockInventoryItem|null} belt Belt - * @property {SkyblockInventoryItem|null} cloak Cloak - * @property {SkyblockInventoryItem|null} necklace Necklace - */ -/** - * @typedef {object} SkyblockMemberArmor - * @property {SkyblockInventoryItem|null} helmet Helmet - * @property {SkyblockInventoryItem|null} chestplate Chestplate - * @property {SkyblockInventoryItem|null} leggings Leggings - * @property {SkyblockInventoryItem|null} boots Boots - */ -/** - * @typedef {object} SkyblockMemberSkills - * @property {SkyblockSkillLevel} combat Combat skill - * @property {SkyblockSkillLevel} farming Farming skill - * @property {SkyblockSkillLevel} fishing Fishing skill - * @property {SkyblockSkillLevel} mining Mining skill - * @property {SkyblockSkillLevel} foraging Foraging skills - * @property {SkyblockSkillLevel} enchanting Enchanting skill - * @property {SkyblockSkillLevel} alchemy Alchemy skill - * @property {SkyblockSkillLevel} carpentry Carpentry skill - * @property {SkyblockSkillLevel} runecrafting Runecrafting skill - * @property {SkyblockSkillLevel} taming Taming skill - * @property {SkyblockSkillLevel} social Social skill - * @property {number} average Average skill level - */ -/** - * @typedef {object} SkyblockSkillLevel - * There is list of skills: {@link SkyblockMemberSkills}.
- * Usage: `.skills.farming.xp`. - * - * @property {number} xp Total XP - * @property {number} level Level - * @property {number} maxLevel Max level - * @property {number} xpCurrent Current XP - * @property {number} xpForNext XP for next level - * @property {number} progress Progress - * @property {boolean} cosmetic Cosmetic - */ -/** - * @typedef {object} SkyblockMemberSlayer - * @property {SkyblockMemberSlayerLevel} zombie Zombie - * @property {SkyblockMemberSlayerLevel} spider Spider - * @property {SkyblockMemberSlayerLevel} wolf Wolf - * @property {SkyblockMemberSlayerLevel} enderman Enderman - * @property {SkyblockMemberSlayerLevel} blaze Blaze - * @property {SkyblockMemberSlayerLevel} vampire Vampire - */ -/** - * @typedef {object} SkyblockMemberSlayerLevel - * @property {number} xp Total XP - * @property {number} tier1 Tier 1 - * @property {number} tier2 Tier 2 - * @property {number} tier3 Tier 3 - * @property {number} tier4 Tier 4 - * @property {number} tier5 Tier 5 - * @property {number} level Level - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsle - * @property {"mages"|"barbarians"|null} faction Faction - * @property {SkyblockMemberCrimsonIsleRepuation} repuation Repuation - * @property {SkyblockMemberCrimsonIsleTrophyFish} trophyFish trophyFish - * @property {SkyblockMemberCrimsonIsleKuudra} kuudra Kuudra - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleTrophyFishDojo - * @property {"Black"|"Brown"|"Blue"|"Green"|"Yellow"|"White"} belt Belt Color - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} force Force - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} stamina Stamina - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} mastery Mastery - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} discipline Discipline - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} swiftness Swiftness - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} control Control - * @property {SkyblockMemberCrimsonIsleTrophyFishDojoMode} tenacity Tenacity - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleTrophyFishDojoMode - * @property {number} points Points - * @property {"S"|"A"|"B"|"C"|"D"|"F"} rank Rank - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleTrophyFish - * @property {'Bronze'|'Silver'|'Gold'|'Diamond'|null} rank Trophy Fish Rank - * @property {SkyblockMemberCrimsonIsleTrophyFishCaught} caught - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleTrophyFishCaught - * @property {number} total Total Caught - * @property {number} bronze Bronze Caught - * @property {number} silver Silver Caught - * @property {number} gold Gold Caught - * @property {number} diamond Diamond Caught - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleRepuation - * @property {number} barbarians barbarian Repuation - * @property {number} mages mage Repuation - */ -/** - * @typedef {object} SkyblockMemberCrimsonIsleKuudra - * @property {number} none None Completions - * @property {number} hot Hot Completions - * @property {number} burning Burning Completions - * @property {number} fiery Fiery Completions - * @property {number} highestWaveHot Highest Wave Hot - * @property {number} highestWaveFiery Highest Wave Fiery - * @property {number} infernal Infernal Completions - * @property {number} highestWaveInfernal Highest Wave Infernal - * @property {number} highestWaveBurning Highest Wave Burning - */ -/** - * @typedef {object} SkyblockMemberDungeons - * @property {SkyblockSkillLevel} experience Dungeons Experience - * @property {number} secrets Amount of secrets found - * @property {SkyblockMemberDungeonsCompletions} completions Dungeon completions - * @property {SkyblockMemberDungeonsFloors} floors Dungeon Floor Stats - */ -/** - * @typedef {object} SkyblockMemberDungeonsCompletions - * @property {Record} catacombs Normal Dungeons - * @property {Record} masterCatacombs Master Mode Dungeons - */ -/** - * @typedef {object} SkyblockMemberDungeonsClasses - * @property {SkyblockSkillLevel} healer Healer class - * @property {SkyblockSkillLevel} mage Mage class - * @property {SkyblockSkillLevel} berserk Berserk class - * @property {SkyblockSkillLevel} archer Archer class - * @property {SkyblockSkillLevel} tank Tank class - * @property {string} selected Current Selected Class - */ -/** - * @typedef {object} SkyblockMemberDungeonsFloorRun - * @property {number} timestamp Timestamp - * @property {number} score_exploration Score Exploration - * @property {number} score_speed Score Speed - * @property {number} score_skill Score Skill - * @property {number} score_bonus Score Bonus - * @property {string} dungeon_class Dungeon Class - * @property {string[]} teammates Teammates - * @property {number} elapsed_time Elapsed Time - * @property {number} damage_dealt Damage Dealt - * @property {number} deaths Deaths - * @property {number} mobs_killed Mobs Killed - * @property {number} secrets_found Secrets Found - * @property {number} damage_mitigated Damage Mitigated - */ -/** - * @typedef {object} SkyblockMemberDungeonsFloor - * @property {SkyblockMemberDungeonsFloorRun} fastestRun Fastest Run - * @property {SkyblockMemberDungeonsFloorRun} fastestSRun Fastest S Run - * @property {SkyblockMemberDungeonsFloorRun} fastestSPlusRun Fastest S+ Run - * @property {number} completions Completions - */ -/** - * @typedef {object} SkyblockMemberDungeonsFloors - * @property {SkyblockMemberDungeonsFloor} entrance Entrance Stats - * @property {SkyblockMemberDungeonsFloor} floor1 Floor 1 Stats - * @property {SkyblockMemberDungeonsFloor} floor2 Floor 2 Stats - * @property {SkyblockMemberDungeonsFloor} floor3 Floor 3 Stats - * @property {SkyblockMemberDungeonsFloor} floor4 Floor 4 Stats - * @property {SkyblockMemberDungeonsFloor} floor5 Floor 5 Stats - * @property {SkyblockMemberDungeonsFloor} floor6 Floor 6 Stats - * @property {SkyblockMemberDungeonsFloor} floor7 Floor 7 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs1 Master Mode Floor 1 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs2 Master Mode Floor 2 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs3 Master Mode Floor 3 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs4 Master Mode Floor 4 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs5 Master Mode Floor 5 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs6 Master Mode Floor 6 Stats - * @property {SkyblockMemberDungeonsFloor} masterCatacombs7 Master Mode Floor 7 Stats - */ -/** - * @typedef {object} jacobDataPerks - * @property {number} doubleDrops Double drops - * @property {number} farmingLevelCap Farming level cap - * @property {boolean} personalBests Personal Bests - */ -/** - * @typedef {object} jacobDataMedals - * @property {number} gold gold medals - * @property {number} silver silver medals - * @property {number} bronze bronze medals - */ -/** - * @typedef {object} jacobData - * @property {jacobDataMedals} medals Medals - * @property {jacobDataPerks} perks Perks - * @property {object} contests Contests - */ -/** - * @typedef {object} chocolateFactoryDataEmployees - * @property {number} bro bro employee level - * @property {number} cousin cousin employee level - * @property {number} sis sis employee level - * @property {number} father father employee level - * @property {number} grandma grandma employee level - * @property {number} dog dog employee level - * @property {number} uncle uncle employee level - */ -/** - * @typedef {object} chocolateFactoryDataChocolate - * @property {number} count amount of current chocolate - * @property {number} total total amount of chocolate - * @property {number} sincePrestige amount of chocolate since prestige - */ -/** - * @typedef {object} chocolateFactoryDataTimeTower - * @property {number} charge amount of charges in the time tower - * @property {number} level level of the time tower - */ -/** - * @typedef {object} chocolateFactoryDataUpgrades - * @property {number} click amount of click upgrades - * @property {number} multiplier amount of multiplier upgrades - * @property {number} rabbitRarity amount of rabbit rarity upgrades - */ -/** - * @typedef {object} chocolateFactoryDataGoldenClick - * @property {number} amount amount of golden clicks - * @property {number} year year - */ -/** - * @typedef {object} chocolateFactoryData - * @property {chocolateFactoryDataEmployees} employees Employees - * @property {chocolateFactoryDataChocolate} chocolate Chocolate - * @property {chocolateFactoryDataTimeTower} timeTower Time Tower - * @property {chocolateFactoryDataUpgrades} upgrades Upgrades - * @property {chocolateFactoryDataGoldenClick} goldenClick Golden Click - * @property {number} barnCapacity Barn Capacity - * @property {number} prestige Prestige - */ -/** - * @typedef {object} SkyblockMemberHotmPowderData - * @property {number} spent Spent HOTM Powder - * @property {number} current Current HOTM Powder - * @property {number} total Total HOTM Powder - */ -/** - * @typedef {object} SkyblockMemberHotmPowder - * @property {SkyblockMemberHotmPowderData} mithril Mithril Powder - * @property {SkyblockMemberHotmPowderData} gemstone Gemstone Powder - * @property {SkyblockMemberHotmPowderData} glacite Glacite Powder - */ -/** - * @typedef {object} SkyblockMemberHotm - * @property {SkyblockSkillLevel} experience Experience - * @property {string} ability Selected Ability - * @property {SkyblockMemberHotmPowder} powder Powder Data - */ -module.exports = SkyblockMember; diff --git a/src/structures/SkyBlock/SkyblockMuseum.js b/src/structures/SkyBlock/SkyblockMuseum.js deleted file mode 100644 index 8753275e7..000000000 --- a/src/structures/SkyBlock/SkyblockMuseum.js +++ /dev/null @@ -1,60 +0,0 @@ -const SkyblockMuseumItem = require('./SkyblockMuseumItem'); -const { decode } = require('../../utils/SkyblockUtils'); -/** - * Skyblock Museum class - */ -class SkyblockMuseum { - /** - * @param {object} data Skyblock member data - */ - constructor(data) { - /** - * Raw data - * @type {object} - */ - this.raw = data.m.members?.[data.uuid] ?? {}; - /** - * Normal Items - * @returns {SkyblockMuseumItem[]} - */ - this.getItems = async () => { - const keys = Object.keys(data.m.members[data.uuid].items); - const items = []; - for (const key of keys) { - const decoded = await decode(data.m.members[data.uuid].items[key].items.data); - items.push( - new SkyblockMuseumItem({ - decoded: decoded, - borrowing: data.m.members[data.uuid].items[key].borrowing ?? false, - featuredSlot: data.m.members[data.uuid].items[key].featured_slot ?? null, - donatedTime: data.m.members[data.uuid].items[key].donated_time, - name: key.toLowerCase().replace(/_/g, ' ') - }) - ); - } - return items; - }; - /** - * Special items - * @returns {SkyblockMuseumItem[]} - */ - this.getSpecial = async () => { - const items = []; - for (const item of data.m.members[data.uuid].special) { - const decoded = await decode(item.items.data); - items.push( - new SkyblockMuseumItem({ - decoded: decoded, - borrowing: item.borrowing ?? false, - featuredSlot: item.featured_slot ?? null, - donatedTime: item.donated_time, - name: null - }) - ); - } - return items; - }; - } -} - -module.exports = SkyblockMuseum; diff --git a/src/structures/SkyBlock/SkyblockMuseumItem.js b/src/structures/SkyBlock/SkyblockMuseumItem.js deleted file mode 100644 index c1ea7cee5..000000000 --- a/src/structures/SkyBlock/SkyblockMuseumItem.js +++ /dev/null @@ -1,54 +0,0 @@ -const SkyblockInventoryItem = require('./SkyblockInventoryItem'); -/** - * Item class - */ -class SkyblockMuseumItem { - /** - * @param {object} data Item data - */ - constructor(data) { - /** - * Item name - * @type {string|null} - **/ - this.name = data.name; - /** - * Item - * @type {SkyblockInventoryItem[]} - */ - this.items = []; - data.decoded.forEach((item) => { - if (!item.tag) return; - this.items.push(new SkyblockInventoryItem(item)); - }); - /** - * Donated Time - * @type {number} - */ - this.donatedTime = data.donatedTime; - /** - * Donated Time as Date - * @type {Date} - */ - this.donatedTimeAt = new Date(data.donatedTime); - /** - * Borrowing - * @type {boolean} - */ - this.borrowing = data.borrowing; - /** - * Featured Slot - * @type {string|null} - */ - this.featuredSlot = data.featuredSlot; - } - /** - * Item Name - * @return {string} - */ - toString() { - return this.name; - } -} - -module.exports = SkyblockMuseumItem; diff --git a/src/structures/SkyBlock/SkyblockPet.js b/src/structures/SkyBlock/SkyblockPet.js deleted file mode 100644 index f6e07a78d..000000000 --- a/src/structures/SkyBlock/SkyblockPet.js +++ /dev/null @@ -1,71 +0,0 @@ -const { petScore } = require('../../utils/Constants'); -/** - * Skyblock Pet class - */ -class SkyblockPet { - /** - * Skyblock pet data - * @param {object} data - */ - constructor(data) { - /** - * Skyblock Pet UUID - * @type {string} - */ - this.uuid = data.uuid; - /** - * Skyblock Pet type - * @type {string} - */ - this.type = data.type; - /** - * Skyblock Pet experience - * @type {number} - */ - this.xp = data.exp || 0; - /** - * wether the pet is currently equipped - * @type {boolean} - */ - this.active = Boolean(data.active); - /** - * Skyblock Pet rarity - * @type {Rarity} - */ - this.rarity = data.tier; - /** - * Skyblock Pet score - * @type {number} - */ - - this.petScore = petScore[data.tier] || 0; - /** - * Skyblock Pet held item - * @type {string|null} - */ - this.heldItem = data.heldItem ? data.heldItem.replace(/^PET_ITEM_/, '') : null; - /** - * Skyblock Pet candy used - * @type {number} - */ - this.candyUsed = data.candyUsed || 0; - /** - * Skyblock Pet skin - * @type {string|null} - */ - this.skin = data.skin; - } -} -/** - * @typedef {string} Rarity - * * `VERY_SPECIAL` - * * `SPECIAL` - * * `SUPREME` - * * `MYTHIC` - * * `LEGENDARY` - * * `EPIC` - * * `RARE` - * * `UNCOMMON` - * * `COMMON` - */ -module.exports = SkyblockPet; diff --git a/src/structures/SkyBlock/SkyblockProfile.js b/src/structures/SkyBlock/SkyblockProfile.js deleted file mode 100644 index dc6b60aea..000000000 --- a/src/structures/SkyBlock/SkyblockProfile.js +++ /dev/null @@ -1,81 +0,0 @@ -const SkyblockGarden = require('./SkyblockGarden'); -const SkyblockMember = require('./SkyblockMember'); -/** - * Skyblock Profile class - */ -class SkyblockProfile { - /** - * Skyblock profile data - * @param {object} data - */ - constructor(data) { - /** - * Skyblock profile ID - * @type {string} - */ - this.profileId = data.profileId; - /** - * Skyblock profile name - * @type {string} - */ - this.profileName = data.profileName; - /** - * Profile's gamemode - * @type {string|null} - */ - this.gameMode = data.gameMode; - /** - * Profile's banking - * @type {object} - */ - this.banking = data.banking; - /** - * Profile's garden - * @type {SkyblockGarden|null} - */ - this.garden = data.garden || null; - /** - * Profile's community upgrades - * @type {object} - */ - this.communityUpgrades = data.communityUpgrades; - /** - * Profile is selected - * @type {boolean} - */ - this.selected = data.selected; - /** - * Skyblock profile members - * @type {SkyblockMember[]} - */ - this.members = Object.keys(data.members).map( - (uuid) => - new SkyblockMember({ - uuid: uuid, - profileId: this.profileId, - profileName: this.profileName, - gameMode: this.gameMode, - m: data.members[uuid], - banking: this.banking, - communityUpgrades: this.communityUpgrades, - museum: null, - garden: this.garden, - selected: this.selected - }) - ); - /** - * Queried player's member stats - * @type {SkyblockMember} - */ - this.me = this.members.find((x) => x.uuid === data.uuid); - } - /** - * Profile Name - * @return {string} - */ - toString() { - return this.profileName; - } -} - -module.exports = SkyblockProfile; diff --git a/src/structures/SkyBlock/Static/Bingo.js b/src/structures/SkyBlock/Static/Bingo.js deleted file mode 100644 index acd474854..000000000 --- a/src/structures/SkyBlock/Static/Bingo.js +++ /dev/null @@ -1,101 +0,0 @@ -// eslint-disable-next-line jsdoc/require-jsdoc -function parsePosition(position) { - const x = (position % 5) + 1; - const y = Math.floor(position / 5) + 1; - return [x, y]; -} -/** - * Bingo class - */ -class Bingo { - /** - * Constructor - * @param {Object} data data - * @param {number} position Position - */ - constructor(data, position = 0) { - /** - * Name of this bingo goal - * @type {string} - */ - this.name = data.name; - /** - * string ID (code name) - * @type {string} - */ - this.id = data.id; - const [row, column] = parsePosition(position); - /** - * 1-indexed row - * @type {number|null} - */ - this.row = row; - /** - * 1-indexed colmun - * @type {number|null} - */ - this.column = column; - /** - * Bingo lore, with color codes - * @type {string} - */ - this.rawLore = data.lore; - /** - * Bingo lore in plain text - * @type {string} - */ - this.lore = data.lore?.replace?.(/§([1-9]|[a-l])|§/gm, '') || null; - /** - * Only available for TIERED bingos - * Shows you the requirement for each tier of this achievement - * @type {number[]} - */ - this.tiers = Array.isArray(data.tiers) ? data.tiers.map((x) => parseInt(x, 10) || 0) : null; - /** - * Only available for TIERED bingos - * Difference between each tier requirement, if it is constant - * @type {number|null} - */ - this.tierStep = this.getTierStep(); - /** - * Only available for ONE_TIERED bingos - * @type {number|null} - */ - this.requiredAmount = parseInt(data.requiredAmount, 10) ?? null; - /** - * Type of Bingo - * ONE_TIME means the goal doesn't have a specific amount - * ONE_TIER means the goal specifies 1 amount to achieve - * TIERED means the goal specifies more than 1 amount to achieve - * @type {'ONE_TIME'|'ONE_TIER'|'TIERED'} - */ - this.type = this.tiers ? 'TIERED' : this.requiredAmount ? 'ONE_TIER' : 'ONE_TIME'; - } - /** - * As string - * BEWARE this returns ID to assure compatibility with PlayerBingo - * @return {string} - */ - toString() { - return this.id; - } - /** - * Gets tier step, if constant - * @private - * @returns {number|null} - */ - getTierStep() { - if ('TIERED' !== this.type) return null; - // No step possible - if (2 > this.tiers.length) return null; - const hypotheticStep = this.tiers[1] - this.tiers[0]; - // Check if every 2 elements have the same step - const isConstant = this.tiers.slice(1).every((el, index) => { - return hypotheticStep === this.tiers[index - 1] - el; - }); - if (!isConstant) return null; - return hypotheticStep; - } -} - -module.exports = Bingo; diff --git a/src/structures/SkyBlock/Static/BingoData.js b/src/structures/SkyBlock/Static/BingoData.js deleted file mode 100644 index 42a6cb363..000000000 --- a/src/structures/SkyBlock/Static/BingoData.js +++ /dev/null @@ -1,45 +0,0 @@ -const Bingo = require('./Bingo.js'); - -/** - * SB Bingo Class - */ -class BingoData { - /** - * constructor - * @param {Object} data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - /** - * Bingo ID - * @type {number|null} - */ - this.id = parseInt(data.id, 10) || null; - /** - * Goals - * @type {Bingo[]|null} - */ - this.goals = Array.isArray(data.goals) ? data.goals.map((goal, index) => new Bingo(goal, index)) : null; - } - /** - * Gets a goal on the bingo table by row and column - * @param {number} column Column number (starts at 1) - * @param {number} row Row number (starts at 1) - * @returns {Bingo|undefined} - */ - getGoal(column, row) { - if (!this.goals || 1 > this.goals.length) return; - return this.goals.find((goal) => goal.row === row && goal.column === column); - } -} - -module.exports = BingoData; diff --git a/src/structures/SkyBlock/Static/Candidate.js b/src/structures/SkyBlock/Static/Candidate.js deleted file mode 100644 index 9626a0f7c..000000000 --- a/src/structures/SkyBlock/Static/Candidate.js +++ /dev/null @@ -1,50 +0,0 @@ -const Perk = require('./Perk'); -/** - * Candidate class - */ -class Candidate { - /** - * Constructor - * @param {Object} data data - * @param {boolean} [isMayor=false] if this candidate is the current mayor - */ - constructor(data, isMayor = false, isMinister = false) { - /** - * Mayor's name - * @type {string} - */ - this.name = data.name; - /** - * Mayor's Key Benefit (in 1 word) - * @type {string} - */ - this.keyBenefit = data.key; - /** - * Mayor's Perk (Only shows if its the Minister) - * @type {Perk|null} - */ - this.perk = data.perk?.[0] ? new Perk(data.perk[0]) : null; - /** - * Perks - * @type {Perk[]} - */ - this.perks = data.perks?.map((x) => new Perk(x)) ?? []; - /** - * If this candidate is the current mayor - * @type {boolean} - */ - this.isMayor = isMayor || false; - /** - * If this candidate is the current mayor - * @type {boolean} - */ - this.isMinister = isMinister || false; - /** - * The number of votes received by this candidate - * @type {number} - */ - this.votesReceived = parseInt(data.votes, 10) || 0; - } -} - -module.exports = Candidate; diff --git a/src/structures/SkyBlock/Static/FireSale.js b/src/structures/SkyBlock/Static/FireSale.js deleted file mode 100644 index 20dfa18c4..000000000 --- a/src/structures/SkyBlock/Static/FireSale.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * SB Fire Sale - */ -class FireSale { - /** - * constructor - * @param {Object} data - */ - constructor(data) { - /** - * Item ID - * @type {string|null} - */ - this.itemId = data.item_id || null; - /** - * Start Timestamp as a unix - * @type {number} - */ - this.startTimestamp = parseInt(data.start, 10); - /** - * Start Date - * @type {Date} - */ - this.startAt = new Date(this.startTimestamp); - /** - * End Timestamp as a unix - * @type {number} - */ - this.endTimestamp = parseInt(data.end, 10); - /** - * End Date - * @type {Date} - */ - this.endAt = new Date(this.endTimestamp); - /** - * Amount of items being sold - * @type {number} - */ - this.amount = data.amount || 0; - /** - * Price - * @type {number} - */ - this.price = data.price || 0; - } - /** - * Item Id - * @return {string|null} - */ - toString() { - return this.itemId; - } -} - -module.exports = FireSale; diff --git a/src/structures/SkyBlock/Static/Government.js b/src/structures/SkyBlock/Static/Government.js deleted file mode 100644 index d0286455b..000000000 --- a/src/structures/SkyBlock/Static/Government.js +++ /dev/null @@ -1,79 +0,0 @@ -const Candidate = require('./Candidate'); - -/** - * SB Government Class - */ -class GovernmentData { - /** - * constructor - * @param {Object} data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - const lastElectionResults = data.mayor.election.candidates.map((x) => new Candidate(x, x.name === data.mayor.name)); - /** - * A map of last election results for each candidate - * Sorted ascendingly by votes received - * @type {Map} - */ - this.lastElectionResults = new Map( - lastElectionResults - .sort((a, b) => a.votesReceived - b.votesReceived) - .reverse() - .map((x) => [x.name, x]) - ); - /** - * The mayor - * @type {Candidate} - */ - this.mayor = this.lastElectionResults.get(data.mayor.name); - /** - * Minister - * @type {Candidate} - */ - this.minister = new Candidate(data.mayor.minister, false, true); - /** - * The year the mayor will be running for - * @type {number} - */ - this.runningYear = parseInt(data.mayor.election.year, 10) || 0; - const thisElection = data.current?.candidates.map((x) => new Candidate(x, x.name === data.mayor.name)) || null; - /** - * Current elections, valid for next year - * Sorted ascendingly by votes received - * RESULTS MIGHT BE TEMPORARY - * @type {Map|null} - */ - this.currentElectionResults = thisElection - ? new Map( - thisElection - .sort((a, b) => a.votesReceived - b.votesReceived) - .reverse() - .map((x) => [x.name, x]) - ) - : null; - /** - * The year the current election will be effective for - * @type {number|null} - */ - this.currentElectionFor = parseInt(data.current?.year, 10) || null; - } - /** - * Current Mayor - * @return {string} - */ - toString() { - return this.mayor.name; - } -} - -module.exports = GovernmentData; diff --git a/src/structures/SkyBlock/Static/Perk.js b/src/structures/SkyBlock/Static/Perk.js deleted file mode 100644 index 17fe0a1b6..000000000 --- a/src/structures/SkyBlock/Static/Perk.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Candidate class - */ -class Perk { - /** - * Constructor - * @param {Object} data data - */ - constructor(data) { - /** - * Perk's Name - * @type {string} - */ - this.name = data.name; - /** - * Perk's Description - * @type {string} - */ - this.description = data.description; - } -} - -module.exports = Perk; diff --git a/src/structures/Static/Achievement.js b/src/structures/Static/Achievement.js deleted file mode 100644 index 6707e0cde..000000000 --- a/src/structures/Static/Achievement.js +++ /dev/null @@ -1,87 +0,0 @@ -const AchievementTier = require('./AchievementTier'); - -// eslint-disable-next-line jsdoc/require-jsdoc -function collectAll(data) { - const mTier = data.maxTier; - let totalPoints = 0; - let totalAmount = 0; - for (let i = 1; i <= mTier; i++) { - totalPoints += data.getTier(i).pointsRewarded; - totalAmount += data.getTier(i).amountRequired; - } - return { totalPoints, totalAmount }; -} - -/** - * Achievement Class - */ -class Achievement { - /** - * constructor - * @param {string} achievementName Name of achievement - * @param {Object} data - */ - constructor(achievementName, data) { - /** - * Name of achievement, trimmed trailing spaces - * @type {string} - */ - this.name = data.name.trim(); - /** - * Code name of achievement - * @type {string} - */ - this.codeName = achievementName; - /** - * Description, trimmed trailing spaces - * @type {string} - */ - this.description = data.description.trim(); - /** - * Type of achievement - * @type {'ONE_TIME'|'TIERED'} - */ - this.type = data.tiers ? 'TIERED' : 'ONE_TIME'; - /** - * ONLY AVAILABLE IN PERSONAL ONE TIME ACHIEVEMENTS, last checked April 26th - * Unlock rate of this achievement - * Local : Fraction of players that have played the game and gotten this achievement (0 to 1 inclusive) - * Global : Fraction of players that have played Hypixel and gotten this achievement (0 to 1 inclusive) - * ...percentage : In percentage (0 to 100 inclusive) - * @type {Record<'local'|'localPercentage'|'global'|'globalPercentage', number>|null} - */ - this.rarity = { - local: parseFloat(data.gamePercentUnlocked) || 0, - localPercentage: parseFloat(data.gamePercentUnlocked) * 100 || 0, - global: data.globalPercentUnlocked, - globalPercentage: parseFloat(data.globalPercentUnlocked) * 100 || 0 - }; - /** - * ONLY AVAILABLE FOR TIERED - * @type {AchievementTier|null} - */ - this.tierInformation = 'TIERED' === this.type ? new AchievementTier(data.tiers) : null; - - const { totalPoints, totalAmount } = 'TIERED' === this.type ? collectAll(this.tierInformation) : {}; - /** - * Total points worth (sum of all tiers if tiered) - * This is always 0 for Guild Achievements - * @type {number} - */ - this.points = 'ONE_TIME' === this.type ? parseInt(data.points, 10) : totalPoints; - /** - * Total amount required to reach max tier, only for tiered - * @type {number|null} - */ - this.totalAmountRequired = 'TIERED' === this.type ? totalAmount : null; - } - /** - * As string - * @return {string} - */ - toString() { - return this.achievementName; - } -} - -module.exports = Achievement; diff --git a/src/structures/Static/AchievementTier.js b/src/structures/Static/AchievementTier.js deleted file mode 100644 index 7b13b037c..000000000 --- a/src/structures/Static/AchievementTier.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * AchievementTier class - */ -class AchievementTier { - /** - * @param {Record} data - */ - constructor(data) { - /** - * Maximum tier reachable - * getTier will be take any integer from 1 to this number (inclusive) - * @type {number} - */ - this.maxTier = data.length; - // Still make sure it is well sorted - this.tierInfo = data.sort(({ tier: tierA }, { tier: tierB }) => Number(tierA) - Number(tierB)); - } - /** - * Gets information for tier - * @param {number} tier Tier number (1-indexed!) - * @returns {Record<'pointsRewarded'|'amountRequired', number>} - */ - getTier(tier) { - const index = tier - 1; - const info = this.tierInfo[index]; - return { - pointsRewarded: parseInt(info.points, 10) || 0, - amountRequired: parseInt(info.amount, 10) || 0 - }; - } -} - -module.exports = AchievementTier; diff --git a/src/structures/Static/Achievements.js b/src/structures/Static/Achievements.js deleted file mode 100644 index f568dee2b..000000000 --- a/src/structures/Static/Achievements.js +++ /dev/null @@ -1,30 +0,0 @@ -const GameAchievements = require('./GameAchievements.js'); - -/** - * Achievement class - */ -class Achievements { - /** - * @param {object} data data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - /** - * @type {Record} - */ - this.achievementsPerGame = Object.fromEntries( - Object.entries(data.achievements).map(([game, data]) => [game, new GameAchievements(game, data)]) - ); - } -} - -module.exports = Achievements; diff --git a/src/structures/Static/Challenges.js b/src/structures/Static/Challenges.js deleted file mode 100644 index dff19b1ae..000000000 --- a/src/structures/Static/Challenges.js +++ /dev/null @@ -1,29 +0,0 @@ -const GameChallenges = require('./GameChallenges.js'); -/** - * Achievement class - */ -class Challenges { - /** - * @param {object} data data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - /** - * @type {Record} - */ - this.challengesPerGame = Object.fromEntries( - Object.entries(data.challenges).map(([game, data]) => [game, new GameChallenges(game, data)]) - ); - } -} - -module.exports = Challenges; diff --git a/src/structures/Static/GameAchievements.js b/src/structures/Static/GameAchievements.js deleted file mode 100644 index 17a3f5636..000000000 --- a/src/structures/Static/GameAchievements.js +++ /dev/null @@ -1,36 +0,0 @@ -const Achievement = require('./Achievement'); - -/** - * Game achievements class - */ -class GameAchievements { - /** - * @param {string} name game name - * @param {object} data data - */ - constructor(name, data) { - /** - * Name of game/category - * @type {StaticGameNames} - */ - this.category = name; - /** - * Total points possible from all achievements in this game - * @type {number} - */ - this.totalPoints = parseInt(data.total_points, 10) || 0; - /** - * Total legacy points possible from all achievements in this game - * @type {number} - */ - this.totalLegacyPoints = parseInt(data.total_legacy_points, 10) || 0; - /** - * @type {Achievement[]} - */ - this.achievements = Object.entries({ ...(data.one_time || {}), ...(data.tiered || {}) }).map( - ([name, data]) => new Achievement(name, data) - ); - } -} - -module.exports = GameAchievements; diff --git a/src/structures/Static/GameChallenges.js b/src/structures/Static/GameChallenges.js deleted file mode 100644 index 3254aa9f7..000000000 --- a/src/structures/Static/GameChallenges.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Game challenges class - */ -class GameChallenges { - /** - * @param {string} name game name - * @param {object} data data - */ - constructor(name, data) { - /** - * Name of game/category - * @type {StaticGameNames} - */ - this.category = name; - /** - * @type {Map} - */ - this.challenges = new Map(); - - data.forEach((challenge) => { - const content = { - id: challenge.id, - name: challenge.name, - reward: parseInt(challenge.rewards[0].amount, 10) || 0, - rewardType: challenge.rewards[0].type - }; - this.challenges.set(challenge.id, content); - }); - } -} - -/** - * @typedef {Object} ChallengeData - * @property {string} id String ID of the challenge - * @property {string} name String name of the challenge - * @property {number} reward Amount of XP upon challenge completion, always 3700 XP. - * @property {string} rewardType Type of reward. Always "MultipliedExperienceReward" here - */ - -module.exports = GameChallenges; diff --git a/src/structures/Static/GameQuests.js b/src/structures/Static/GameQuests.js deleted file mode 100644 index ae0af6c22..000000000 --- a/src/structures/Static/GameQuests.js +++ /dev/null @@ -1,24 +0,0 @@ -const Quest = require('./Quest'); - -/** - * Game quests class - */ -class GameQuests { - /** - * @param {string} name game name - * @param {object} data data - */ - constructor(name, data) { - /** - * Name of game - * @type {StaticGameNames} - */ - this.game = name; - /** - * @type {Quest[]} - */ - this.quests = (data || []).map((x) => new Quest(x)); - } -} - -module.exports = GameQuests; diff --git a/src/structures/Static/GuildAchievements.js b/src/structures/Static/GuildAchievements.js deleted file mode 100644 index bce03b924..000000000 --- a/src/structures/Static/GuildAchievements.js +++ /dev/null @@ -1,34 +0,0 @@ -const Achievement = require('./Achievement.js'); - -/** - * Achievement class - */ -class GuildAchievements { - /** - * @param {object} data data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - /** - * Achievements - * @type {Record} - */ - this.achievements = Object.fromEntries( - Object.entries({ ...(data.tiered || {}), ...(data.one_time || {}) }).map(([name, value]) => [ - name, - new Achievement(name, value) - ]) - ); - } -} - -module.exports = GuildAchievements; diff --git a/src/structures/Static/Quest.js b/src/structures/Static/Quest.js deleted file mode 100644 index d9e26233a..000000000 --- a/src/structures/Static/Quest.js +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Quest Class - */ -class Quest { - /** - * constructor - * @param {Object} data - */ - constructor(data) { - /** - * Name of quest, trimmed trailing spaces - * @type {string} - */ - this.questName = data.name.trim(); - /** - * ID of quest - * @type {string} - */ - this.questID = data.id; - /** - * Description, trimmed trailing spaces - * @type {string} - */ - this.description = data.description.trim(); - /** - * Type of quest - * @type {'DAILY'|'WEEKLY'} - */ - this.type = 'DailyResetQuestRequirement' === data.requirements?.[0].type ? 'DAILY' : 'WEEKLY'; - /** - * Objectives - * @type {Objective[]} - */ - this.objectives = data.objectives.map((objective) => ({ - id: objective.id, - type: 'IntegerObjective' === objective.type ? 'Integer' : 'Boolean', - amountNeeded: parseInt(objective.integer || '1', 10) - })); - /** - * Rewards for this quest - * @type {QuestReward[]} - */ - this.rewards = data.rewards || []; - } - /** - * As string - * @return {string} - */ - toString() { - return this.questName; - } -} - -/** - * @typedef {Object} Objective - * @property {string} id ID - * @property {'Integer'|'Boolean'} type Integer: a certain amount of something (i.e kills) is needed; Boolean: a condition needs to be fulfilled - * @property {number} amountNeeded a Boolean-typed objective will have this set to 1. (instead of null in API) - */ -/** - * @typedef {Object} QuestReward - * @property {string} type Types of reward. - * @property {number} amount Amount - */ - -module.exports = Quest; diff --git a/src/structures/Static/Quests.js b/src/structures/Static/Quests.js deleted file mode 100644 index c3f3e572e..000000000 --- a/src/structures/Static/Quests.js +++ /dev/null @@ -1,31 +0,0 @@ -const GameQuests = require('./GameQuests.js'); - -/** - * Quest class - */ -class Quests { - /** - * @param {object} data data - */ - constructor(data) { - /** - * Last time this resource was updated - * @type {number} - */ - this.lastUpdatedTimestamp = parseInt(data.lastUpdated, 10); - /** - * Last time this resource was updated, as Date - * @type {Date|null} - */ - this.lastUpdatedAt = new Date(this.lastUpdatedTimestamp); - /** - * Quests per game - * @type {Record} - */ - this.questsPerGame = Object.fromEntries( - Object.entries(data.quests).map(([game, data]) => [game, new GameQuests(game, data)]) - ); - } -} - -module.exports = Quests; diff --git a/src/structures/Status.js b/src/structures/Status.js deleted file mode 100644 index b858f1b0c..000000000 --- a/src/structures/Status.js +++ /dev/null @@ -1,41 +0,0 @@ -const Game = require('./Game'); -/** - * Status class - */ -class Status { - /** - * @param {object} data Status data - */ - constructor(data) { - /** - * Player online status.
- *
- * Players can disable this endpoint via in-game settings. When done so the API will return as if the player is offline. - * @type {boolean} - */ - this.online = data.online; - /** - * Game type - * @type {Game|null} - */ - this.game = data.gameType ? new Game(data.gameType) : null; - /** - * Game mode - * @type {string|null} - */ - this.mode = data.mode ?? null; - /** - * Map - * @type {string|null} - */ - this.map = data.map ?? null; - } - /** - * Online Status - * @return {string} - */ - toString() { - return this.online ? 'Online' : 'Offline'; - } -} -module.exports = Status; diff --git a/src/structures/Watchdog/Stats.js b/src/structures/Watchdog/Stats.js deleted file mode 100644 index 1008e07a8..000000000 --- a/src/structures/Watchdog/Stats.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * WatchdogStats class - */ -class WatchdogStats { - /** - * @param {object} data Watchdog data - */ - constructor(data) { - /** - * Total watchdog's bans - * @type {number} - */ - this.byWatchdogTotal = data.watchdog_total || 0; - /** - * Watchdog's bans in the last minute - * @type {number} - */ - this.byWatchdogLastMinute = data.watchdog_lastMinute || 0; - /** - * Watchdog's bans in the last day ( resets at 5 am UTC ). - * @type {number} - */ - this.byWatchdogRollingDay = data.watchdog_rollingDaily || 0; - /** - * Total staff bans - * @type {number} - */ - this.byStaffTotal = data.staff_total || 0; - /** - * Staff bans in the last day ( resets at 5 am UTC ). - * @type {number} - */ - this.byStaffRollingDay = data.staff_rollingDaily || 0; - } -} -module.exports = WatchdogStats; diff --git a/src/utils/Constants.js b/src/utils/Constants.js deleted file mode 100644 index 3af8041b6..000000000 --- a/src/utils/Constants.js +++ /dev/null @@ -1,3260 +0,0 @@ -module.exports = { - duelsDivisions: [ - { name: 'Rookie', key: 'rookie' }, - { name: 'Iron', key: 'iron' }, - { name: 'Gold', key: 'gold' }, - { name: 'Diamond', key: 'diamond' }, - { name: 'Master', key: 'master' }, - { name: 'Legend', key: 'legend' }, - { name: 'Grandmaster', key: 'grandmaster' }, - { name: 'Godlike', key: 'godlike' }, - { name: 'Celestial', key: 'celestial' }, - { name: 'Divine', key: 'divine' }, - { name: 'Ascended', key: 'ascended' } - ], - levelingXp: { - 1: 50, - 2: 125, - 3: 200, - 4: 300, - 5: 500, - 6: 750, - 7: 1000, - 8: 1500, - 9: 2000, - 10: 3500, - 11: 5000, - 12: 7500, - 13: 10000, - 14: 15000, - 15: 20000, - 16: 30000, - 17: 50000, - 18: 75000, - 19: 100000, - 20: 200000, - 21: 300000, - 22: 400000, - 23: 500000, - 24: 600000, - 25: 700000, - 26: 800000, - 27: 900000, - 28: 1000000, - 29: 1100000, - 30: 1200000, - 31: 1300000, - 32: 1400000, - 33: 1500000, - 34: 1600000, - 35: 1700000, - 36: 1800000, - 37: 1900000, - 38: 2000000, - 39: 2100000, - 40: 2200000, - 41: 2300000, - 42: 2400000, - 43: 2500000, - 44: 2600000, - 45: 2750000, - 46: 2900000, - 47: 3100000, - 48: 3400000, - 49: 3700000, - 50: 4000000 - }, - xpPast50: { - 51: 4300000, - 52: 4600000, - 53: 4900000, - 54: 5200000, - 55: 5500000, - 56: 5800000, - 57: 6100000, - 58: 6400000, - 59: 6700000, - 60: 7000000 - }, - runecraftingXp: { - 1: 50, - 2: 100, - 3: 125, - 4: 160, - 5: 200, - 6: 250, - 7: 315, - 8: 400, - 9: 500, - 10: 625, - 11: 785, - 12: 1000, - 13: 1250, - 14: 1600, - 15: 2000, - 16: 2465, - 17: 3125, - 18: 4000, - 19: 5000, - 20: 6200, - 21: 7800, - 22: 9800, - 23: 12200, - 24: 15300, - 25: 19050 - }, - skillsCap: { - taming: 60, - farming: 60, - mining: 60, - combat: 60, - foraging: 50, - fishing: 50, - enchanting: 60, - alchemy: 50, - carpentry: 50, - runecrafting: 25, - dungeons: 50, - social: 25, - hotm: 10, - garden: 15 - }, - dungeonXp: { - 1: 50, - 2: 75, - 3: 110, - 4: 160, - 5: 230, - 6: 330, - 7: 470, - 8: 670, - 9: 950, - 10: 1340, - 11: 1890, - 12: 2665, - 13: 3760, - 14: 5260, - 15: 7380, - 16: 10300, - 17: 14400, - 18: 20000, - 19: 27600, - 20: 38000, - 21: 52500, - 22: 71500, - 23: 97000, - 24: 132000, - 25: 180000, - 26: 243000, - 27: 328000, - 28: 445000, - 29: 600000, - 30: 800000, - 31: 1065000, - 32: 1410000, - 33: 1900000, - 34: 2500000, - 35: 3300000, - 36: 4300000, - 37: 5600000, - 38: 7200000, - 39: 9200000, - 40: 1.2e7, - 41: 1.5e7, - 42: 1.9e7, - 43: 2.4e7, - 44: 3e7, - 45: 3.8e7, - 46: 4.8e7, - 47: 6e7, - 48: 7.5e7, - 49: 9.3e7, - 50: 1.1625e8, - 55: 1e9 - }, - hotmXp: { - 1: 0, - 2: 3000, - 3: 9000, - 4: 25000, - 5: 60000, - 6: 100000, - 7: 150000, - 8: 210000, - 9: 290000, - 10: 400000 - }, - socialXp: { - 1: 50, - 2: 100, - 3: 150, - 4: 250, - 5: 500, - 6: 750, - 7: 1000, - 8: 1250, - 9: 1500, - 10: 2000, - 11: 2500, - 12: 3000, - 13: 3750, - 14: 4500, - 15: 6000, - 16: 8000, - 17: 10000, - 18: 12500, - 19: 15000, - 20: 20000, - 21: 25000, - 22: 30000, - 23: 35000, - 24: 40000, - 25: 50000 - }, - garden: { - 1: 0, - 2: 70, - 3: 70, - 4: 140, - 5: 240, - 6: 600, - 7: 1500, - 8: 2000, - 9: 2500, - 10: 3000, - 11: 10000, - 12: 10000, - 13: 10000, - 14: 10000, - 15: 10000 - }, - wheat: { - 1: 30, - 2: 50, - 3: 80, - 4: 170, - 5: 330, - 6: 670, - 7: 1330, - 8: 2500, - 9: 3500, - 10: 5000, - 11: 6500, - 12: 8000, - 13: 10000, - 14: 20000, - 15: 35000, - 16: 50000, - 17: 75000, - 18: 100000, - 19: 175000, - 20: 250000, - 21: 350000, - 22: 500000, - 23: 750000, - 24: 1000000, - 25: 1300000, - 26: 1600000, - 27: 2000000, - 28: 2300000, - 29: 2600000, - 30: 3000000, - 31: 3000000, - 32: 3000000, - 33: 3000000, - 34: 3000000, - 35: 3000000, - 36: 3000000, - 37: 3000000, - 38: 3000000, - 39: 3000000, - 40: 3000000, - 41: 3000000, - 42: 3000000, - 43: 3000000, - 44: 3000000, - 45: 3000000, - 46: 3000000 - }, - carrot: { - 1: 100, - 2: 150, - 3: 250, - 4: 500, - 5: 1500, - 6: 2500, - 7: 5000, - 8: 7500, - 9: 10000, - 10: 15000, - 11: 20000, - 12: 25000, - 13: 40000, - 14: 70000, - 15: 100000, - 16: 200000, - 17: 250000, - 18: 250000, - 19: 500000, - 20: 750000, - 21: 1000000, - 22: 1500000, - 23: 2000000, - 24: 3000000, - 25: 4000000, - 26: 5000000, - 27: 6000000, - 28: 7000000, - 29: 8000000, - 30: 9000000, - 31: 10000000, - 32: 10000000, - 33: 10000000, - 34: 10000000, - 35: 10000000, - 36: 10000000, - 37: 10000000, - 38: 10000000, - 39: 10000000, - 40: 10000000, - 41: 10000000, - 42: 10000000, - 43: 10000000, - 44: 10000000, - 45: 10000000, - 46: 10000000 - }, - potato: { - 1: 100, - 2: 150, - 3: 250, - 4: 500, - 5: 1500, - 6: 2500, - 7: 5000, - 8: 7500, - 9: 10000, - 10: 15000, - 11: 20000, - 12: 25000, - 13: 40000, - 14: 70000, - 15: 100000, - 16: 200000, - 17: 250000, - 18: 250000, - 19: 500000, - 20: 750000, - 21: 1000000, - 22: 1500000, - 23: 2000000, - 24: 3000000, - 25: 4000000, - 26: 5000000, - 27: 6000000, - 28: 7000000, - 29: 8000000, - 30: 9000000, - 31: 10000000, - 32: 10000000, - 33: 10000000, - 34: 10000000, - 35: 10000000, - 36: 10000000, - 37: 10000000, - 38: 10000000, - 39: 10000000, - 40: 10000000, - 41: 10000000, - 42: 10000000, - 43: 10000000, - 44: 10000000, - 45: 10000000, - 46: 10000000 - }, - melon: { - 1: 150, - 2: 250, - 3: 400, - 4: 850, - 5: 1650, - 6: 3350, - 7: 6650, - 8: 12500, - 9: 17500, - 10: 25000, - 11: 32500, - 12: 40000, - 13: 50000, - 14: 100000, - 15: 175000, - 16: 250000, - 17: 375000, - 18: 500000, - 19: 875000, - 20: 1250000, - 21: 1750000, - 22: 2500000, - 23: 3750000, - 24: 5000000, - 25: 6500000, - 26: 8000000, - 27: 10000000, - 28: 11500000, - 29: 13000000, - 30: 15000000, - 31: 15000000, - 32: 15000000, - 33: 15000000, - 34: 15000000, - 35: 15000000, - 36: 15000000, - 37: 15000000, - 38: 15000000, - 39: 15000000, - 40: 15000000, - 41: 15000000, - 42: 15000000, - 43: 15000000, - 44: 15000000, - 45: 15000000, - 46: 15000000 - }, - pumpkin: { - 1: 30, - 2: 50, - 3: 80, - 4: 170, - 5: 330, - 6: 670, - 7: 1330, - 8: 2500, - 9: 3500, - 10: 5000, - 11: 6500, - 12: 8000, - 13: 10000, - 14: 20000, - 15: 35000, - 16: 50000, - 17: 75000, - 18: 100000, - 19: 175000, - 20: 250000, - 21: 350000, - 22: 500000, - 23: 750000, - 24: 1000000, - 25: 1300000, - 26: 1600000, - 27: 2000000, - 28: 2300000, - 29: 2600000, - 30: 3000000, - 31: 3000000, - 32: 3000000, - 33: 3000000, - 34: 3000000, - 35: 3000000, - 36: 3000000, - 37: 3000000, - 38: 3000000, - 39: 3000000, - 40: 3000000, - 41: 3000000, - 42: 3000000, - 43: 3000000, - 44: 3000000, - 45: 3000000, - 46: 3000000 - }, - sugarCane: { - 1: 60, - 2: 100, - 3: 160, - 4: 340, - 5: 660, - 6: 1340, - 7: 2660, - 8: 5000, - 9: 7000, - 10: 10000, - 11: 13000, - 12: 16000, - 13: 20000, - 14: 40000, - 15: 70000, - 16: 100000, - 17: 150000, - 18: 200000, - 19: 350000, - 20: 500000, - 21: 700000, - 22: 1000000, - 23: 1500000, - 24: 2000000, - 25: 2600000, - 26: 3200000, - 27: 4000000, - 28: 4600000, - 29: 5200000, - 30: 6000000, - 31: 6000000, - 32: 6000000, - 33: 6000000, - 34: 6000000, - 35: 6000000, - 36: 6000000, - 37: 6000000, - 38: 6000000, - 39: 6000000, - 40: 6000000, - 41: 6000000, - 42: 6000000, - 43: 6000000, - 44: 6000000, - 45: 6000000, - 46: 6000000 - }, - cocoaBeans: { - 1: 90, - 2: 150, - 3: 250, - 4: 500, - 5: 1000, - 6: 2000, - 7: 4000, - 8: 7500, - 9: 10000, - 10: 15000, - 11: 20000, - 12: 25000, - 13: 30000, - 14: 50000, - 15: 100000, - 16: 150000, - 17: 200000, - 18: 300000, - 19: 500000, - 20: 750000, - 21: 1000000, - 22: 1500000, - 23: 2000000, - 24: 3000000, - 25: 4000000, - 26: 5000000, - 27: 6000000, - 28: 7000000, - 29: 8000000, - 30: 9000000, - 31: 9000000, - 32: 9000000, - 33: 9000000, - 34: 9000000, - 35: 9000000, - 36: 9000000, - 37: 9000000, - 38: 9000000, - 39: 9000000, - 40: 9000000, - 41: 9000000, - 42: 9000000, - 43: 9000000, - 44: 9000000, - 45: 9000000, - 46: 9000000 - }, - cactus: { - 1: 60, - 2: 100, - 3: 160, - 4: 340, - 5: 660, - 6: 1340, - 7: 2660, - 8: 5000, - 9: 7000, - 10: 10000, - 11: 13000, - 12: 16000, - 13: 20000, - 14: 40000, - 15: 70000, - 16: 100000, - 17: 150000, - 18: 200000, - 19: 350000, - 20: 500000, - 21: 700000, - 22: 1000000, - 23: 1500000, - 24: 2000000, - 25: 2600000, - 26: 3200000, - 27: 4000000, - 28: 4600000, - 29: 5200000, - 30: 6000000, - 31: 6000000, - 32: 6000000, - 33: 6000000, - 34: 6000000, - 35: 6000000, - 36: 6000000, - 37: 6000000, - 38: 6000000, - 39: 6000000, - 40: 6000000, - 41: 6000000, - 42: 6000000, - 43: 6000000, - 44: 6000000, - 45: 6000000, - 46: 6000000 - }, - mushroom: { - 1: 30, - 2: 50, - 3: 80, - 4: 170, - 5: 330, - 6: 670, - 7: 1330, - 8: 2500, - 9: 3500, - 10: 5000, - 11: 6500, - 12: 8000, - 13: 10000, - 14: 20000, - 15: 35000, - 16: 50000, - 17: 75000, - 18: 100000, - 19: 175000, - 20: 250000, - 21: 350000, - 22: 500000, - 23: 750000, - 24: 1000000, - 25: 1300000, - 26: 1600000, - 27: 2000000, - 28: 2300000, - 29: 2600000, - 30: 3000000, - 31: 3000000, - 32: 3000000, - 33: 3000000, - 34: 3000000, - 35: 3000000, - 36: 3000000, - 37: 3000000, - 38: 3000000, - 39: 3000000, - 40: 3000000, - 41: 3000000, - 42: 3000000, - 43: 3000000, - 44: 3000000, - 45: 3000000, - 46: 3000000 - }, - netherWart: { - 1: 90, - 2: 150, - 3: 250, - 4: 500, - 5: 1000, - 6: 2000, - 7: 4000, - 8: 7500, - 9: 10000, - 10: 15000, - 11: 20000, - 12: 25000, - 13: 30000, - 14: 50000, - 15: 100000, - 16: 150000, - 17: 200000, - 18: 300000, - 19: 500000, - 20: 750000, - 21: 1000000, - 22: 1500000, - 23: 2000000, - 24: 3000000, - 25: 4000000, - 26: 5000000, - 27: 6000000, - 28: 7000000, - 29: 8000000, - 30: 9000000, - 31: 9000000, - 32: 9000000, - 33: 9000000, - 34: 9000000, - 35: 9000000, - 36: 9000000, - 37: 9000000, - 38: 9000000, - 39: 9000000, - 40: 9000000, - 41: 9000000, - 42: 9000000, - 43: 9000000, - 44: 9000000, - 45: 9000000, - 46: 9000000 - }, - petScore: { - COMMON: 1, - UNCOMMON: 2, - RARE: 3, - EPIC: 4, - LEGENDARY: 5, - MYTHIC: 6 - }, - petRarityOffset: { - COMMON: 0, - UNCOMMON: 6, - RARE: 11, - EPIC: 16, - LEGENDARY: 20, - MYTHIC: 20 - }, - petLevels: [ - 100, 110, 120, 130, 145, 160, 175, 190, 210, 230, 250, 275, 300, 330, 360, 400, 440, 490, 540, 600, 660, 730, 800, - 880, 960, 1050, 1150, 1260, 1380, 1510, 1650, 1800, 1960, 2130, 2310, 2500, 2700, 2920, 3160, 3420, 3700, 4000, - 4350, 4750, 5200, 5700, 6300, 7000, 7800, 8700, 9700, 10800, 12000, 13300, 14700, 16200, 17800, 19500, 21300, 23200, - 25200, 27400, 29800, 32400, 35200, 38200, 41400, 44800, 48400, 52200, 56200, 60400, 64800, 69400, 74200, 79200, - 84700, 90700, 97200, 104200, 111700, 119700, 128200, 137200, 146700, 156700, 167700, 179700, 192700, 206700, 221700, - 237700, 254700, 272700, 291700, 311700, 333700, 357700, 383700, 411700, 441700, 476700, 516700, 561700, 611700, - 666700, 726700, 791700, 861700, 936700, 1016700, 1101700, 1191700, 1286700, 1386700, 1496700, 1616700, 1746700, - 1886700, 0, 5555, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, - 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700, 1886700 - ], - leaderboardNames: { - ARENA: 'ARENA', - COPS_AND_CRIMS: 'MCGO', - WARLORDS: 'BATTLEGROUND', - BLITZ_SURVIVAL_GAMES: 'SURVIVAL_GAMES', - UHC: 'UHC', - WALLS: 'WALLS', - PROTOTYPE: 'PROTOTYPE', - PAINTBALL: 'PAINTBALL', - SKYWARS: 'SKYWARS', - MURDER_MYSTERY: 'MURDER_MYSTERY', - SMASH_HEROES: 'SUPER_SMASH', - DUELS: 'DUELS', - SPEED_UHC: 'SPEED_UHC', - TNTGAMES: 'TNTGAMES', - BEDWARS: 'BEDWARS', - TURBO_KART_RACERS: 'GINGERBREAD', - BUILD_BATTLE: 'BUILD_BATTLE', - ARCADE: 'ARCADE', - SKYCLASH: 'SKYCLASH', - QUAKECRAFT: 'QUAKECRAFT', - CRAZY_WALLS: 'TRUE_COMBAT', - MEGA_WALLS: 'WALLS3', - VAMPIREZ: 'VAMPIREZ' - }, - MiniGamesString: { - QUAKECRAFT: 'Quakecraft', - WALLS: 'Walls', - PAINTBALL: 'Paintball', - SURVIVAL_GAMES: 'Blitz Survival Games', - TNTGAMES: 'The TNT Games', - VAMPIREZ: 'VampireZ', - WALLS3: 'Mega Walls', - ARCADE: 'Arcade', - ARENA: 'Arena Brawl', - MCGO: 'Cops and Crims', - UHC: 'UHC Champions', - BATTLEGROUND: 'Warlords', - SUPER_SMASH: 'Smash Heroes', - GINGERBREAD: 'Turbo Kart Racers', - HOUSING: 'Housing', - SKYWARS: 'SkyWars', - TRUE_COMBAT: 'Crazy Walls', - SPEED_UHC: 'Speed UHC', - SKYCLASH: 'SkyClash', - LEGACY: 'Classic Games', - PROTOTYPE: 'Prototype', - BEDWARS: 'BedWars', - MURDER_MYSTERY: 'Murder Mystery', - BUILD_BATTLE: 'Build Battle', - DUELS: 'Duels', - PIT: 'The Pit', - SKYBLOCK: 'SkyBlock', - REPLAY: 'Replay', - LIMBO: 'Limbo', - IDLE: 'Idle', - QUEUE: 'Queue', - MAIN_LOBBY: 'Main Lobby', - TOURNAMENT_LOBBY: 'Tournament Lobby', - WOOL_GAMES: 'Wool Wars' - }, - SkyWarsPrestigeIcons: { - /* eslint-disable camelcase */ - default: '⋆', - angel_1: '★', - angel_2: '☆', - angel_3: '⁕', - angel_4: '✶', - angel_5: '✳', - angel_6: '✴', - angel_7: '✷', - angel_8: '❋', - angel_9: '✼', - angel_10: '❂', - angel_11: '❁', - angel_12: '☬', - iron_prestige: '✙', - gold_prestige: '❤️', - diamond_prestige: '☠', - emerald_prestige: '✦', - sapphire_prestige: '✌', - ruby_prestige: '❦', - crystal_prestige: '✵', - opal_prestige: '❣', - amethyst_prestige: '☯', - rainbow_prestige: '✺', - mythic_prestige: 'ಠ_ಠ', - favor_of_the_angel_prestige: '⚔' - /* eslint-enable camelcase */ - }, - games: [ - { name: 'Quake Craft', code: 'QUAKECRAFT', id: 2 }, - { name: 'Walls', code: 'WALLS', id: 3 }, - { name: 'Paintball', code: 'PAINTBALL', id: 4 }, - { name: 'Blitz Survival Games', code: 'SURVIVAL_GAMES', id: 5 }, - { name: 'The TNT Games', code: 'TNTGAMES', id: 6 }, - { name: 'VampireZ', code: 'VAMPIREZ', id: 7 }, - { name: 'Mega Walls', code: 'WALLS3', id: 13 }, - { name: 'Arcade', code: 'ARCADE', id: 14 }, - { name: 'Arena Brawl', code: 'ARENA', id: 17 }, - { name: 'UHC Champions', code: 'UHC', id: 20 }, - { name: 'Cops and Crims', code: 'MCGO', id: 21 }, - { name: 'Warlords', code: 'BATTLEGROUND', id: 23 }, - { name: 'Smash Heroes', code: 'SUPER_SMASH', id: 24 }, - { name: 'Turbo Kart Racers', code: 'GINGERBREAD', id: 25 }, - { name: 'Housing', code: 'HOUSING', id: 26 }, - { name: 'SkyWars', code: 'SKYWARS', id: 51 }, - { name: 'Crazy Walls', code: 'TRUE_COMBAT', id: 52 }, - { name: 'Speed UHC', code: 'SPEED_UHC', id: 54 }, - { name: 'SkyClash', code: 'SKYCLASH', id: 55 }, - { name: 'Classic Games', code: 'LEGACY', id: 56 }, - { name: 'Prototype', code: 'PROTOTYPE', id: 57 }, - { name: 'Bed Wars', code: 'BEDWARS', id: 58 }, - { name: 'Murder Mystery', code: 'MURDER_MYSTERY', id: 59 }, - { name: 'Build Battle', code: 'BUILD_BATTLE', id: 60 }, - { name: 'Duels', code: 'DUELS', id: 61 }, - { name: 'SkyBlock', code: 'SKYBLOCK', id: 63 }, - { name: 'The Pit', code: 'PIT', id: 64 }, - { name: 'Replay', code: 'REPLAY', id: 65 }, - { name: 'SMP', code: 'SMP', id: 67 }, - { name: 'Wool Wars', code: 'WOOL_GAMES', id: 68 }, - { name: 'Limbo', code: 'LIMBO', id: -2 }, - { name: 'Queue', code: 'QUEUE', id: -3 }, - { name: 'Main Lobby', code: 'MAIN_LOBBY', id: -4 }, - { name: 'Tournament Lobby', code: 'TOURNAMENT_LOBBY', id: -5 }, - { name: 'Idle', code: 'IDLE', id: -6 } - ], - - /* eslint-disable camelcase */ - bestiary: { - dynamic: { - name: 'Private Island', - - mobs: [ - { - name: 'Bat', - cap: 200, - - mobs: ['forest_island_bat_3'], - bracket: 1 - }, - { - name: 'Creeper', - cap: 200, - - mobs: ['creeper_1'], - bracket: 1 - }, - { - name: 'Enderman', - cap: 200, - - mobs: [ - 'enderman_1', - 'enderman_2', - 'enderman_3', - 'enderman_4', - 'enderman_5', - 'enderman_6', - 'enderman_7', - 'enderman_8', - 'enderman_9', - 'enderman_10', - 'enderman_11', - 'enderman_12', - 'enderman_13', - 'enderman_14', - 'enderman_15' - ], - bracket: 1 - }, - { - name: 'Skeleton', - cap: 200, - - mobs: [ - 'skeleton_1', - 'skeleton_2', - 'skeleton_3', - 'skeleton_4', - 'skeleton_5', - 'skeleton_6', - 'skeleton_7', - 'skeleton_8', - 'skeleton_9', - 'skeleton_10', - 'skeleton_11', - 'skeleton_12', - 'skeleton_13', - 'skeleton_14', - 'skeleton_15' - ], - bracket: 1 - }, - { - name: 'Slime', - cap: 200, - - mobs: [ - 'slime_1', - 'slime_2', - 'slime_3', - 'slime_4', - 'slime_5', - 'slime_6', - 'slime_7', - 'slime_8', - 'slime_9', - 'slime_10', - 'slime_11', - 'slime_12', - 'slime_13', - 'slime_14', - 'slime_15' - ], - bracket: 1 - }, - { - name: 'Spider', - cap: 200, - - mobs: [ - 'spider_1', - 'spider_2', - 'spider_3', - 'spider_4', - 'spider_5', - 'spider_6', - 'spider_7', - 'spider_8', - 'spider_9', - 'spider_10', - 'spider_11', - 'spider_12', - 'spider_13', - 'spider_14', - 'spider_15' - ], - bracket: 1 - }, - { - name: 'Witch', - cap: 200, - - mobs: [ - 'witch_1', - 'witch_2', - 'witch_3', - 'witch_4', - 'witch_5', - 'witch_6', - 'witch_7', - 'witch_8', - 'witch_9', - 'witch_10', - 'witch_11', - 'witch_12', - 'witch_13', - 'witch_14', - 'witch_15' - ], - bracket: 1 - }, - { - name: 'Zombie', - cap: 200, - - mobs: [ - 'zombie_1', - 'zombie_2', - 'zombie_3', - 'zombie_4', - 'zombie_5', - 'zombie_6', - 'zombie_7', - 'zombie_8', - 'zombie_9', - 'zombie_10', - 'zombie_11', - 'zombie_12', - 'zombie_13', - 'zombie_14', - 'zombie_15' - ], - bracket: 1 - } - ] - }, - hub: { - name: 'Hub', - - mobs: [ - { - name: 'Crypt Ghoul', - cap: 40000, - - mobs: ['unburried_zombie_30'], - bracket: 1 - }, - { - name: 'Golden Ghoul', - cap: 4000, - - mobs: ['unburried_zombie_60'], - bracket: 3 - }, - { - name: 'Graveyard Zombie', - cap: 200, - - mobs: ['graveyard_zombie_1'], - bracket: 1 - }, - { - name: 'Old Wolf', - cap: 4000, - - mobs: ['old_wolf_50'], - bracket: 3 - }, - { - name: 'Wolf', - cap: 40000, - - mobs: ['ruin_wolf_15'], - bracket: 1 - }, - { - name: 'Zombie Villager', - cap: 1000, - - mobs: ['zombie_villager_1'], - bracket: 4 - } - ] - }, - farming_1: { - name: 'The Farming Islands', - - mobs: [ - { - name: 'Chicken', - cap: 200, - - mobs: ['farming_chicken_1'], - bracket: 1 - }, - { - name: 'Cow', - cap: 200, - - mobs: ['farming_cow_1'], - bracket: 1 - }, - { - name: 'Mushroom Cow', - cap: 200, - - mobs: ['mushroom_cow_1'], - bracket: 1 - }, - { - name: 'Pig', - cap: 200, - - mobs: ['farming_pig_1'], - bracket: 1 - }, - { - name: 'Rabbit', - cap: 200, - - mobs: ['farming_rabbit_1'], - bracket: 1 - }, - { - name: 'Sheep', - cap: 200, - - mobs: ['farming_sheep_1'], - bracket: 1 - } - ] - }, - garden: { - name: 'Garden', - - mobs: [ - { - name: 'Beetle', - cap: 250, - mobs: ['pest_beetle_1'], - bracket: 6 - }, - { - name: 'Cricket', - cap: 250, - mobs: ['pest_cricket_1'], - bracket: 6 - }, - { - name: 'Earthworm', - cap: 250, - mobs: ['pest_worm_1'], - bracket: 6 - }, - { - name: 'Field Mice', - cap: 100, - mobs: ['pest_mouse_1'], - bracket: 7 - }, - { - name: 'Fly', - cap: 250, - mobs: ['pest_fly_1'], - bracket: 6 - }, - { - name: 'Locust', - cap: 250, - mobs: ['pest_locust_1'], - bracket: 6 - }, - { - name: 'Mite', - cap: 250, - mobs: ['pest_mite_1'], - bracket: 6 - }, - { - name: 'Mosquito', - cap: 250, - mobs: ['pest_mosquito_1'], - bracket: 6 - }, - { - name: 'Moth', - cap: 250, - mobs: ['pest_moth_1'], - bracket: 6 - }, - { - name: 'Rat', - cap: 250, - mobs: ['pest_rat_1'], - bracket: 6 - }, - { - name: 'Slug', - cap: 250, - mobs: ['pest_slug_1'], - bracket: 6 - } - ] - }, - combat_1: { - name: 'Spiders Den', - - mobs: [ - { - name: 'Arachne', - cap: 500, - - mobs: ['arachne_500', 'arachne_300'], - bracket: 7 - }, - { - name: "Arachne's Brood", - cap: 1000, - - mobs: ['arachne_brood_200', 'arachne_brood_100'], - bracket: 4 - }, - { - name: "Arachne's Keeper", - cap: 400, - - mobs: ['arachne_keeper_100'], - bracket: 5 - }, - { - name: 'Brood Mother', - cap: 400, - - mobs: ['brood_mother_spider_12'], - bracket: 5 - }, - { - name: 'Dasher Spider', - cap: 10000, - - mobs: ['dasher_spider_50', 'dasher_spider_45', 'dasher_spider_42', 'dasher_spider_4', 'dasher_spider_6'], - bracket: 2 - }, - { - name: 'Gravel Skeleton', - cap: 4000, - - mobs: ['respawning_skeleton_2'], - bracket: 3 - }, - { - name: 'Rain Slime', - cap: 1000, - - mobs: ['random_slime_8', 'random_slime_20'], - bracket: 4 - }, - { - name: 'Silverfish', - cap: 10000, - - mobs: [ - 'jockey_shot_silverfish_3', - 'splitter_spider_silverfish_2', - 'splitter_spider_silverfish_45', - 'splitter_spider_silverfish_42', - 'splitter_spider_silverfish_50', - 'jockey_shot_silverfish_42' - ], - bracket: 2 - }, - { - name: 'Spider Jockey', - cap: 4000, - - mobs: ['spider_jockey_3', 'spider_jockey_42', 'spider_jockey_5'], - bracket: 3 - }, - { - name: 'Splitter Spider', - cap: 10000, - - mobs: [ - 'splitter_spider_2', - 'splitter_spider_45', - 'splitter_spider_42', - 'splitter_spider_50', - 'splitter_spider_4', - 'splitter_spider_6' - ], - bracket: 2 - }, - { - name: 'Voracious Spider', - cap: 10000, - - mobs: ['voracious_spider_50', 'voracious_spider_42', 'voracious_spider_45', 'voracious_spider_10'], - bracket: 2 - }, - { - name: 'Weaver Spider', - cap: 10000, - - mobs: [ - 'weaver_spider_3', - 'weaver_spider_4', - 'weaver_spider_5', - 'weaver_spider_6', - 'weaver_spider_42', - 'weaver_spider_45', - 'weaver_spider_50' - ], - bracket: 2 - } - ] - }, - combat_3: { - name: 'The End', - - mobs: [ - { - name: 'Dragon', - cap: 1000, - - mobs: [ - 'protector_dragon_100', - 'old_dragon_100', - 'young_dragon_100', - 'wise_dragon_100', - 'superior_dragon_100', - 'strong_dragon_100', - 'unstable_dragon_100' - ], - bracket: 5 - }, - { - name: 'Enderman', - cap: 25000, - - mobs: ['enderman_50', 'enderman_45', 'enderman_42'], - bracket: 4 - }, - { - name: 'Endermite', - cap: 10000, - - mobs: ['nest_endermite_50', 'endermite_37', 'endermite_40'], - bracket: 5 - }, - { - name: 'Endstone Protector', - cap: 500, - - mobs: ['corrupted_protector_100'], - bracket: 7 - }, - { - name: 'Obsidian Defender', - cap: 10000, - - mobs: ['obsidian_wither_55'], - bracket: 5 - }, - { - name: 'Voidling Extremist', - cap: 4000, - - mobs: ['voidling_extremist_100'], - bracket: 3 - }, - { - name: 'Voidling Fanatic', - cap: 25000, - - mobs: ['voidling_fanatic_85'], - bracket: 4 - }, - { - name: 'Watcher', - cap: 10000, - - mobs: ['watcher_55'], - bracket: 5 - }, - { - name: 'Zealot', - cap: 25000, - - mobs: ['zealot_bruiser_100', 'zealot_enderman_55'], - bracket: 4 - } - ] - }, - crimson_isle: { - name: 'Crimson Isle', - - mobs: [ - { - name: 'Ashfang', - cap: 500, - - mobs: ['ashfang_200'], - bracket: 7 - }, - { - name: 'Barbarian Duke X', - cap: 500, - - mobs: ['barbarian_duke_x_200'], - bracket: 7 - }, - { - name: 'Bladesoul', - cap: 500, - - mobs: ['bladesoul_200'], - bracket: 7 - }, - { - name: 'Blaze', - cap: 3000, - - mobs: ['blaze_25', 'blaze_70', 'bezal_80', 'mutated_blaze_70'], - bracket: 4 - }, - { - name: 'Flaming Spider', - cap: 10000, - - mobs: ['flaming_spider_80'], - bracket: 3 - }, - { - name: 'Flare', - cap: 100000, - - mobs: ['flare_90'], - bracket: 1 - }, - { - name: 'Ghast', - cap: 3000, - - mobs: ['ghast_85', 'dive_ghast_90'], - bracket: 4 - }, - { - name: 'Kada Knight', - cap: 3000, - - mobs: ['kada_knight_90'], - bracket: 4 - }, - { - name: 'Mage Outlaw', - cap: 500, - - mobs: ['mage_outlaw_200'], - bracket: 7 - }, - { - name: 'Magma Boss', - cap: 500, - - mobs: ['magma_boss_500'], - bracket: 7 - }, - { - name: 'Magma Cube', - cap: 10000, - - mobs: ['pack_magma_cube_90', 'magma_cube_75', 'fireball_magma_cube_75'], - bracket: 3 - }, - { - name: 'Magma Cube Rider', - cap: 3000, - - mobs: ['magma_cube_rider_90'], - bracket: 4 - }, - { - name: 'Matcho', - cap: 400, - - mobs: ['matcho_100'], - bracket: 5 - }, - { - name: 'Millenia-Aged Blaze', - cap: 4000, - - mobs: ['old_blaze_110'], - bracket: 3 - }, - { - name: 'Mushroom Bull', - cap: 10000, - - mobs: ['charging_mushroom_cow_80'], - bracket: 3 - }, - { - name: 'Smoldering Blaze', - cap: 25000, - - mobs: ['smoldering_blaze_95'], - bracket: 2 - }, - { - name: 'Tentacle', - cap: 1000, - - mobs: ['hellwisp_100'], - bracket: 5 - }, - { - name: 'Vanquisher', - cap: 1000, - - mobs: ['vanquisher_100'], - bracket: 5 - }, - { - name: 'Wither Skeleton', - cap: 3000, - - mobs: ['wither_skeleton_70'], - bracket: 4 - }, - { - name: 'Wither Spectre', - cap: 10000, - - mobs: ['wither_spectre_70'], - bracket: 3 - } - ] - }, - mining_2: { - name: 'Deep Caverns', - - mobs: [ - { - name: 'Emerald Slime', - cap: 3000, - - mobs: ['emerald_slime_5', 'emerald_slime_10'], - bracket: 1 - }, - { - name: 'Lapis Zombie', - cap: 3000, - - mobs: ['lapis_zombie_7'], - bracket: 1 - }, - { - name: 'Miner Skeleton', - cap: 3000, - - mobs: ['diamond_skeleton_15', 'diamond_skeleton_20'], - bracket: 1 - }, - { - name: 'Miner Zombie', - cap: 3000, - - mobs: ['diamond_zombie_15', 'diamond_zombie_20'], - bracket: 1 - }, - { - name: 'Redstone Pigman', - cap: 3000, - - mobs: ['redstone_pigman_10'], - bracket: 1 - }, - { - name: 'Sneaky Creeper', - cap: 300, - - mobs: ['invisible_creeper_3'], - bracket: 3 - } - ] - }, - mining_3: { - name: 'Dwarven Mines', - - mobs: [ - { - name: 'Diamond Goblin', - cap: 100, - mobs: ['goblin_500'], - bracket: 7 - }, - { - name: 'Ghost', - cap: 100000, - - mobs: ['caverns_ghost_250'], - bracket: 3 - }, - { - name: 'Glacite Bowman', - cap: 1000, - - mobs: ['glacite_bowman_165'], - bracket: 4 - }, - { - name: 'Glacite Caver', - cap: 1000, - - mobs: ['glacite_caver_200'], - bracket: 4 - }, - { - name: 'Glacite Mage', - cap: 1000, - - mobs: ['glacite_mage_155'], - bracket: 4 - }, - { - name: 'Glacite Mutt', - cap: 1000, - - mobs: ['glacite_mutt_180'], - bracket: 4 - }, - { - name: 'Glacite Walker', - cap: 10000, - - mobs: ['ice_walker_45'], - bracket: 2 - }, - { - name: 'Goblin', - cap: 25000, - - mobs: [ - 'goblin_weakling_melee_25', - 'goblin_weakling_melee_40', - 'goblin_weakling_bow_25', - 'goblin_weakling_bow_40', - 'goblin_creepertamer_100', - 'goblin_pitfighter_70', - 'goblin_knife_thrower_25', - 'goblin_knife_thrower_40', - 'goblin_flamethrower_100', - 'goblin_murderlover_200' - ], - bracket: 2 - }, - { - name: 'Goblin Raiders', - cap: 1000, - - mobs: [ - 'goblin_weakling_melee_5', - 'goblin_weakling_bow_5', - 'goblin_creepertamer_90', - 'goblin_creeper_20', - 'goblin_battler_60', - 'goblin_murderlover_150', - 'goblin_golem_150' - ], - bracket: 4 - }, - { - name: 'Golden Goblin', - cap: 400, - - mobs: ['goblin_50'], - bracket: 5 - }, - { - name: 'Powder Ghast', - cap: 200, - - mobs: ['powder_ghast_1'], - bracket: 1 - }, - { - name: 'Star Sentry', - cap: 1000, - - mobs: ['crystal_sentry_50'], - bracket: 4 - }, - { - name: 'Treasure Hoarder', - cap: 1000, - - mobs: ['treasure_hoarder_70'], - bracket: 4 - } - ] - }, - crystal_hollows: { - name: 'Crystal Hollows', - - mobs: [ - { - name: 'Automaton', - cap: 10000, - - mobs: ['automaton_100', 'automaton_150'], - bracket: 2 - }, - { - name: 'Bal', - cap: 250, - - mobs: ['bal_boss_100'], - bracket: 6 - }, - { - name: 'Boss Corleone', - cap: 100, - - mobs: ['team_treasurite_corleone_200'], - bracket: 7 - }, - { - name: 'Butterfly', - cap: 1000, - - mobs: ['butterfly_100'], - bracket: 4 - }, - { - name: 'Grunt', - cap: 4000, - - mobs: [ - 'team_treasurite_grunt_50', - 'team_treasurite_viper_100', - 'team_treasurite_wendy_100', - 'team_treasurite_sebastian_100' - ], - bracket: 3 - }, - { - name: 'Key Guardian', - cap: 250, - - mobs: ['key_guardian_100'], - bracket: 6 - }, - { - name: 'Sludge', - cap: 10000, - - mobs: ['sludge_5', 'sludge_10', 'sludge_100'], - bracket: 2 - }, - { - name: 'Thyst', - cap: 4000, - - mobs: ['thyst_20'], - bracket: 3 - }, - { - name: 'Worm', - cap: 400, - - mobs: ['worm_5', 'scatha_10'], - bracket: 5 - }, - { - name: 'Yog', - cap: 4000, - - mobs: ['yog_100'], - bracket: 3 - } - ] - }, - foraging_1: { - name: 'The Park', - - mobs: [ - { - name: 'Howling Spirit', - cap: 10000, - - mobs: ['howling_spirit_35'], - bracket: 2 - }, - { - name: 'Pack Spirit', - cap: 10000, - - mobs: ['pack_spirit_30'], - bracket: 2 - }, - { - name: 'Soul of the Alpha', - cap: 1000, - - mobs: ['soul_of_the_alpha_55'], - bracket: 4 - } - ] - }, - spooky_festival: { - name: 'Spooky Festival', - - mobs: [ - { - name: 'Crazy Witch', - cap: 750, - - mobs: ['batty_witch_60'], - bracket: 2 - }, - { - name: 'Headless Horseman', - cap: 500, - - mobs: ['horseman_horse_100'], - bracket: 7 - }, - { - name: 'Phantom Spirit', - cap: 750, - - mobs: ['phantom_spirit_35'], - bracket: 2 - }, - { - name: 'Scary Jerry', - cap: 750, - - mobs: ['scary_jerry_30'], - bracket: 2 - }, - { - name: 'Trick or Treater', - cap: 750, - - mobs: ['trick_or_treater_30'], - bracket: 2 - }, - { - name: 'Wither Gourd', - cap: 750, - - mobs: ['wither_gourd_40'], - bracket: 2 - }, - { - name: 'Wraith', - cap: 750, - - mobs: ['wraith_50'], - bracket: 2 - } - ] - }, - mythological_creatures: { - name: 'Mythological Creatures', - - mobs: [ - { - name: 'Gaia Construct', - cap: 3000, - - mobs: ['gaia_construct_140', 'gaia_construct_260'], - bracket: 4 - }, - { - name: 'Minos Champion', - cap: 1000, - - mobs: ['minos_champion_175', 'minos_champion_310'], - bracket: 5 - }, - { - name: 'Minos Hunter', - cap: 1000, - - mobs: ['minos_hunter_125', 'minos_hunter_15', 'minos_hunter_60'], - bracket: 5 - }, - { - name: 'Minos Inquisitor', - cap: 500, - - mobs: ['minos_inquisitor_750'], - bracket: 7 - }, - { - name: 'Minotaur', - cap: 3000, - - mobs: ['minotaur_45', 'minotaur_120', 'minotaur_210'], - bracket: 4 - }, - { - name: 'Siamese Lynx', - cap: 3000, - - mobs: ['siamese_lynx_25', 'siamese_lynx_85', 'siamese_lynx_155'], - bracket: 4 - } - ] - }, - jerry: { - name: 'Jerry', - - mobs: [ - { - name: 'Green Jerry', - cap: 75, - - mobs: ['mayor_jerry_green_1'], - bracket: 4 - }, - { - name: 'Blue Jerry', - cap: 30, - - mobs: ['mayor_jerry_blue_2'], - bracket: 5 - }, - { - name: 'Purple Jerry', - cap: 25, - - mobs: ['mayor_jerry_purple_3'], - bracket: 6 - }, - { - name: 'Golden Jerry', - cap: 20, - - mobs: ['mayor_jerry_golden_5'], - bracket: 7 - } - ] - }, - kuudra: { - name: 'Kuudra', - - mobs: [ - { - name: 'Blazing Golem', - cap: 300, - - mobs: [ - 'blazing_golem_100', - 'blazing_golem_200', - 'blazing_golem_300', - 'blazing_golem_400', - 'blazing_golem_500' - ], - bracket: 3 - }, - { - name: 'Blight', - cap: 10000, - - mobs: ['blight_100', 'blight_200', 'blight_300', 'blight_400', 'blight_500'], - bracket: 3 - }, - { - name: 'Dropship', - cap: 300, - - mobs: ['dropship_100', 'dropship_200', 'dropship_300', 'dropship_400', 'dropship_500'], - bracket: 3 - }, - { - name: 'Explosive Imp', - cap: 3000, - - mobs: [ - 'explosive_imp_100', - 'explosive_imp_200', - 'explosive_imp_300', - 'explosive_imp_400', - 'explosive_imp_500' - ], - bracket: 4 - }, - { - name: 'Inferno Magma Cube', - cap: 10000, - - mobs: [ - 'inferno_magma_cube_100', - 'inferno_magma_cube_200', - 'inferno_magma_cube_300', - 'inferno_magma_cube_400', - 'inferno_magma_cube_500' - ], - bracket: 3 - }, - { - name: 'Kuudra Berserker', - cap: 10000, - - mobs: [ - 'kuudra_berserker_100', - 'kuudra_berserker_200', - 'kuudra_berserker_300', - 'kuudra_berserker_400', - 'kuudra_berserker_500' - ], - bracket: 3 - }, - { - name: 'Kuudra Follower', - cap: 25000, - - mobs: [ - 'kuudra_follower_100', - 'kuudra_follower_200', - 'kuudra_follower_300', - 'kuudra_follower_400', - 'kuudra_follower_500' - ], - bracket: 2 - }, - { - name: 'Kuudra Knocker', - cap: 10000, - - mobs: [ - 'kuudra_knocker_100', - 'kuudra_knocker_200', - 'kuudra_knocker_300', - 'kuudra_knocker_400', - 'kuudra_knocker_500' - ], - bracket: 3 - }, - { - name: 'Kuudra Landmine', - cap: 10000, - - mobs: [ - 'kuudra_landmine_100', - 'kuudra_landmine_200', - 'kuudra_landmine_300', - 'kuudra_landmine_400', - 'kuudra_landmine_500' - ], - bracket: 3 - }, - { - name: 'Kuudra Slasher', - cap: 30, - - mobs: [ - 'kuudra_slasher_100', - 'kuudra_slasher_200', - 'kuudra_slasher_300', - 'kuudra_slasher_400', - 'kuudra_slasher_500' - ], - bracket: 5 - }, - { - name: 'Magma Follower', - cap: 30, - - mobs: [ - 'magma_follower_100', - 'magma_follower_200', - 'magma_follower_300', - 'magma_follower_400', - 'magma_follower_500' - ], - bracket: 5 - }, - { - name: 'Wandering Blaze', - cap: 3000, - - mobs: [ - 'wandering_blaze_100', - 'wandering_blaze_200', - 'wandering_blaze_300', - 'wandering_blaze_400', - 'wandering_blaze_500' - ], - bracket: 4 - }, - { - name: 'Wither Sentry', - cap: 75, - - mobs: [ - 'wither_sentry_100', - 'wither_sentry_200', - 'wither_sentry_300', - 'wither_sentry_400', - 'wither_sentry_500' - ], - bracket: 4 - } - ] - }, - fishing: { - fishing: { - name: 'Fishing', - - mobs: [ - { - name: 'Abyssal Miner', - cap: 250, - - mobs: ['zombie_miner_150'], - bracket: 6 - }, - { - name: 'Agarimoo', - cap: 4000, - - mobs: ['agarimoo_35'], - bracket: 3 - }, - { - name: 'Carrot King', - cap: 400, - - mobs: ['carrot_king_25'], - bracket: 5 - }, - { - name: 'Catfish', - cap: 1000, - - mobs: ['catfish_23'], - bracket: 4 - }, - { - name: 'Deep Sea Protector', - cap: 1000, - - mobs: ['deep_sea_protector_60'], - bracket: 4 - }, - { - name: 'Guardian Defender', - cap: 1000, - - mobs: ['guardian_defender_45'], - bracket: 4 - }, - { - name: 'Night Squid', - cap: 1000, - - mobs: ['night_squid_6'], - bracket: 4 - }, - { - name: 'Oasis Rabbit', - cap: 300, - - mobs: ['oasis_rabbit_10'], - bracket: 3 - }, - { - name: 'Oasis Sheep', - cap: 300, - - mobs: ['oasis_sheep_10'], - bracket: 3 - }, - { - name: 'Poisoned Water Worm', - cap: 1000, - - mobs: ['poisoned_water_worm_25'], - bracket: 4 - }, - { - name: 'Rider of the Deep', - cap: 4000, - - mobs: ['zombie_deep_20', 'chicken_deep_20'], - bracket: 3 - }, - { - name: 'Sea Archer', - cap: 4000, - - mobs: ['sea_archer_15'], - bracket: 3 - }, - { - name: 'Sea Guardian', - cap: 4000, - - mobs: ['sea_guardian_10'], - bracket: 3 - }, - { - name: 'Sea Leech', - cap: 1000, - - mobs: ['sea_leech_30'], - bracket: 4 - }, - { - name: 'Sea Walker', - cap: 4000, - - mobs: ['sea_walker_4'], - bracket: 3 - }, - { - name: 'Sea Witch', - cap: 4000, - - mobs: ['sea_witch_15'], - bracket: 3 - }, - { - name: 'Squid', - cap: 10000, - - mobs: ['pond_squid_1'], - bracket: 2 - }, - { - name: 'The Sea Emperor', - cap: 100, - - mobs: ['skeleton_emperor_150', 'guardian_emperor_150'], - bracket: 7 - }, - { - name: 'Water Hydra', - cap: 400, - - mobs: ['water_hydra_100'], - bracket: 5 - }, - { - name: 'Water Worm', - cap: 1000, - - mobs: ['water_worm_20'], - bracket: 4 - } - ] - }, - lava: { - name: 'Lava Fishing', - - mobs: [ - { - name: 'Fire Eel', - cap: 1000, - - mobs: ['fire_eel_240'], - bracket: 4 - }, - { - name: 'Flaming Worm', - cap: 4000, - - mobs: ['flaming_worm_50'], - bracket: 3 - }, - { - name: 'Lava Blaze', - cap: 1000, - - mobs: ['lava_blaze_100'], - bracket: 4 - }, - { - name: 'Lava Flame', - cap: 1000, - - mobs: ['lava_flame_230'], - bracket: 4 - }, - { - name: 'Lava Leech', - cap: 4000, - - mobs: ['lava_leech_220'], - bracket: 3 - }, - { - name: 'Lava Pigman', - cap: 1000, - - mobs: ['lava_pigman_100'], - bracket: 4 - }, - { - name: 'Lord Jawbus', - cap: 100, - - mobs: ['lord_jawbus_600'], - bracket: 7 - }, - { - name: 'Magma Slug', - cap: 10000, - - mobs: ['magma_slug_200'], - bracket: 2 - }, - { - name: 'Moogma', - cap: 4000, - - mobs: ['moogma_210'], - bracket: 3 - }, - { - name: 'Plhlegblast', - cap: 7, - - mobs: ['pond_squid_300'], - bracket: 7 - }, - { - name: 'Pyroclastic Worm', - cap: 1000, - - mobs: ['pyroclastic_worm_240'], - bracket: 4 - }, - { - name: 'Taurus', - cap: 1000, - - mobs: ['pig_rider_250'], - bracket: 4 - }, - { - name: 'Thunder', - cap: 400, - - mobs: ['thunder_400'], - bracket: 5 - } - ] - }, - spooky_festival: { - name: 'Spooky Festival Fishing', - - mobs: [ - { - name: 'Grim Reaper', - cap: 100, - - mobs: ['grim_reaper_190'], - bracket: 7 - }, - { - name: 'Nightmare', - cap: 1000, - - mobs: ['nightmare_24'], - bracket: 4 - }, - { - name: 'Phantom Fisher', - cap: 250, - - mobs: ['phantom_fisherman_160'], - bracket: 6 - }, - { - name: 'Scarecrow', - cap: 4000, - - mobs: ['scarecrow_9'], - bracket: 3 - }, - { - name: 'Werewolf', - cap: 1000, - - mobs: ['werewolf_50'], - bracket: 4 - } - ] - }, - fishing_festival: { - name: 'Fishing Festival', - - mobs: [ - { - name: 'Blue Shark', - cap: 1000, - - mobs: ['blue_shark_20'], - bracket: 4 - }, - { - name: 'Great White Shark', - cap: 400, - - mobs: ['great_white_shark_180'], - bracket: 5 - }, - { - name: 'Nurse Shark', - cap: 4000, - - mobs: ['nurse_shark_6'], - bracket: 3 - }, - { - name: 'Tiger Shark', - cap: 1000, - - mobs: ['tiger_shark_50'], - bracket: 4 - } - ] - }, - winter: { - name: 'Winter Fishing', - - mobs: [ - { - name: 'Frosty', - cap: 4000, - - mobs: ['frosty_the_snowman_13'], - bracket: 3 - }, - { - name: 'Frozen Steve', - cap: 4000, - - mobs: ['frozen_steve_7'], - bracket: 3 - }, - { - name: 'Grinch', - cap: 250, - - mobs: ['grinch_21'], - bracket: 6 - }, - { - name: 'Nutcracker', - cap: 400, - - mobs: ['nutcracker_50'], - bracket: 5 - }, - { - name: 'Reindrake', - cap: 100, - - mobs: ['reindrake_100'], - bracket: 7 - }, - { - name: 'Yeti', - cap: 250, - - mobs: ['yeti_175'], - bracket: 6 - } - ] - } - }, - catacombs: { - name: 'Catacombs', - - mobs: [ - { - name: 'Angry Archeologist', - cap: 3000, - - mobs: [ - 'diamond_guy_80', - 'diamond_guy_90', - 'diamond_guy_100', - 'diamond_guy_110', - 'diamond_guy_120', - 'diamond_guy_130', - 'diamond_guy_140', - 'diamond_guy_150', - 'diamond_guy_160', - 'diamond_guy_170', - 'master_diamond_guy_80', - 'master_diamond_guy_90', - 'master_diamond_guy_100', - 'master_diamond_guy_110', - 'master_diamond_guy_120', - 'master_diamond_guy_130', - 'master_diamond_guy_140', - 'master_diamond_guy_150', - 'master_diamond_guy_160', - 'master_diamond_guy_170' - ], - bracket: 7 - }, - { - name: 'Bat', - cap: 1000, - - mobs: ['dungeon_secret_bat_1'], - bracket: 4 - }, - { - name: 'Cellar Spider', - cap: 1000, - - mobs: [ - 'cellar_spider_45', - 'cellar_spider_65', - 'cellar_spider_75', - 'cellar_spider_85', - 'cellar_spider_95', - 'cellar_spider_105', - 'cellar_spider_115', - 'cellar_spider_125', - 'master_cellar_spider_45', - 'master_cellar_spider_65', - 'master_cellar_spider_75', - 'master_cellar_spider_85', - 'master_cellar_spider_95', - 'master_cellar_spider_105', - 'master_cellar_spider_115', - 'master_cellar_spider_125' - ], - bracket: 4 - }, - { - name: 'Crypt Dreadlord', - cap: 25000, - - mobs: [ - 'crypt_dreadlord_47', - 'crypt_dreadlord_67', - 'crypt_dreadlord_77', - 'crypt_dreadlord_87', - 'crypt_dreadlord_97', - 'crypt_dreadlord_107', - 'crypt_dreadlord_117', - 'crypt_dreadlord_127', - 'master_crypt_dreadlord_47', - 'master_crypt_dreadlord_67', - 'master_crypt_dreadlord_77', - 'master_crypt_dreadlord_87', - 'master_crypt_dreadlord_97', - 'master_crypt_dreadlord_107', - 'master_crypt_dreadlord_117', - 'master_crypt_dreadlord_127' - ], - bracket: 4 - }, - { - name: 'Crypt Lurker', - cap: 25000, - - mobs: [ - 'crypt_lurker_41', - 'crypt_lurker_61', - 'crypt_lurker_71', - 'crypt_lurker_81', - 'crypt_lurker_91', - 'crypt_lurker_101', - 'crypt_lurker_111', - 'crypt_lurker_121', - 'master_crypt_lurker_41', - 'master_crypt_lurker_61', - 'master_crypt_lurker_71', - 'master_crypt_lurker_81', - 'master_crypt_lurker_91', - 'master_crypt_lurker_101', - 'master_crypt_lurker_111', - 'master_crypt_lurker_121' - ], - bracket: 4 - }, - { - name: 'Crypt Souleater', - cap: 25000, - - mobs: [ - 'crypt_souleater_45', - 'crypt_souleater_65', - 'crypt_souleater_75', - 'crypt_souleater_85', - 'crypt_souleater_95', - 'crypt_souleater_105', - 'crypt_souleater_115', - 'crypt_souleater_125', - 'master_crypt_souleater_45', - 'master_crypt_souleater_65', - 'master_crypt_souleater_75', - 'master_crypt_souleater_85', - 'master_crypt_souleater_95', - 'master_crypt_souleater_105', - 'master_crypt_souleater_115', - 'master_crypt_souleater_125' - ], - bracket: 4 - }, - { - name: 'Fels', - cap: 10000, - - mobs: [ - 'tentaclees_90', - 'tentaclees_100', - 'tentaclees_110', - 'master_tentaclees_90', - 'master_tentaclees_100', - 'master_tentaclees_110' - ], - bracket: 5 - }, - { - name: 'Golem', - cap: 1000, - - mobs: ['sadan_golem_1', 'master_sadan_golem_1'], - bracket: 4 - }, - { - name: 'King Midas', - cap: 750, - - mobs: [ - 'king_midas_130', - 'king_midas_140', - 'king_midas_150', - 'king_midas_160', - 'king_midas_170', - 'master_king_midas_130', - 'master_king_midas_140', - 'master_king_midas_150', - 'master_king_midas_160', - 'master_king_midas_170' - ], - bracket: 6 - }, - { - name: 'Lonely Spider', - - cap: 25000, - mobs: [ - 'lonely_spider_35', - 'lonely_spider_55', - 'lonely_spider_65', - 'lonely_spider_75', - 'lonely_spider_85', - 'lonely_spider_95', - 'lonely_spider_105', - 'lonely_spider_115', - 'master_lonely_spider_35', - 'master_lonely_spider_55', - 'master_lonely_spider_65', - 'master_lonely_spider_75', - 'master_lonely_spider_85', - 'master_lonely_spider_95', - 'master_lonely_spider_105', - 'master_lonely_spider_115' - ], - bracket: 4 - }, - { - name: 'Lost Adventurer', - cap: 3000, - - mobs: [ - 'lost_adventurer_80', - 'lost_adventurer_81', - 'lost_adventurer_82', - 'lost_adventurer_83', - 'lost_adventurer_85', - 'lost_adventurer_86', - 'lost_adventurer_87', - 'lost_adventurer_88', - 'lost_adventurer_90', - 'lost_adventurer_91', - 'lost_adventurer_92', - 'lost_adventurer_93', - 'lost_adventurer_100', - 'lost_adventurer_101', - 'lost_adventurer_102', - 'lost_adventurer_103', - 'lost_adventurer_110', - 'lost_adventurer_111', - 'lost_adventurer_112', - 'lost_adventurer_113', - 'lost_adventurer_120', - 'lost_adventurer_121', - 'lost_adventurer_122', - 'lost_adventurer_123', - 'lost_adventurer_130', - 'lost_adventurer_131', - 'lost_adventurer_132', - 'lost_adventurer_133', - 'lost_adventurer_134', - 'lost_adventurer_135', - 'lost_adventurer_140', - 'lost_adventurer_141', - 'lost_adventurer_142', - 'lost_adventurer_143', - 'lost_adventurer_144', - 'lost_adventurer_150', - 'lost_adventurer_151', - 'lost_adventurer_152', - 'lost_adventurer_153', - 'lost_adventurer_154', - 'lost_adventurer_160', - 'lost_adventurer_161', - 'lost_adventurer_162', - 'lost_adventurer_163', - 'lost_adventurer_164', - 'master_lost_adventurer_80', - 'master_lost_adventurer_81', - 'master_lost_adventurer_82', - 'master_lost_adventurer_83', - 'master_lost_adventurer_85', - 'master_lost_adventurer_86', - 'master_lost_adventurer_87', - 'master_lost_adventurer_88', - 'master_lost_adventurer_90', - 'master_lost_adventurer_91', - 'master_lost_adventurer_92', - 'master_lost_adventurer_93', - 'master_lost_adventurer_100', - 'master_lost_adventurer_101', - 'master_lost_adventurer_102', - 'master_lost_adventurer_103', - 'master_lost_adventurer_110', - 'master_lost_adventurer_111', - 'master_lost_adventurer_112', - 'master_lost_adventurer_113', - 'master_lost_adventurer_120', - 'master_lost_adventurer_121', - 'master_lost_adventurer_122', - 'master_lost_adventurer_123', - 'master_lost_adventurer_130', - 'master_lost_adventurer_131', - 'master_lost_adventurer_132', - 'master_lost_adventurer_133', - 'master_lost_adventurer_134', - 'master_lost_adventurer_135', - 'master_lost_adventurer_140', - 'master_lost_adventurer_141', - 'master_lost_adventurer_142', - 'master_lost_adventurer_143', - 'master_lost_adventurer_144', - 'master_lost_adventurer_150', - 'master_lost_adventurer_151', - 'master_lost_adventurer_152', - 'master_lost_adventurer_153', - 'master_lost_adventurer_154', - 'master_lost_adventurer_160', - 'master_lost_adventurer_161', - 'master_lost_adventurer_162', - 'master_lost_adventurer_163', - 'master_lost_adventurer_164' - ], - bracket: 7 - }, - { - name: 'Mimic', - cap: 1000, - - mobs: ['mimic_115', 'mimic_125', 'master_mimic_115', 'master_mimic_125'], - bracket: 4 - }, - { - name: 'Scared Skeleton', - cap: 4000, - - mobs: [ - 'scared_skeleton_42', - 'scared_skeleton_62', - 'scared_skeleton_72', - 'master_scared_skeleton_42', - 'master_scared_skeleton_62', - 'master_scared_skeleton_72' - ], - bracket: 3 - }, - { - name: 'Shadow Assassin', - cap: 3000, - - mobs: [ - 'shadow_assassin_120', - 'shadow_assassin_130', - 'shadow_assassin_140', - 'shadow_assassin_150', - 'shadow_assassin_160', - 'shadow_assassin_170', - 'shadow_assassin_171', - 'master_shadow_assassin_120', - 'master_shadow_assassin_130', - 'master_shadow_assassin_140', - 'master_shadow_assassin_150', - 'master_shadow_assassin_160', - 'master_shadow_assassin_170', - 'master_shadow_assassin_171' - ], - bracket: 7 - }, - { - name: 'Skeleton Grunt', - cap: 4000, - - mobs: [ - 'skeleton_grunt_40', - 'skeleton_grunt_60', - 'skeleton_grunt_70', - 'skeleton_grunt_80', - 'master_skeleton_grunt_40', - 'master_skeleton_grunt_60', - 'master_skeleton_grunt_70', - 'master_skeleton_grunt_80' - ], - bracket: 3 - }, - { - name: 'Skeleton Lord', - cap: 1000, - - mobs: ['skeleton_lord_150', 'master_skeleton_lord_150'], - bracket: 5 - }, - { - name: 'Skeleton Master', - cap: 25000, - - mobs: [ - 'skeleton_master_48', - 'skeleton_master_68', - 'skeleton_master_78', - 'skeleton_master_88', - 'skeleton_master_98', - 'skeleton_master_108', - 'skeleton_master_118', - 'skeleton_master_128', - 'master_skeleton_master_48', - 'master_skeleton_master_68', - 'master_skeleton_master_78', - 'master_skeleton_master_88', - 'master_skeleton_master_98', - 'master_skeleton_master_108', - 'master_skeleton_master_118', - 'master_skeleton_master_128' - ], - bracket: 4 - }, - { - name: 'Skeleton Soldier', - cap: 40000, - - mobs: [ - 'skeleton_soldier_46', - 'skeleton_soldier_66', - 'skeleton_soldier_76', - 'skeleton_soldier_86', - 'skeleton_soldier_96', - 'skeleton_soldier_106', - 'skeleton_soldier_116', - 'skeleton_soldier_126', - 'master_skeleton_soldier_46', - 'master_skeleton_soldier_66', - 'master_skeleton_soldier_76', - 'master_skeleton_soldier_86', - 'master_skeleton_soldier_96', - 'master_skeleton_soldier_106', - 'master_skeleton_soldier_116', - 'master_skeleton_soldier_126' - ], - bracket: 1 - }, - { - name: 'Skeletor', - cap: 10000, - - mobs: [ - 'skeletor_80', - 'skeletor_90', - 'skeletor_100', - 'skeletor_101', - 'skeletor_110', - 'skeletor_120', - 'skeletor_prime_100', - 'skeletor_prime_110', - 'skeletor_prime_120', - 'master_skeletor_80', - 'master_skeletor_90', - 'master_skeletor_100', - 'master_skeletor_101', - 'master_skeletor_110', - 'master_skeletor_120', - 'master_skeletor_prime_100', - 'master_skeletor_prime_110', - 'master_skeletor_prime_120' - ], - bracket: 5 - }, - { - name: 'Sniper', - cap: 4000, - - mobs: [ - 'sniper_skeleton_43', - 'sniper_skeleton_63', - 'sniper_skeleton_73', - 'sniper_skeleton_83', - 'sniper_skeleton_93', - 'sniper_skeleton_103', - 'sniper_skeleton_113', - 'sniper_skeleton_123', - 'master_sniper_skeleton_43', - 'master_sniper_skeleton_63', - 'master_sniper_skeleton_73', - 'master_sniper_skeleton_83', - 'master_sniper_skeleton_93', - 'master_sniper_skeleton_103', - 'master_sniper_skeleton_113', - 'master_sniper_skeleton_123' - ], - bracket: 3 - }, - { - name: 'Super Archer', - cap: 10000, - - mobs: [ - 'super_archer_90', - 'super_archer_100', - 'super_archer_110', - 'super_archer_120', - 'master_super_archer_90', - 'master_super_archer_100', - 'master_super_archer_110', - 'master_super_archer_120' - ], - bracket: 5 - }, - { - name: 'Super Tank Zombie', - cap: 25000, - - mobs: [ - 'super_tank_zombie_90', - 'super_tank_zombie_100', - 'super_tank_zombie_110', - 'super_tank_zombie_120', - 'master_super_tank_zombie_90', - 'master_super_tank_zombie_100', - 'master_super_tank_zombie_110', - 'master_super_tank_zombie_120' - ], - bracket: 4 - }, - { - name: 'Tank Zombie', - cap: 4000, - - mobs: [ - 'crypt_tank_zombie_40', - 'crypt_tank_zombie_60', - 'crypt_tank_zombie_70', - 'crypt_tank_zombie_80', - 'crypt_tank_zombie_90', - 'master_crypt_tank_zombie_40', - 'master_crypt_tank_zombie_60', - 'master_crypt_tank_zombie_70', - 'master_crypt_tank_zombie_80', - 'master_crypt_tank_zombie_90' - ], - bracket: 3 - }, - { - name: 'Terracotta', - cap: 40000, - - mobs: ['sadan_statue_1', 'master_sadan_statue_1'], - bracket: 1 - }, - { - name: 'Undead', - cap: 10000, - - mobs: [ - 'watcher_summon_undead_1', - 'watcher_summon_undead_2', - 'watcher_summon_undead_3', - 'watcher_summon_undead_4', - 'watcher_summon_undead_5', - 'watcher_summon_undead_6', - 'watcher_summon_undead_7', - 'watcher_summon_undead_8', - 'master_watcher_summon_undead_1', - 'master_watcher_summon_undead_2', - 'master_watcher_summon_undead_3', - 'master_watcher_summon_undead_4', - 'master_watcher_summon_undead_5', - 'master_watcher_summon_undead_6', - 'master_watcher_summon_undead_7', - 'master_watcher_summon_undead_8' - ], - bracket: 2 - }, - { - name: 'Undead Skeleton', - cap: 25000, - - mobs: [ - 'dungeon_respawning_skeleton_40', - 'dungeon_respawning_skeleton_40', - 'dungeon_respawning_skeleton_60', - 'dungeon_respawning_skeleton_60', - 'dungeon_respawning_skeleton_70', - 'dungeon_respawning_skeleton_70', - 'dungeon_respawning_skeleton_80', - 'dungeon_respawning_skeleton_80', - 'dungeon_respawning_skeleton_90', - 'dungeon_respawning_skeleton_90', - 'dungeon_respawning_skeleton_100', - 'dungeon_respawning_skeleton_100', - 'dungeon_respawning_skeleton_110', - 'dungeon_respawning_skeleton_110', - 'dungeon_respawning_skeleton_120', - 'dungeon_respawning_skeleton_120', - 'master_dungeon_respawning_skeleton_40', - 'master_dungeon_respawning_skeleton_40', - 'master_dungeon_respawning_skeleton_60', - 'master_dungeon_respawning_skeleton_60', - 'master_dungeon_respawning_skeleton_70', - 'master_dungeon_respawning_skeleton_70', - 'master_dungeon_respawning_skeleton_80', - 'master_dungeon_respawning_skeleton_80', - 'master_dungeon_respawning_skeleton_90', - 'master_dungeon_respawning_skeleton_90', - 'master_dungeon_respawning_skeleton_100', - 'master_dungeon_respawning_skeleton_100', - 'master_dungeon_respawning_skeleton_110', - 'master_dungeon_respawning_skeleton_110', - 'master_dungeon_respawning_skeleton_120' - ], - bracket: 4 - }, - { - name: 'Wither Guard', - cap: 10000, - - mobs: ['wither_guard_100', 'master_wither_guard_100'], - bracket: 5 - }, - { - name: 'Wither Husk', - cap: 10000, - - mobs: ['master_wither_husk_100'], - bracket: 5 - }, - { - name: 'Wither Miner', - cap: 25000, - - mobs: ['wither_miner_100', 'master_wither_miner_100'], - bracket: 4 - }, - { - name: 'Withermancer', - - cap: 25000, - mobs: [ - 'crypt_witherskeleton_90', - 'crypt_witherskeleton_100', - 'crypt_witherskeleton_110', - 'crypt_witherskeleton_120', - 'master_crypt_witherskeleton_90', - 'master_crypt_witherskeleton_100', - 'master_crypt_witherskeleton_110', - 'master_crypt_witherskeleton_120' - ], - bracket: 4 - }, - { - name: 'Zombie Commander', - cap: 3000, - - mobs: [ - 'zombie_commander_110', - 'zombie_commander_120', - 'master_zombie_commander_110', - 'master_zombie_commander_120' - ], - bracket: 4 - }, - { - name: 'Zombie Grunt', - cap: 4000, - - mobs: [ - 'zombie_grunt_40', - 'zombie_grunt_60', - 'zombie_grunt_70', - 'zombie_grunt_80', - 'master_zombie_grunt_40', - 'master_zombie_grunt_60', - 'master_zombie_grunt_70', - 'master_zombie_grunt_80' - ], - bracket: 3 - }, - { - name: 'Zombie Knight', - cap: 10000, - - mobs: [ - 'zombie_knight_86', - 'zombie_knight_96', - 'zombie_knight_106', - 'zombie_knight_116', - 'zombie_knight_126', - 'master_zombie_knight_86', - 'master_zombie_knight_96', - 'master_zombie_knight_106', - 'master_zombie_knight_116', - 'master_zombie_knight_126' - ], - bracket: 5 - }, - { - name: 'Zombie Lord', - cap: 1000, - - mobs: ['zombie_lord_150', 'master_zombie_lord_150'], - bracket: 5 - }, - { - name: 'Zombie Soldier', - cap: 40000, - - mobs: [ - 'zombie_soldier_83', - 'zombie_soldier_93', - 'zombie_soldier_103', - 'zombie_soldier_113', - 'zombie_soldier_123', - 'master_zombie_soldier_83', - 'master_zombie_soldier_93', - 'master_zombie_soldier_103', - 'master_zombie_soldier_113', - 'master_zombie_soldier_123' - ], - bracket: 1 - } - ] - } - }, - bestiaryBrackets: { - 1: [ - 20, 40, 60, 100, 200, 400, 800, 1400, 2000, 3000, 6000, 12000, 20000, 30000, 40000, 50000, 60000, 72000, 86000, - 100000, 200000, 400000, 600000, 800000, 1000000 - ], - 2: [ - 5, 10, 15, 25, 50, 100, 200, 350, 500, 750, 1500, 3000, 5000, 7500, 10000, 12500, 15000, 18000, 21500, 25000, - 50000, 100000, 150000, 200000, 250000 - ], - 3: [ - 4, 8, 12, 16, 20, 40, 80, 140, 200, 300, 600, 1200, 2000, 3000, 4000, 5000, 6000, 7200, 8600, 10000, 20000, 40000, - 60000, 80000, 100000 - ], - 4: [ - 2, 4, 6, 10, 15, 20, 25, 35, 50, 75, 150, 300, 500, 750, 1000, 1350, 1650, 2000, 2500, 3000, 5000, 10000, 15000, - 20000, 25000 - ], - 5: [ - 1, 2, 3, 5, 7, 10, 15, 20, 25, 30, 60, 120, 200, 300, 400, 500, 600, 720, 860, 1000, 2000, 4000, 6000, 8000, 10000 - ], - 6: [1, 2, 3, 5, 7, 9, 14, 17, 21, 25, 50, 80, 125, 175, 250, 325, 425, 525, 625, 750, 1500, 3000, 4500, 6000, 7500], - 7: [1, 2, 3, 5, 7, 9, 11, 14, 17, 20, 30, 40, 55, 75, 100, 150, 200, 275, 375, 500, 1000, 1500, 2000, 2500, 3000] - }, - /* eslint-enable camelcase */ - // Credits (pit) https://github.com/PitPanda/PitPandaProduction/blob/b1971f56ea1aa8c829b722cbb33247c96591c0cb/structures/Pit.js - pit: { - Prestiges: [ - { Multiplier: 1, TotalXp: 65950, SumXp: 65950, GoldReq: 10000, Renown: 0 }, - { Multiplier: 1.1, TotalXp: 72560, SumXp: 138510, GoldReq: 20000, Renown: 10 }, - { Multiplier: 1.2, TotalXp: 79170, SumXp: 217680, GoldReq: 20000, Renown: 10 }, - { Multiplier: 1.3, TotalXp: 85750, SumXp: 303430, GoldReq: 20000, Renown: 10 }, - { Multiplier: 1.4, TotalXp: 92330, SumXp: 395760, GoldReq: 30000, Renown: 10 }, - { Multiplier: 1.5, TotalXp: 98940, SumXp: 494700, GoldReq: 35000, Renown: 10 }, - { Multiplier: 1.75, TotalXp: 115440, SumXp: 610140, GoldReq: 40000, Renown: 20 }, - { Multiplier: 2, TotalXp: 131900, SumXp: 742040, GoldReq: 45000, Renown: 20 }, - { Multiplier: 2.5, TotalXp: 164890, SumXp: 906930, GoldReq: 50000, Renown: 20 }, - { Multiplier: 3, TotalXp: 197850, SumXp: 1104780, GoldReq: 60000, Renown: 20 }, - { Multiplier: 4, TotalXp: 263800, SumXp: 1368580, GoldReq: 70000, Renown: 20 }, - { Multiplier: 5, TotalXp: 329750, SumXp: 1698330, GoldReq: 80000, Renown: 30 }, - { Multiplier: 6, TotalXp: 395700, SumXp: 2094030, GoldReq: 90000, Renown: 30 }, - { Multiplier: 7, TotalXp: 461650, SumXp: 2555680, GoldReq: 100000, Renown: 30 }, - { Multiplier: 8, TotalXp: 527600, SumXp: 3083280, GoldReq: 125000, Renown: 30 }, - { Multiplier: 9, TotalXp: 593550, SumXp: 3676830, GoldReq: 150000, Renown: 30 }, - { Multiplier: 10, TotalXp: 659500, SumXp: 4336330, GoldReq: 175000, Renown: 40 }, - { Multiplier: 12, TotalXp: 791400, SumXp: 5127730, GoldReq: 200000, Renown: 40 }, - { Multiplier: 14, TotalXp: 923300, SumXp: 6051030, GoldReq: 250000, Renown: 40 }, - { Multiplier: 16, TotalXp: 1055200, SumXp: 7106230, GoldReq: 300000, Renown: 40 }, - { Multiplier: 18, TotalXp: 1187100, SumXp: 8293330, GoldReq: 350000, Renown: 40 }, - { Multiplier: 20, TotalXp: 1319000, SumXp: 9612330, GoldReq: 400000, Renown: 50 }, - { Multiplier: 24, TotalXp: 1582800, SumXp: 11195130, GoldReq: 500000, Renown: 50 }, - { Multiplier: 28, TotalXp: 1846600, SumXp: 13041730, GoldReq: 600000, Renown: 50 }, - { Multiplier: 32, TotalXp: 2110400, SumXp: 15152130, GoldReq: 700000, Renown: 50 }, - { Multiplier: 36, TotalXp: 2374200, SumXp: 17526330, GoldReq: 800000, Renown: 50 }, - { Multiplier: 40, TotalXp: 2638000, SumXp: 20164330, GoldReq: 900000, Renown: 75 }, - { Multiplier: 45, TotalXp: 2967750, SumXp: 23132080, GoldReq: 1000000, Renown: 75 }, - { Multiplier: 50, TotalXp: 3297500, SumXp: 26429580, GoldReq: 1000000, Renown: 75 }, - { Multiplier: 75, TotalXp: 4946250, SumXp: 31375830, GoldReq: 1000000, Renown: 75 }, - { Multiplier: 100, TotalXp: 6595000, SumXp: 37970830, GoldReq: 1000000, Renown: 250 }, - { Multiplier: 101, TotalXp: 6660950, SumXp: 44631780, GoldReq: 1000000, Renown: 100 }, - { Multiplier: 101, TotalXp: 6660950, SumXp: 51292730, GoldReq: 1000000, Renown: 100 }, - { Multiplier: 101, TotalXp: 6660950, SumXp: 57953680, GoldReq: 1000000, Renown: 100 }, - { Multiplier: 101, TotalXp: 6660950, SumXp: 64614630, GoldReq: 1000000, Renown: 100 }, - { Multiplier: 101, TotalXp: 6660950, SumXp: 71275580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 200, TotalXp: 13190000, SumXp: 84465580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 300, TotalXp: 19785000, SumXp: 104250580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 400, TotalXp: 26380000, SumXp: 130630580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 500, TotalXp: 32975000, SumXp: 163605580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 750, TotalXp: 49462500, SumXp: 213068080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 1000, TotalXp: 65950000, SumXp: 279018080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 1250, TotalXp: 82437500, SumXp: 361455580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 1500, TotalXp: 98925000, SumXp: 460380580, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 1750, TotalXp: 115412500, SumXp: 575793080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 2000, TotalXp: 131900000, SumXp: 707693080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 3000, TotalXp: 197850000, SumXp: 905543080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 5000, TotalXp: 329750000, SumXp: 1235293080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 10000, TotalXp: 659500000, SumXp: 1894793080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 50000, TotalXp: 3297500000, SumXp: 5192293080, GoldReq: 2000000, Renown: 100 }, - { Multiplier: 100000, TotalXp: 6595000000, SumXp: 11787293080, GoldReq: 0, Renown: 100 } - ], - Levels: [ - { Xp: 15 }, - { Xp: 30 }, - { Xp: 50 }, - { Xp: 75 }, - { Xp: 125 }, - { Xp: 300 }, - { Xp: 600 }, - { Xp: 800 }, - { Xp: 900 }, - { Xp: 1000 }, - { Xp: 1200 }, - { Xp: 1500 }, - { Xp: 0 } - ] - } -}; diff --git a/src/utils/Guild.js b/src/utils/Guild.js deleted file mode 100644 index 0e3bf4581..000000000 --- a/src/utils/Guild.js +++ /dev/null @@ -1,89 +0,0 @@ -/* eslint-disable jsdoc/require-jsdoc */ -const GuildRank = require('../structures/Guild/GuildRank'); -const dateRegExp = /(\d{4})-(\d{2})-(\d{2})/; - -function parseDate(date) { - date[1] -= 1; - return new Date(Math.round(new Date(new Date().setUTCFullYear(...date)).setUTCHours(5, 0, 0) / 1000) * 1000); -} - -function parseHistory(historyData) { - const expValuesReversed = Object.values(historyData).reverse(); - return Object.entries(historyData).map((x, index) => ({ - day: x[0], - date: - parseDate( - x[0] - .match(dateRegExp) - .slice(1) - .map((x) => parseInt(x, 10)) - ) || undefined, - exp: x[1] || 0, - totalExp: expValuesReversed.slice(0, expValuesReversed.length - index).reduce((pV, cV) => pV + cV) - })); -} - -function getGuildLevel(exp) { - const EXP_NEEDED = [ - 100000, 150000, 250000, 500000, 750000, 1000000, 1250000, 1500000, 2000000, 2500000, 2500000, 2500000, 2500000, - 2500000, 3000000 - ]; - - let level = 0; - - for (let i = 0; 1000 >= i; i += 1) { - let need; - if (i >= EXP_NEEDED.length) { - need = EXP_NEEDED[EXP_NEEDED.length - 1]; - } else { - need = EXP_NEEDED[i]; - } - - if (0 > exp - need) { - return Math.round((level + exp / need) * 100) / 100; - } - level += 1; - exp -= need; - } - - return 1000; -} - -function ranks(data) { - return data.ranks && data.ranks.length - ? data.ranks.map((r) => new GuildRank(r)).sort((a, b) => a.priority - b.priority) - : []; -} - -function expLimit(exp) { - return 2e5 < exp ? (7e5 < exp ? 2.5e5 + Math.round(exp * 0.03) : 2e5 + Math.round((exp - 2e5) / 10)) : exp; -} - -function calculateExpHistory(data) { - const finalObj = {}; - for (const day of Object.keys(data.members[0].expHistory)) { - let gexp = 0; - for (const member of data.members) { - gexp += member.expHistory[day] || 0; - } - finalObj[day] = expLimit(gexp); - } - return parseHistory(finalObj); -} - -/** - * @typedef {object} ExpHistory - * @property {string} day String Date ( unparsed ) - * @property {Date} date Parsed Date - * @property {number} exp Experience of the day - * @property {number} totalExp Experience earned from day 0 to this day - */ - -module.exports = { - parseDate, - parseHistory, - getGuildLevel, - ranks, - expLimit, - calculateExpHistory -}; diff --git a/src/utils/Player.js b/src/utils/Player.js deleted file mode 100644 index d7eaae119..000000000 --- a/src/utils/Player.js +++ /dev/null @@ -1,112 +0,0 @@ -/* eslint-disable jsdoc/require-jsdoc */ -function getRank(player) { - let rank; - if (player.prefix) { - rank = player.prefix.replace(/§[0-9|a-z]|\[|\]/g, ''); - } else if (player.rank && 'NORMAL' !== player.rank) { - switch (player.rank) { - case 'YOUTUBER': - rank = 'YouTube'; - break; - case 'GAME_MASTER': - rank = 'Game Master'; - break; - case 'ADMIN': - rank = 'Admin'; - break; - default: - rank = ''; - break; - } - } else { - switch (player.newPackageRank) { - case 'MVP_PLUS': - rank = player.monthlyPackageRank && 'SUPERSTAR' === player.monthlyPackageRank ? 'MVP++' : 'MVP+'; - break; - case 'MVP': - rank = 'MVP'; - break; - case 'VIP_PLUS': - rank = 'VIP+'; - break; - case 'VIP': - rank = 'VIP'; - break; - default: - rank = player.monthlyPackageRank && 'SUPERSTAR' === player.monthlyPackageRank ? 'MVP++' : 'Default'; - } - } - return rank; -} - -function getPlayerLevel(exp) { - const base = 10000; - const growth = 2500; - const reversePqPrefix = -(base - 0.5 * growth) / growth; - const reverseConst = reversePqPrefix * reversePqPrefix; - const growthDivides2 = 2 / growth; - const num = 1 + reversePqPrefix + Math.sqrt(reverseConst + growthDivides2 * exp); - const level = Math.round(num * 100) / 100; - return level; -} - -function xpToNextLevel(player) { - const lvl = getPlayerLevel(player.networkExp); - const xpToNext = 2500 * Math.floor(lvl) + 5000; - if (10000 > player.networkExp) return 10000; - return xpToNext; -} - -function levelToXP(player) { - let level = Number(Math.floor(getPlayerLevel(player.networkExp))); - level = level - 1; - const xp = 1250 * level ** 2 + 8750 * level; - return xp; -} - -function playerLevelProgress(player) { - const xpFromLevel = levelToXP(player); - let currentXP = player.networkExp - xpFromLevel; - const xpToNext = xpToNextLevel(player); - const remainingXP = xpToNext - currentXP + 2500; - currentXP = currentXP - 2500; - const percent = Math.round((currentXP / xpToNext) * 100 * 100) / 100; - const percentRemaining = Math.round((100 - percent) * 100) / 100; - return { - xpToNext, - remainingXP, - currentXP, - percent, - percentRemaining - }; -} - -function getSocialMedia(data) { - if (!data) return null; - const links = data.links; - const formattedNames = ['Twitter', 'YouTube', 'Instagram', 'Twitch', 'Hypixel', 'Discord']; - const upperNames = ['TWITTER', 'YOUTUBE', 'INSTAGRAM', 'TWITCH', 'HYPIXEL', 'DISCORD']; - if (!links) return null; - return Object.keys(links) - .map((x) => upperNames.indexOf(x)) - .filter((x) => -1 !== x) - .map((x) => ({ name: formattedNames[x], link: links[upperNames[x]], id: upperNames[x] })); -} - -function parseClaimedRewards(data) { - if (!data) return null; - return Object.keys(data) - .map((x) => x.match(/levelingReward_(\d+)/)) - .filter((x) => x) - .map((x) => parseInt(x[1], 10)); -} - -module.exports = { - getRank, - getPlayerLevel, - xpToNextLevel, - levelToXP, - playerLevelProgress, - getSocialMedia, - parseClaimedRewards -}; diff --git a/src/utils/SkyblockUtils.js b/src/utils/SkyblockUtils.js deleted file mode 100644 index 51841c9e8..000000000 --- a/src/utils/SkyblockUtils.js +++ /dev/null @@ -1,667 +0,0 @@ -/* eslint-disable jsdoc/require-jsdoc */ -const { parse, simplify } = require('prismarine-nbt'); -const constants = require('./Constants'); - -async function decode(base64, isBuffer = false) { - // Credit: https://github.com/SkyCryptWebsite/SkyCryptv2/blob/3b5b3ae4fe77c60eff90691797f09024baf68872/src/lib/server/stats/items/processing.ts#L215-L218 - const buffer = isBuffer ? base64 : Buffer.from(base64, 'base64'); - let data = await parse(buffer); - data = simplify(data.parsed); - const newdata = []; - for (let i = 0; i < data.i.length; i++) { - newdata.push(data.i[i]); - } - return newdata; -} - -function getLevelByXp(xp, type, levelCap) { - let xpTable; - switch (type) { - case 'runecrafting': - xpTable = constants.runecraftingXp; - break; - case 'dungeons': - xpTable = constants.dungeonXp; - break; - case 'hotm': - xpTable = constants.hotmXp; - break; - case 'social': - xpTable = constants.socialXp; - break; - case 'garden': - xpTable = constants.garden; - break; - case 'wheat': - xpTable = constants.wheat; - break; - case 'carrot': - xpTable = constants.carrot; - break; - case 'potato': - xpTable = constants.potato; - break; - case 'melon': - xpTable = constants.melon; - break; - case 'pumpkin': - xpTable = constants.pumpkin; - break; - case 'sugarCane': - xpTable = constants.sugarCane; - break; - case 'cocoaBeans': - xpTable = constants.cocoaBeans; - break; - case 'cactus': - xpTable = constants.cactus; - break; - case 'mushroom': - xpTable = constants.mushroom; - break; - case 'netherWart': - xpTable = constants.netherWart; - break; - default: - xpTable = constants.levelingXp; - } - let maxLevel = Math.max(...Object.keys(xpTable)); - if ((constants.skillsCap[type] ?? maxLevel) > maxLevel) { - xpTable = Object.assign(constants.xpPast50, xpTable); - maxLevel = 'number' === typeof levelCap ? maxLevel + levelCap : Math.max(...Object.keys(xpTable)); - } - if (isNaN(xp)) { - return { - xp: 0, - level: 0, - maxLevel, - xpCurrent: 0, - xpForNext: xpTable[1], - progress: 0, - cosmetic: Boolean('runecrafting' === type || 'social' === type) - }; - } - let xpTotal = 0; - let level = 0; - let xpForNext = 0; - for (let x = 1; x <= maxLevel; x++) { - if (!xpTable[x]) continue; - xpTotal += xpTable[x]; - if (xpTotal > xp) { - xpTotal -= xpTable[x]; - break; - } else { - level = x; - } - } - const xpCurrent = Math.floor(xp - xpTotal); - if (level < maxLevel) xpForNext = Math.ceil(xpTable[level + 1]); - const progress = Math.floor(Math.max(0, Math.min(xpCurrent / xpForNext, 1)) * 100 * 10) / 10; - - return { - xp: xp, - level: level, - maxLevel: maxLevel, - xpCurrent: xpCurrent, - xpForNext: xpForNext, - progress: progress, - cosmetic: Boolean('runecrafting' === type || 'social' === type) - }; -} - -function getSlayerLevel(slayer) { - if (!slayer) { - return { - xp: 0, - tier1: 0, - tier2: 0, - tier3: 0, - tier4: 0, - tier5: 0, - level: 0 - }; - } - - // eslint-disable-next-line camelcase - const { claimed_levels } = slayer; - let level = 0; - - // eslint-disable-next-line camelcase - for (const levelName in claimed_levels) { - if (Object.prototype.hasOwnProperty.call(claimed_levels, levelName)) { - const newLevel = parseInt(levelName.replace('_special', '').split('_').pop(), 10); - if (newLevel > level) { - level = newLevel; - } - } - } - return { - xp: slayer.xp || 0, - tier1: slayer.boss_kills_tier_0 || 0, - tier2: slayer.boss_kills_tier_1 || 0, - tier3: slayer.boss_kills_tier_2 || 0, - tier4: slayer.boss_kills_tier_3 || 0, - tier5: slayer.boss_kills_tier_4 || 0, - level - }; -} - -function getMemberStats(obj) { - return Object.keys(obj).reduce( - (result, currentKey) => { - const key = currentKey.replace(/_[a-z]/gi, (match) => match[1].toUpperCase()); - - if (currentKey.startsWith('kills') || currentKey.startsWith('deaths')) { - const category = currentKey.startsWith('kills') ? 'kills' : 'deaths'; - const subKey = key === category ? 'total' : key; - - result[category][ - subKey.replace(category, (sub, _, key) => { - return key[sub.length].toLowerCase() + key.slice(sub.length + 1); - }) - ] = obj[currentKey]; - } else { - result[key] = obj[currentKey]; - } - - return result; - }, - { kills: {}, deaths: {} } - ); -} - -function getTrophyFishRank(level) { - if (1 === level) { - return 'Bronze'; - } else if (2 === level) { - return 'Silver'; - } else if (3 === level) { - return 'Gold'; - } else if (4 <= level) { - return 'Diamond'; - } - return null; -} - -function getSkills(data) { - const skillsObject = {}; - skillsObject.combat = getLevelByXp(data?.player_data?.experience?.SKILL_COMBAT ?? 0, 'combat'); - skillsObject.farming = getLevelByXp( - data?.player_data?.experience?.SKILL_FARMING ?? 0, - 'farming', - data?.m?.jacobs_contest?.perks?.farming_level_cap ?? 0 + 50 - ); - skillsObject.fishing = getLevelByXp(data?.player_data?.experience?.SKILL_FISHING ?? 0, 'fishing'); - skillsObject.mining = getLevelByXp(data?.player_data?.experience?.SKILL_MINING ?? 0, 'mining'); - skillsObject.foraging = getLevelByXp(data?.player_data?.experience?.SKILL_FORAGING ?? 0, 'foraging'); - skillsObject.enchanting = getLevelByXp(data?.player_data?.experience?.SKILL_ENCHANTING ?? 0, 'enchanting'); - skillsObject.alchemy = getLevelByXp(data?.player_data?.experience?.SKILL_ALCHEMY ?? 0, 'alchemy'); - skillsObject.carpentry = getLevelByXp(data?.player_data?.experience?.SKILL_CARPENTRY ?? 0, 'carpentry'); - skillsObject.runecrafting = getLevelByXp(data?.player_data?.experience?.SKILL_RUNECRAFTING ?? 0, 'runecrafting'); - skillsObject.taming = getLevelByXp(data?.player_data?.experience?.SKILL_TAMING ?? 0, 'taming'); - skillsObject.social = getLevelByXp(data?.player_data?.experience?.SKILL_SOCIAL ?? 0, 'social'); - const levels = Object.values(skillsObject) - .filter((skill) => true !== skill.cosmetic) - .map((skill) => skill.level); - skillsObject.average = levels.reduce((a, b) => a + b, 0) / levels.length; - return skillsObject; -} - -function formatBestiaryMobs(userProfile, mobs) { - const output = []; - for (const mob of mobs) { - const mobBracket = constants.bestiaryBrackets[mob.bracket]; - - const totalKills = mob.mobs.reduce((acc, cur) => { - return acc + (userProfile.bestiary.kills[cur] ?? 0); - }, 0); - - const maxKills = mob.cap; - const nextTierKills = mobBracket.find((tier) => totalKills < tier && tier <= maxKills); - const tier = nextTierKills ? mobBracket.indexOf(nextTierKills) : mobBracket.indexOf(maxKills) + 1; - - output.push({ - tier: tier - }); - } - - return output; -} - -function getBestiaryLevel(userProfile) { - try { - if (userProfile.bestiary?.kills === undefined) { - return null; - } - - const output = {}; - let tiersUnlocked = 0; - for (const [category, data] of Object.entries(constants.bestiary)) { - const { mobs } = data; - output[category] = {}; - - if ('fishing' === category) { - for (const [key, value] of Object.entries(data)) { - output[category][key] = { - mobs: formatBestiaryMobs(userProfile, value.mobs) - }; - tiersUnlocked += output[category][key].mobs.reduce((acc, cur) => acc + cur.tier, 0); - } - } else { - output[category].mobs = formatBestiaryMobs(userProfile, mobs); - tiersUnlocked += output[category].mobs.reduce((acc, cur) => acc + cur.tier, 0); - } - } - - return tiersUnlocked / 10; - } catch (error) { - // eslint-disable-next-line no-console - console.log(error); - return null; - } -} - -function getSlayer(data) { - if (!data?.slayer?.slayer_bosses) return; - return { - zombie: getSlayerLevel(data?.slayer?.slayer_bosses?.zombie), - spider: getSlayerLevel(data?.slayer?.slayer_bosses?.spider), - wolf: getSlayerLevel(data?.slayer?.slayer_bosses?.wolf), - enderman: getSlayerLevel(data?.slayer?.slayer_bosses?.enderman), - blaze: getSlayerLevel(data?.slayer?.slayer_bosses?.blaze), - vampire: getSlayerLevel(data?.slayer?.slayer_bosses?.vampire) - }; -} - -function getScore(points) { - if (1000 <= points) { - return 'S'; - } else if (800 <= points) { - return 'A'; - } else if (600 <= points) { - return 'B'; - } else if (400 <= points) { - return 'C'; - } else if (200 <= points) { - return 'D'; - } - return 'F'; -} - -function getBelt(points) { - if (7000 <= points) { - return 'Black'; - } else if (6000 <= points) { - return 'Brown'; - } else if (4000 <= points) { - return 'Blue'; - } else if (2000 <= points) { - return 'Green'; - } else if (1000 <= points) { - return 'Yellow'; - } - return 'White'; -} - -function getCrimson(data) { - return { - faction: data?.nether_island_player_data?.selected_faction || null, - reputation: { - barbarians: data?.nether_island_player_data?.barbarians_reputation ?? 0, - mages: data?.nether_island_player_data?.mages_reputation ?? 0 - }, - trophyFish: { - rank: getTrophyFishRank((data?.trophy_fish?.rewards ?? [])?.length), - caught: { - total: data?.trophy_fish?.total_caught ?? 0, - bronze: Object.keys(data?.trophy_fish ?? {}).filter((key) => key.endsWith('_bronze'))?.length, - silver: Object.keys(data?.trophy_fish ?? {}).filter((key) => key.endsWith('_silver'))?.length, - gold: Object.keys(data?.trophy_fish ?? {}).filter((key) => key.endsWith('_gold'))?.length, - diamond: Object.keys(data?.trophy_fish ?? {}).filter((key) => key.endsWith('_diamond'))?.length - } - }, - dojo: { - belt: getBelt( - Object.keys(data?.nether_island_player_data?.dojo ?? {}) - .filter((key) => key?.startsWith('dojo_points')) - .reduce((acc, key) => acc + (data?.nether_island_player_data?.dojo[key] ?? 0), 0) - ), - force: { - points: data?.nether_island_player_data?.dojo?.dojo_points_mob_kb ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_mob_kb ?? 0) - }, - stamina: { - points: data?.nether_island_player_data?.dojo?.dojo_points_wall_jump ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_wall_jump ?? 0) - }, - mastery: { - points: data?.nether_island_player_data?.dojo?.dojo_points_archer ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_archer ?? 0) - }, - discipline: { - points: data?.nether_island_player_data?.dojo?.dojo_points_sword_swap ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_sword_swap ?? 0) - }, - swiftness: { - points: data?.nether_island_player_data?.dojo?.dojo_points_snake ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_snake ?? 0) - }, - control: { - points: data?.nether_island_player_data?.dojo?.dojo_points_lock_head ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_lock_head ?? 0) - }, - tenacity: { - points: data?.nether_island_player_data?.dojo?.dojo_points_fireball ?? 0, - rank: getScore(data?.nether_island_player_data?.dojo?.dojo_points_fireball ?? 0) - } - }, - kuudra: { - none: data?.nether_island_player_data?.kuudra_completed_tiers?.none ?? 0, - hot: data?.nether_island_player_data?.kuudra_completed_tiers?.hot ?? 0, - burning: data?.nether_island_player_data?.kuudra_completed_tiers?.burning ?? 0, - fiery: data?.nether_island_player_data?.kuudra_completed_tiers?.fiery ?? 0, - highestWaveHot: data?.nether_island_player_data?.kuudra_completed_tiers?.highest_wave_hot ?? 0, - highestWaveFiery: data?.nether_island_player_data?.kuudra_completed_tiers?.highest_wave_fiery ?? 0, - infernal: data?.nether_island_player_data?.kuudra_completed_tiers?.infernal ?? 0, - highestWaveInfernal: data?.nether_island_player_data?.kuudra_completed_tiers?.highest_wave_infernal ?? 0, - highestWaveBurning: data?.nether_island_player_data?.kuudra_completed_tiers?.highest_wave_burning ?? 0 - } - }; -} - -function getCompletions(data) { - const completions = { - total: 0 - }; - - for (const tier in data) { - if ('total' === tier) continue; - completions[`Floor_${tier}`] = data[tier]; - completions.total += data[tier]; - } - - return completions; -} - -function getDungeonsFloor(data, type, floor) { - return { - fastestRun: (data?.dungeons?.dungeon_types?.[type]?.best_runs?.[floor] ?? []).sort( - (a, b) => a?.elapsed_time - b?.elapsed_time - )[0], - fastestSRun: (data?.dungeons?.dungeon_types?.[type]?.best_runs?.[floor] ?? []) - .filter((run) => 270 >= run?.score_exploration + run?.score_speed + run?.score_skill + run?.score_bonus) - .sort((a, b) => a?.elapsed_time - b?.elapsed_time)[0], - fastestSPlusRun: (data?.dungeons?.dungeon_types?.[type]?.best_runs?.[floor] ?? []) - .filter((run) => 300 >= run?.score_exploration + run?.score_speed + run?.score_skill + run?.score_bonus) - .sort((a, b) => a?.elapsed_time - b?.elapsed_time)[0], - completions: data?.dungeonXp?.dungeon_types?.[type]?.tier_completions[floor] ?? 0 - }; -} - -function getDungeons(data) { - return { - experience: getLevelByXp(data?.dungeons?.dungeon_types?.catacombs?.experience ?? 0, 'dungeons'), - secrets: data?.dungeons?.secrets ?? 0, - completions: { - catacombs: getCompletions(data?.dungeons?.dungeon_types?.catacombs?.tier_completions), - masterCatacombs: getCompletions(data?.dungeons?.dungeon_types?.master_catacombs?.tier_completions) - }, - floors: { - entrance: getDungeonsFloor(data, 'catacombs', '0'), - floor1: getDungeonsFloor(data, 'catacombs', '1'), - floor2: getDungeonsFloor(data, 'catacombs', '2'), - floor3: getDungeonsFloor(data, 'catacombs', '3'), - floor4: getDungeonsFloor(data, 'catacombs', '4'), - floor5: getDungeonsFloor(data, 'catacombs', '5'), - floor6: getDungeonsFloor(data, 'catacombs', '6'), - floor7: getDungeonsFloor(data, 'catacombs', '7'), - masterCatacombs1: getDungeonsFloor(data, 'master_catacombs', '1'), - masterCatacombs2: getDungeonsFloor(data, 'master_catacombs', '2'), - masterCatacombs3: getDungeonsFloor(data, 'master_catacombs', '3'), - masterCatacombs4: getDungeonsFloor(data, 'master_catacombs', '4'), - masterCatacombs5: getDungeonsFloor(data, 'master_catacombs', '5'), - masterCatacombs6: getDungeonsFloor(data, 'master_catacombs', '6'), - masterCatacombs7: getDungeonsFloor(data, 'master_catacombs', '7') - }, - classes: { - healer: getLevelByXp(data?.dungeons?.player_classes?.healer?.experience ?? 0, 'dungeons'), - mage: getLevelByXp(data?.dungeons?.player_classes?.mage?.experience ?? 0, 'dungeons'), - berserk: getLevelByXp(data?.dungeons?.player_classes?.berserk?.experience ?? 0, 'dungeons'), - archer: getLevelByXp(data?.dungeons?.player_classes?.archer?.experience ?? 0, 'dungeons'), - tank: getLevelByXp(data?.dungeons?.player_classes?.tank?.experience ?? 0, 'dungeons'), - selected: data?.dungeons?.selected_dungeon_class ?? 'mage' - }, - essence: { - diamond: data?.currencies?.essence?.DIAMOND?.current || 0, - dragon: data?.currencies?.essence?.DRAGON?.current || 0, - spider: data?.currencies?.essence?.SPIDER?.current || 0, - wither: data?.currencies?.essence?.WITHER?.current || 0, - undead: data?.currencies?.essence?.UNDEAD?.current || 0, - gold: data?.currencies?.essence?.GOLD?.current || 0, - ice: data?.currencies?.essence?.ICE?.current || 0, - crimson: data?.currencies?.essence?.CRIMSON?.current || 0 - } - }; -} - -function getJacobData(data) { - if (!data.jacobs_contest) { - return { - medals: { - bronze: 0, - silver: 0, - gold: 0 - }, - perks: { - doubleDrops: 0, - farmingLevelCap: 0, - personalBests: false - }, - contests: {} - }; - } - return { - medals: data.jacobs_contest.medals_inv - ? { - bronze: data.jacobs_contest.medals_inv.bronze || 0, - silver: data.jacobs_contest.medals_inv.silver || 0, - gold: data.jacobs_contest.medals_inv.gold || 0 - } - : { bronze: 0, silver: 0, gold: 0 }, - perks: data.jacobs_contest.perks - ? { - doubleDrops: data.jacobs_contest.perks.double_drops || 0, - farmingLevelCap: data.jacobs_contest.perks.farming_level_cap || 0, - personalBests: data.jacobs_contest.perks.personal_bests || false - } - : { doubleDrops: 0, farmingLevelCap: 0, personalBests: false }, - contests: data.jacobs_contest.contests || {} - }; -} - -function getChocolateFactory(data) { - if (!data?.events?.easter) { - return { - employees: { - bro: 0, - cousin: 0, - sis: 0, - father: 0, - grandma: 0, - dog: 0, - uncle: 0 - }, - chocolate: { - current: 0, - total: 0, - sincePrestige: 0 - }, - timeTower: { - charges: 0, - level: 0 - }, - upgrades: { - click: 0, - multiplier: 0, - rabbitRarity: 0 - }, - goldenClick: { - amount: 0, - year: 0 - }, - barnCapacity: 0, - prestige: 0 - }; - } - return { - employees: { - bro: data?.events?.easter?.employees?.rabbit_bro || 0, - cousin: data?.events?.easter?.employees?.rabbit_cousin || 0, - sis: data?.events?.easter?.employees?.rabbit_sis || 0, - father: data?.events?.easter?.employees?.rabbit_father || 0, - grandma: data?.events?.easter?.employees?.rabbit_grandma || 0, - dog: data?.events?.easter?.employees?.rabbit_dog || 0, - uncle: data?.events?.easter?.employees?.rabbit_uncle || 0 - }, - chocolate: { - current: data?.events?.easter?.chocolate || 0, - total: data?.events?.easter?.total_chocolate || 0, - sincePrestige: data?.events?.easter?.chocolate_since_prestige || 0 - }, - timeTower: { - charges: data?.events?.easter?.time_tower?.charges || 0, - level: data?.events?.easter?.time_tower?.level || 0 - }, - upgrades: { - click: data?.events?.easter?.click_upgrades || 0, - multiplier: data?.events?.easter?.chocolate_multiplier_upgrades || 0, - rabbitRarity: data?.events?.easter?.rabbit_rarity_upgrades || 0 - }, - goldenClick: { - amount: data?.events?.easter?.golden_click_amount || 0, - year: data?.events?.easter?.golden_click_year || 0 - }, - barnCapacity: data?.events?.easter?.rabbit_barn_capacity_level || 0, - prestige: data?.events?.easter?.chocolate_level || 0 - }; -} - -function getPetLevel(petExp, offsetRarity, maxLevel) { - const rarityOffset = constants.petRarityOffset[offsetRarity]; - const levels = constants.petLevels.slice(rarityOffset, rarityOffset + maxLevel - 1); - - const xpMaxLevel = levels.reduce((a, b) => a + b, 0); - let xpTotal = 0; - let level = 1; - - let xpForNext; - - for (let i = 0; i < maxLevel; i++) { - xpTotal += levels[i]; - - if (xpTotal > petExp) { - xpTotal -= levels[i]; - break; - } else { - level++; - } - } - - let xpCurrent = Math.floor(petExp - xpTotal); - let progress; - - if (level < maxLevel) { - xpForNext = Math.ceil(levels[level - 1]); - progress = Math.max(0, Math.min(xpCurrent / xpForNext, 1)); - } else { - level = maxLevel; - xpCurrent = petExp - levels[maxLevel - 1]; - xpForNext = 0; - progress = 1; - } - - return { - level, - xpCurrent, - xpForNext, - progress, - xpMaxLevel - }; -} - -function parseRarity(stringContainingRarity) { - const rarityArray = [ - 'COMMON', - 'UNCOMMON', - 'RARE', - 'EPIC', - 'LEGENDARY', - 'MYTHIC', - 'DIVINE', - 'SPECIAL', - 'VERY SPECIAL' - ]; - for (const rarity of rarityArray) { - if (stringContainingRarity.includes(rarity)) return rarity; - } -} - -function parseGearScore(lore) { - for (const line of lore) { - if (line.match(/Gear Score: §[0-9a-f](\d+)/)) return Number(line.match(/Gear Score: §d(\d+)/)[1]); - } -} - -function populateGoals(achieved, all) { - const populatedAchieved = []; - const unachieved = []; - for (const goal of all) { - if (achieved.find((str) => str === goal.name)) populatedAchieved.push(goal); - else unachieved.push(goal); - } - populatedAchieved.unachievedGoals = unachieved; - return populatedAchieved; -} - -function getHOTM(data) { - return { - experience: getLevelByXp(data.mining_core?.experience, 'hotm'), - ability: data.mining_core?.selected_pickaxe_ability || 'none', - powder: { - mithril: { - spent: data?.mining_core?.powder_spent_mithril || 0, - current: data?.mining_core?.powder_mithril || 0, - total: data?.mining_core?.powder_spent_mithril || 0 + data?.mining_core?.powder_mithril || 0 - }, - gemstone: { - spent: data?.mining_core?.powder_spent_gemstone || 0, - current: data?.mining_core?.powder_gemstone || 0, - total: data?.mining_core?.powder_spent_gemstone || 0 + data?.mining_core?.powder_gemstone || 0 - }, - glacite: { - spent: data?.mining_core?.powder_spent_glacite || 0, - current: data?.mining_core?.powder_glacite || 0, - total: data?.mining_core?.powder_spent_glacite || 0 + data?.mining_core?.powder_glacite || 0 - } - } - }; -} - -module.exports = { - decode, - getLevelByXp, - getMemberStats, - getTrophyFishRank, - getSkills, - getBestiaryLevel, - getSlayer, - getCrimson, - getDungeons, - getJacobData, - getChocolateFactory, - getPetLevel, - parseRarity, - parseGearScore, - populateGoals, - getHOTM -}; diff --git a/src/utils/arrayTools.js b/src/utils/arrayTools.js deleted file mode 100644 index cdd184975..000000000 --- a/src/utils/arrayTools.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - isStrArray: (input) => Array.isArray(input) || 'string' === typeof input, - strToArray: (input) => [input].flat() -}; diff --git a/src/utils/divide.js b/src/utils/divide.js deleted file mode 100644 index 416f28ef6..000000000 --- a/src/utils/divide.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (a = 0, b = 1) => { - const out = Number(((a || 0) / (b || 0)).toFixed(2)) || 0; - if (isFinite(out)) return out; - return a; -}; diff --git a/src/utils/index.js b/src/utils/index.js deleted file mode 100644 index 6e9b260e5..000000000 --- a/src/utils/index.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - arrayTool: require('./arrayTools'), - Constants: require('./Constants'), - divide: require('./divide'), - guild: require('./Guild'), - isGuildID: require('./isGuildID'), - isUUID: require('./isUUID'), - oscillation: require('./oscillation'), - player: require('./Player'), - removeSnakeCase: require('./removeSnakeCase'), - SkyblockUtils: require('./SkyblockUtils'), - toUuid: require('./toUuid'), - varInt: require('./varInt') -}; diff --git a/src/utils/isGuildID.js b/src/utils/isGuildID.js deleted file mode 100644 index e3ec95685..000000000 --- a/src/utils/isGuildID.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = (id) => { - return 24 === id.length; -}; diff --git a/src/utils/isUUID.js b/src/utils/isUUID.js deleted file mode 100644 index 5d769e66f..000000000 --- a/src/utils/isUUID.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (uuid) => { - const regexp = /^[0-9a-f]{32}$/i; - uuid = uuid.replace(/-/g, ''); - return regexp.test(uuid); -}; diff --git a/src/utils/oscillation.js b/src/utils/oscillation.js deleted file mode 100644 index 84190263e..000000000 --- a/src/utils/oscillation.js +++ /dev/null @@ -1,17 +0,0 @@ -// See https://github.com/HypixelDev/PublicAPI/blob/db26b5fd3b7bb29da14e40e6d211143ec44a4519/Documentation/misc/Oscillation.md -// Month oscillation started in December 2014, so every month that is pair ( odd in js!! ) is month A -// Weekly oscillation started... just refer to the code in the docs - -// eslint-disable-next-line jsdoc/require-jsdoc -function monthAB(date = Date.now()) { - return new Date(date).getMonth() % 2 ? 'a' : 'b'; -} - -const weeklyOscillationStart = 1417237200000; - -// eslint-disable-next-line jsdoc/require-jsdoc -function weekAB(date = Date.now()) { - return (Math.abs(new Date(date).getTime() - weeklyOscillationStart) / 604800000) % 2 ? 'a' : 'b'; -} - -module.exports = { monthAB, weekAB }; diff --git a/src/utils/removeSnakeCase.js b/src/utils/removeSnakeCase.js deleted file mode 100644 index 6806b742c..000000000 --- a/src/utils/removeSnakeCase.js +++ /dev/null @@ -1,33 +0,0 @@ -const single = (obj) => { - Object.keys(obj).reduce((pV, cV) => ({ ...pV, [cV.replace(/_[a-z]/gi, (x) => x[1].toUpperCase())]: obj[cV] }), {}); -}; - -// eslint-disable-next-line jsdoc/require-jsdoc -function validateJSON(obj) { - return 'object' === typeof obj && '{' === JSON.stringify(obj)[0]; -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function recursive(obj, lowerCase = false) { - if (!validateJSON(obj)) return obj; - return Object.keys(obj).reduce( - (pV, cV) => ({ - ...pV, - [(lowerCase ? cV : cV.toLowerCase()).replace(/_[a-z]/gi, (x) => x[1].toUpperCase())]: recursive(obj[cV]) - }), - {} - ); -} - -// eslint-disable-next-line jsdoc/require-jsdoc -function removeSnakeCaseString(str) { - if ('string' !== typeof str) return null; - return str.toLowerCase().replace(/_[a-z]/gi, (x) => x[1].toUpperCase()); -} - -module.exports = { - single, - recursive, - validateJSON, - removeSnakeCaseString -}; diff --git a/src/utils/rgbToHexColor.js b/src/utils/rgbToHexColor.js deleted file mode 100644 index 6709170a7..000000000 --- a/src/utils/rgbToHexColor.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = (rgb) => { - let hexCode = '#'; - for (const num of rgb) { - const hex = Number(num).toString(16); - hexCode += 1 === hex.length ? '0' + hex : hex; - } - return hexCode; -}; diff --git a/src/utils/romanize.js b/src/utils/romanize.js deleted file mode 100644 index e4e176fc6..000000000 --- a/src/utils/romanize.js +++ /dev/null @@ -1,42 +0,0 @@ -module.exports = (num) => { - if (isNaN(num)) return NaN; - const digits = String(Number(num)).split(''); - const key = [ - '', - 'C', - 'CC', - 'CCC', - 'CD', - 'D', - 'DC', - 'DCC', - 'DCCC', - 'CM', - '', - 'X', - 'XX', - 'XXX', - 'XL', - 'L', - 'LX', - 'LXX', - 'LXXX', - 'XC', - '', - 'I', - 'II', - 'III', - 'IV', - 'V', - 'VI', - 'VII', - 'VIII', - 'IX' - ]; - let roman = ''; - let i = 3; - while (i--) { - roman = (key[Number(digits.pop()) + i * 10] || '') + roman; - } - return Array(Number(digits.join('')) + 1).join('M') + roman; -}; diff --git a/src/utils/toUuid.js b/src/utils/toUuid.js deleted file mode 100644 index f1a46af5a..000000000 --- a/src/utils/toUuid.js +++ /dev/null @@ -1,24 +0,0 @@ -const fetch = require('../Private/uuidCache.js'); -const isUUID = require('./isUUID.js'); -const Errors = require('../Errors'); - -module.exports = async (input, cacheTime = 600, useThirdPartyAPI = '') => { - if (!input) throw new Error(Errors.NO_NICKNAME_UUID); - if ('string' !== typeof input) throw new Error(Errors.UUID_NICKNAME_MUST_BE_A_STRING); - if (isUUID(input)) return input.replace(/-/g, ''); - try { - const customUrl = true === useThirdPartyAPI ? 'https://api.minetools.eu/uuid/' : useThirdPartyAPI; - const url = useThirdPartyAPI ? `${customUrl}${input}` : `https://mowojang.matdoes.dev/${input}`; - const res = await fetch(url, input, cacheTime); - if (404 === res.status) { - return Promise.reject(new Error(Errors.PLAYER_DOES_NOT_EXIST)); - } else if (200 !== res.status) { - throw new Error('Unknown Error whilst retrieving player information'); - } - return res.id; - } catch { - // 2nd Try - if (!useThirdPartyAPI) return module.exports(input, cacheTime, true); - throw new Error(Errors.PLAYER_DOES_NOT_EXIST); - } -}; diff --git a/src/utils/varInt.js b/src/utils/varInt.js deleted file mode 100644 index c186fe0e0..000000000 --- a/src/utils/varInt.js +++ /dev/null @@ -1,17 +0,0 @@ -// eslint-disable-next-line jsdoc/require-jsdoc -function readVarInt(bytes) { - let numRead = 0; - let result = 0; - do { - const read = bytes[numRead]; - const value = read & 0b01111111; - result |= value << (7 * numRead); - numRead++; - if (5 < numRead) { - return NaN; - } - } while (numRead < bytes.length); - - return result; -} -module.exports = readVarInt; diff --git a/tests/Client#getAPIStatus.js b/tests/Client#getAPIStatus.js deleted file mode 100644 index 27825ef86..000000000 --- a/tests/Client#getAPIStatus.js +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable no-undef */ -const { APIIncident } = require('../src'); -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getAPIStatus', async () => { - let status; - it('expect not to throw', async () => { - status = await client.getAPIStatus(); - }); - it('should be an object', () => { - expect(status).to.be.an('object'); - }); - it('required keys should exist', () => { - if (status.sourceUrl) expect(status.sourceUrl).to.be.a('string'); - if (status.title) expect(status.title).to.be.a('string'); - if (status.description) expect(status.description).to.be.a('string'); - status.incidents.forEach((incident) => { - expect(incident).instanceOf(APIIncident); - }); - }); -}); diff --git a/tests/Client#getBoosters.js b/tests/Client#getBoosters.js deleted file mode 100644 index c2b1cee7a..000000000 --- a/tests/Client#getBoosters.js +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getBoosters', async () => { - let boosters; - it('expect not to throw', async () => { - boosters = await client.getBoosters(); - }); - it('should be an array', () => { - expect(boosters).to.be.an('array'); - }); - it('required keys should exist', () => { - boosters.forEach((booster) => { - expect(booster).to.have.property('purchaser').that.is.a('string'); - expect(booster).to.have.property('amount').that.is.a('number'); - expect(booster).to.have.property('originalLength').that.is.a('number'); - expect(booster).to.have.property('remaining').that.is.a('number'); - expect(booster).to.have.property('activatedTimestamp').that.is.a('number'); - expect(booster).to.have.property('activated').that.is.a('Date'); - expect(booster).to.have.property('isActive').that.is.a('boolean'); - expect(booster).to.have.property('type').that.is.oneOf(['QUEUED', 'STACKED', 'ACTIVE']); - expect(booster).to.have.property('stackers').that.is.an('array'); - expect(booster).to.have.property('expired').that.is.a('boolean'); - }); - }); -}); diff --git a/tests/Client#getChallenges.js b/tests/Client#getChallenges.js deleted file mode 100644 index c352d1418..000000000 --- a/tests/Client#getChallenges.js +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable no-undef */ -const { GameChallenges } = require('../src/index.js'); -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getChallenges', async () => { - let challenges; - it('expect not to throw', async () => { - challenges = await client.getChallenges(); - }); - it('should be an objecct', () => { - expect(challenges).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(challenges.lastUpdatedTimestamp).to.be.a('number'); - expect(challenges.lastUpdatedAt).to.be.a('date'); - expect(challenges.challengesPerGame).to.be.an('object'); - expect(challenges.challengesPerGame.arcade).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.arena).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.bedwars).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.hungergames).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.buildbattle).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.truecombat).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.duels).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.mcgo).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.murdermystery).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.paintball).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.quake).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.skyclash).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.skywars).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.supersmash).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.speeduhc).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.gingerbread).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.tntgames).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.uhc).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.vampirez).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.walls3).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.walls).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.battleground).instanceOf(GameChallenges); - expect(challenges.challengesPerGame.woolgames).instanceOf(GameChallenges); - }); -}); diff --git a/tests/Client#getGameCounts.js b/tests/Client#getGameCounts.js deleted file mode 100644 index 0502f8abd..000000000 --- a/tests/Client#getGameCounts.js +++ /dev/null @@ -1,242 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getGameCounts', async () => { - let gameCounts; - it('expect not to throw', async () => { - gameCounts = await client.getGameCounts(); - }); - it('should be an object ', () => { - expect(gameCounts).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(gameCounts.playerCount).to.be.a('number'); - - expect(gameCounts.mainLobby).to.be.a('object'); - expect(gameCounts.mainLobby.players).to.be.a('number'); - - if (gameCounts.tournamentLobby) { - expect(gameCounts.tournamentLobby).to.be.a('object'); - expect(gameCounts.tournamentLobby.players).to.be.a('number'); - } - - if (gameCounts.smp) { - expect(gameCounts.smp).to.be.a('object'); - expect(gameCounts.smp.players).to.be.a('number'); - } - - if (gameCounts.bedwars) { - expect(gameCounts.bedwars).to.be.a('object'); - expect(gameCounts.bedwars.players).to.be.a('number'); - if (gameCounts.bedwars.modes) { - expect(gameCounts.bedwars.modes).to.be.a('object'); - for (const mode in gameCounts.bedwars.modes) { - expect(gameCounts.bedwars.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.thePit) { - expect(gameCounts.thePit).to.be.a('object'); - expect(gameCounts.thePit.players).to.be.a('number'); - if (gameCounts.thePit.modes) { - expect(gameCounts.thePit.modes).to.be.a('object'); - for (const mode in gameCounts.thePit.modes) { - expect(gameCounts.thePit.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.theTntGames) { - expect(gameCounts.theTntGames).to.be.a('object'); - expect(gameCounts.theTntGames.players).to.be.a('number'); - if (gameCounts.theTntGames.modes) { - expect(gameCounts.theTntGames.modes).to.be.a('object'); - for (const mode in gameCounts.theTntGames.modes) { - expect(gameCounts.theTntGames.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.classicGames) { - expect(gameCounts.classicGames).to.be.a('object'); - expect(gameCounts.classicGames.players).to.be.a('number'); - if (gameCounts.classicGames.modes) { - expect(gameCounts.classicGames.modes).to.be.a('object'); - for (const mode in gameCounts.classicGames.modes) { - expect(gameCounts.classicGames.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.warlords) { - expect(gameCounts.warlords).to.be.a('object'); - expect(gameCounts.warlords.players).to.be.a('number'); - } - - if (gameCounts.duels) { - expect(gameCounts.duels).to.be.a('object'); - expect(gameCounts.duels.players).to.be.a('number'); - if (gameCounts.duels.modes) { - expect(gameCounts.duels.modes).to.be.a('object'); - for (const mode in gameCounts.duels.modes) { - expect(gameCounts.duels.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.smashHeroes) { - expect(gameCounts.smashHeroes).to.be.a('object'); - expect(gameCounts.smashHeroes.players).to.be.a('number'); - if (gameCounts.smashHeroes.modes) { - expect(gameCounts.smashHeroes.modes).to.be.a('object'); - for (const mode in gameCounts.smashHeroes.modes) { - expect(gameCounts.smashHeroes.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.skyblock) { - expect(gameCounts.skyblock).to.be.a('object'); - expect(gameCounts.skyblock.players).to.be.a('number'); - if (gameCounts.skyblock.modes) { - expect(gameCounts.skyblock.modes).to.be.a('object'); - for (const mode in gameCounts.skyblock.modes) { - expect(gameCounts.skyblock.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.uhcChampions) { - expect(gameCounts.uhcChampions).to.be.a('object'); - expect(gameCounts.uhcChampions.players).to.be.a('number'); - if (gameCounts.uhcChampions.modes) { - expect(gameCounts.uhcChampions.modes).to.be.a('object'); - for (const mode in gameCounts.uhcChampions.modes) { - expect(gameCounts.uhcChampions.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.blitzSurvivalGames) { - expect(gameCounts.blitzSurvivalGames).to.be.a('object'); - expect(gameCounts.blitzSurvivalGames.players).to.be.a('number'); - if (gameCounts.blitzSurvivalGames.modes) { - expect(gameCounts.blitzSurvivalGames.modes).to.be.a('object'); - for (const mode in gameCounts.blitzSurvivalGames.modes) { - expect(gameCounts.blitzSurvivalGames.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.murderMystery) { - expect(gameCounts.murderMystery).to.be.a('object'); - expect(gameCounts.murderMystery.players).to.be.a('number'); - if (gameCounts.murderMystery.modes) { - expect(gameCounts.murderMystery.modes).to.be.a('object'); - for (const mode in gameCounts.murderMystery.modes) { - expect(gameCounts.murderMystery.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.speedUhc) { - expect(gameCounts.speedUhc).to.be.a('object'); - expect(gameCounts.speedUhc.players).to.be.a('number'); - } - - if (gameCounts.copsAndCrims) { - expect(gameCounts.copsAndCrims).to.be.a('object'); - expect(gameCounts.copsAndCrims.players).to.be.a('number'); - if (gameCounts.copsAndCrims.modes) { - expect(gameCounts.copsAndCrims.modes).to.be.a('object'); - for (const mode in gameCounts.copsAndCrims.modes) { - expect(gameCounts.copsAndCrims.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.skywars) { - expect(gameCounts.skywars).to.be.a('object'); - expect(gameCounts.skywars.players).to.be.a('number'); - if (gameCounts.skywars.modes) { - expect(gameCounts.skywars.modes).to.be.a('object'); - for (const mode in gameCounts.skywars.modes) { - expect(gameCounts.skywars.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.replay) { - expect(gameCounts.replay).to.be.a('object'); - expect(gameCounts.replay.players).to.be.a('number'); - if (gameCounts.replay.modes) { - expect(gameCounts.replay.modes).to.be.a('object'); - for (const mode in gameCounts.replay.modes) { - expect(gameCounts.replay.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.arcade) { - expect(gameCounts.arcade).to.be.a('object'); - expect(gameCounts.arcade.players).to.be.a('number'); - if (gameCounts.arcade.modes) { - expect(gameCounts.arcade.modes).to.be.a('object'); - for (const mode in gameCounts.arcade.modes) { - expect(gameCounts.arcade.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.woolGames) { - expect(gameCounts.woolGames).to.be.a('object'); - expect(gameCounts.woolGames.players).to.be.a('number'); - if (gameCounts.woolGames.modes) { - expect(gameCounts.woolGames.modes).to.be.a('object'); - for (const mode in gameCounts.woolGames.modes) { - expect(gameCounts.woolGames.modes[mode]).to.be.a('number'); - } - } - } - - if (gameCounts.housing) { - expect(gameCounts.housing).to.be.a('object'); - expect(gameCounts.housing.players).to.be.a('number'); - } - - if (gameCounts.megaWalls) { - expect(gameCounts.megaWalls).to.be.a('object'); - expect(gameCounts.megaWalls.players).to.be.a('number'); - expect(gameCounts.megaWalls.modes).to.be.a('object'); - for (const mode in gameCounts.megaWalls.modes) { - expect(gameCounts.megaWalls.modes[mode]).to.be.a('number'); - } - } - - if (gameCounts.buildBattle) { - expect(gameCounts.buildBattle).to.be.a('object'); - expect(gameCounts.buildBattle.players).to.be.a('number'); - expect(gameCounts.buildBattle.modes).to.be.a('object'); - for (const mode in gameCounts.buildBattle.modes) { - expect(gameCounts.buildBattle.modes[mode]).to.be.a('number'); - } - } - - if (gameCounts.limbo) { - expect(gameCounts.limbo).to.be.a('object'); - expect(gameCounts.limbo.players).to.be.a('number'); - } - - if (gameCounts.idle) { - expect(gameCounts.idle).to.be.a('object'); - expect(gameCounts.idle.players).to.be.a('number'); - } - - if (gameCounts.queue) { - expect(gameCounts.queue).to.be.a('object'); - expect(gameCounts.queue.players).to.be.a('number'); - } - }); -}); diff --git a/tests/Client#getGuild.js b/tests/Client#getGuild.js deleted file mode 100644 index 0a5ebc762..000000000 --- a/tests/Client#getGuild.js +++ /dev/null @@ -1,416 +0,0 @@ -/* eslint-disable no-undef */ -const { guilds, invalid } = require('./data.js'); -const { Game, Errors } = require('../src'); -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getGuild', async () => { - describe('Valid', async () => { - guilds.forEach((guild) => { - let guildName; - let guildId; - let guildPlayer; - describe(`Guild Test ${guilds.indexOf(guild) + 1}`, async () => { - describe('Guild Name', async () => { - it('expect not to throw', async () => { - guildName = await client.getGuild('name', guild.name); - }); - it('should be an object', () => { - expect(guildName).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(guildName.id).to.be.a('string'); - expect(guildName.name).to.be.a('string'); - expect(guildName.description).to.be.a('string'); - expect(guildName.experience).to.be.a('number'); - expect(guildName.level).to.be.a('number'); - expect(guildName.members).to.be.an('array'); - guildName.members.forEach((member) => { - expect(member).to.be.an('object'); - expect(member.uuid).to.be.a('string'); - expect(member.joinedAtTimestamp).to.be.a('number'); - expect(member.joinedAt).to.be.a('Date'); - expect(member.questParticipation).to.be.a('number'); - expect(member.rank).to.be.a('string'); - expect(member.expHistory).to.be.a('array'); - member.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(member.weeklyExperience).to.be.a('number'); - }); - if (guildName.me) { - expect(guildName.me).to.be.an('object'); - expect(guildName.me.uuid).to.be.a('string'); - expect(guildName.me.joinedAtTimestamp).to.be.a('number'); - expect(guildName.me.joinedAt).to.be.a('Date'); - expect(guildName.me.questParticipation).to.be.a('number'); - expect(guildName.me.rank).to.be.a('string'); - expect(guildName.me.expHistory).to.be.a('array'); - guildName.me.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(guildName.me.weeklyExperience).to.be.a('number'); - } - expect(guildName.ranks).to.be.an('array'); - guildName.ranks.forEach((rank) => { - expect(rank).to.be.an('object'); - expect(rank.name).to.be.a('string'); - expect(rank.default).to.be.a('boolean'); - if (rank.tag) expect(rank.tag).to.be.a('string'); - expect(rank.createdAt).to.be.a('date'); - expect(rank.createdAtTimestamp).to.be.a('number'); - expect(rank.priority).to.be.a('number'); - }); - expect(guildName.totalWeeklyGexp).to.be.a('number'); - expect(guildName.createdAtTimestamp).to.be.a('number'); - expect(guildName.createdAt).to.be.a('date'); - expect(guildName.joinable).to.be.a('boolean'); - expect(guildName.publiclyListed).to.be.a('boolean'); - if (guildName.banner) { - expect(guildName.banner).to.be.a('object'); - expect(guildName.banner['Base']).to.be.a('string'); - expect(guildName.banner['Patterns']).to.be.an('array'); - guildName.banner['Patterns'].forEach((pattern) => { - expect(pattern).to.be.a('object'); - expect(pattern['Pattern']).to.be.a('string'); - expect(pattern['Color']).that.satisfies( - (value) => typeof value === 'number' || typeof value === 'string' - ); - }); - } - if (guildName.tag) expect(guildName.tag).to.be.a('string'); - if (guildName.tagColor) { - expect(guildName.tagColor.color).to.be.a('string'); - expect(guildName.tagColor.color).to.be.oneOf([ - 'BLACK', - 'DARK_BLUE', - 'DARK_GREEN', - 'DARK_AQUA', - 'DARK_RED', - 'DARK_PURPLE', - 'GOLD', - 'GRAY', - 'DARK_GRAY', - 'BLUE', - 'GREEN', - 'AQUA', - 'RED', - 'LIGHT_PURPLE', - 'YELLOW', - 'WHITE' - ]); - } - expect(guildName.legacyRank).to.be.a('number'); - expect(guildName.expHistory).to.be.a('array'); - guildName.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - expect(guildName.achievements).to.be.a('object'); - expect(guildName.achievements.winners).to.be.a('number'); - expect(guildName.achievements.experienceKings).to.be.a('number'); - expect(guildName.achievements.onlinePlayers).to.be.a('number'); - expect(guildName.preferredGames).to.be.an('array'); - guildName.preferredGames.forEach((game) => { - expect(game).instanceOf(Game); - }); - }); - }); - }); - describe('Guild Id', async () => { - it('expect not to throw', async () => { - guildId = await client.getGuild('id', guild.id); - }); - it('should be an object', () => { - expect(guildId).to.be.an('object'); - }); - - it('required keys should exist', () => { - expect(guildId.id).to.be.a('string'); - expect(guildId.name).to.be.a('string'); - expect(guildId.description).to.be.a('string'); - expect(guildId.experience).to.be.a('number'); - expect(guildId.level).to.be.a('number'); - expect(guildId.members).to.be.an('array'); - guildId.members.forEach((member) => { - expect(member).to.be.an('object'); - expect(member.uuid).to.be.a('string'); - expect(member.joinedAtTimestamp).to.be.a('number'); - expect(member.joinedAt).to.be.a('Date'); - expect(member.questParticipation).to.be.a('number'); - expect(member.rank).to.be.a('string'); - expect(member.expHistory).to.be.a('array'); - member.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(member.weeklyExperience).to.be.a('number'); - }); - if (guildId.me) { - expect(guildId.me).to.be.an('object'); - expect(guildId.me.uuid).to.be.a('string'); - expect(guildId.me.joinedAtTimestamp).to.be.a('number'); - expect(guildId.me.joinedAt).to.be.a('Date'); - expect(guildId.me.questParticipation).to.be.a('number'); - expect(guildId.me.rank).to.be.a('string'); - expect(guildId.me.expHistory).to.be.a('array'); - guildId.me.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(guildId.me.weeklyExperience).to.be.a('number'); - } - expect(guildId.ranks).to.be.an('array'); - guildId.ranks.forEach((rank) => { - expect(rank).to.be.an('object'); - expect(rank.name).to.be.a('string'); - expect(rank.default).to.be.a('boolean'); - if (rank.tag) expect(rank.tag).to.be.a('string'); - expect(rank.createdAt).to.be.a('date'); - expect(rank.createdAtTimestamp).to.be.a('number'); - expect(rank.priority).to.be.a('number'); - }); - expect(guildId.totalWeeklyGexp).to.be.a('number'); - expect(guildId.createdAtTimestamp).to.be.a('number'); - expect(guildId.createdAt).to.be.a('date'); - expect(guildId.joinable).to.be.a('boolean'); - expect(guildId.publiclyListed).to.be.a('boolean'); - if (guildId.banner) { - expect(guildId.banner).to.be.a('object'); - expect(guildId.banner['Base']).to.be.a('string'); - expect(guildId.banner['Patterns']).to.be.an('array'); - guildId.banner['Patterns'].forEach((pattern) => { - expect(pattern).to.be.a('object'); - expect(pattern['Pattern']).to.be.a('string'); - expect(pattern['Color']).that.satisfies( - (value) => typeof value === 'number' || typeof value === 'string' - ); - }); - } - if (guildId.tag) expect(guildId.tag).to.be.a('string'); - if (guildId.tagColor) { - expect(guildId.tagColor.color).to.be.a('string'); - expect(guildId.tagColor.color).to.be.oneOf([ - 'BLACK', - 'DARK_BLUE', - 'DARK_GREEN', - 'DARK_AQUA', - 'DARK_RED', - 'DARK_PURPLE', - 'GOLD', - 'GRAY', - 'DARK_GRAY', - 'BLUE', - 'GREEN', - 'AQUA', - 'RED', - 'LIGHT_PURPLE', - 'YELLOW', - 'WHITE' - ]); - } - expect(guildId.legacyRank).to.be.a('number'); - expect(guildId.expHistory).to.be.a('array'); - guildId.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - expect(guildId.achievements).to.be.a('object'); - expect(guildId.achievements.winners).to.be.a('number'); - expect(guildId.achievements.experienceKings).to.be.a('number'); - expect(guildId.achievements.onlinePlayers).to.be.a('number'); - expect(guildId.preferredGames).to.be.an('array'); - guildId.preferredGames.forEach((game) => { - expect(game).instanceOf(Game); - }); - }); - }); - }); - describe('Guild Player', async () => { - it('expect not to throw', async () => { - guildPlayer = await client.getGuild('player', guild.uuid); - }); - it('should be an object', () => { - expect(guildPlayer).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(guildPlayer.id).to.be.a('string'); - expect(guildPlayer.name).to.be.a('string'); - expect(guildPlayer.description).to.be.a('string'); - expect(guildPlayer.experience).to.be.a('number'); - expect(guildPlayer.level).to.be.a('number'); - expect(guildPlayer.members).to.be.an('array'); - guildPlayer.members.forEach((member) => { - expect(member).to.be.an('object'); - expect(member.uuid).to.be.a('string'); - expect(member.joinedAtTimestamp).to.be.a('number'); - expect(member.joinedAt).to.be.a('Date'); - expect(member.questParticipation).to.be.a('number'); - expect(member.rank).to.be.a('string'); - expect(member.expHistory).to.be.a('array'); - member.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(member.weeklyExperience).to.be.a('number'); - }); - if (guildPlayer.me) { - expect(guildPlayer.me).to.be.an('object'); - expect(guildPlayer.me.uuid).to.be.a('string'); - expect(guildPlayer.me.joinedAtTimestamp).to.be.a('number'); - expect(guildPlayer.me.joinedAt).to.be.a('Date'); - expect(guildPlayer.me.questParticipation).to.be.a('number'); - expect(guildPlayer.me.rank).to.be.a('string'); - expect(guildPlayer.me.expHistory).to.be.a('array'); - guildPlayer.me.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - }); - expect(guildPlayer.me.weeklyExperience).to.be.a('number'); - } - expect(guildPlayer.ranks).to.be.an('array'); - guildPlayer.ranks.forEach((rank) => { - expect(rank).to.be.an('object'); - expect(rank.name).to.be.a('string'); - expect(rank.default).to.be.a('boolean'); - if (rank.tag) expect(rank.tag).to.be.a('string'); - expect(rank.createdAt).to.be.a('date'); - expect(rank.createdAtTimestamp).to.be.a('number'); - expect(rank.priority).to.be.a('number'); - }); - expect(guildPlayer.totalWeeklyGexp).to.be.a('number'); - expect(guildPlayer.createdAtTimestamp).to.be.a('number'); - expect(guildPlayer.createdAt).to.be.a('date'); - expect(guildPlayer.joinable).to.be.a('boolean'); - expect(guildPlayer.publiclyListed).to.be.a('boolean'); - if (guildPlayer.banner) { - expect(guildPlayer.banner).to.be.a('object'); - expect(guildPlayer.banner['Base']).to.be.a('string'); - expect(guildPlayer.banner['Patterns']).to.be.an('array'); - guildPlayer.banner['Patterns'].forEach((pattern) => { - expect(pattern).to.be.a('object'); - expect(pattern['Pattern']).to.be.a('string'); - expect(pattern['Color']).that.satisfies( - (value) => typeof value === 'number' || typeof value === 'string' - ); - }); - } - if (guildPlayer.tag) expect(guildPlayer.tag).to.be.a('string'); - if (guildPlayer.tagColor) { - expect(guildPlayer.tagColor.color).to.be.a('string'); - expect(guildPlayer.tagColor.color).to.be.oneOf([ - 'BLACK', - 'DARK_BLUE', - 'DARK_GREEN', - 'DARK_AQUA', - 'DARK_RED', - 'DARK_PURPLE', - 'GOLD', - 'GRAY', - 'DARK_GRAY', - 'BLUE', - 'GREEN', - 'AQUA', - 'RED', - 'LIGHT_PURPLE', - 'YELLOW', - 'WHITE' - ]); - } - expect(guildPlayer.legacyRank).to.be.a('number'); - expect(guildPlayer.expHistory).to.be.a('array'); - guildPlayer.expHistory.forEach((history) => { - expect(history).to.be.a('object'); - expect(history.day).to.be.a('string'); - expect(history.date).to.be.a('date'); - expect(history.exp).to.be.a('number'); - expect(history.totalExp).to.be.a('number'); - expect(guildPlayer.achievements).to.be.a('object'); - expect(guildPlayer.achievements.winners).to.be.a('number'); - expect(guildPlayer.achievements.experienceKings).to.be.a('number'); - expect(guildPlayer.achievements.onlinePlayers).to.be.a('number'); - expect(guildPlayer.preferredGames).to.be.an('array'); - guildPlayer.preferredGames.forEach((game) => { - expect(game).instanceOf(Game); - }); - }); - }); - }); - }); - }); - }); - describe('Invalid', async () => { - describe('Guild Name Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getGuild('name', 'This is not a valid guild name'); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.GUILD_DOES_NOT_EXIST); - } - }).timeout(5000); - }); - describe('Player not in guild', async () => { - invalid.noGuild.forEach((user) => { - it('expect to throw', async () => { - player = await client.getGuild('player', user.uuid); - expect(player).to.be.null; - }).timeout(5000); - }); - }); - describe('Guild id Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getGuild('id', 'This is not a valid guild id'); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.INVALID_GUILD_ID); - } - }).timeout(5000); - }); - describe('No input Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getGuild(); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.NO_GUILD_QUERY); - } - }).timeout(5000); - }); - describe('Bad guild search', async () => { - it('expect to throw', async () => { - try { - player = await client.getGuild('test', 'no'); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.INVALID_GUILD_SEARCH_PARAMETER); - } - }).timeout(5000); - }); - }); -}); diff --git a/tests/Client#getLeaderboards.js b/tests/Client#getLeaderboards.js deleted file mode 100644 index 34450a277..000000000 --- a/tests/Client#getLeaderboards.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getLeaderboards', async () => { - let leaderboards; - it('expect not to throw', async () => { - leaderboards = await client.getLeaderboards(); - }); - it('should be an object', () => { - expect(leaderboards).to.be.an('object'); - }); - it('required keys should exist', () => { - for (const minigame in leaderboards) { - const minigameLbs = leaderboards[minigame]; - for (const lb of minigameLbs) { - expect(lb).to.be.an('object'); - expect(lb.leaders).to.be.an('array'); - expect(lb.playerCount).to.be.a('number'); - if (lb.name) { - expect(lb.name).to.be.a('string'); - } - if (lb.title) { - expect(lb.title).to.be.a('string'); - } - } - } - }); -}); diff --git a/tests/Client#getPlayer.js b/tests/Client#getPlayer.js deleted file mode 100644 index 945c25f23..000000000 --- a/tests/Client#getPlayer.js +++ /dev/null @@ -1,467 +0,0 @@ -/* eslint-disable no-undef */ -const { - Game, - SkyWars, - BedWars, - UHC, - SpeedUHC, - MurderMystery, - Duels, - BuildBattle, - MegaWalls, - CopsAndCrims, - TNTGames, - SmashHeroes, - VampireZ, - BlitzSurvivalGames, - ArenaBrawl, - Guild, - PlayerCosmetics, - Pets, - Pet, - Color, - WoolGames, - Errors, - Player -} = require('../src'); -const { client } = require('./Client.js'); -const { users } = require('./data.js'); -const { expect } = require('chai'); - -describe('Client#getPlayer', () => { - describe('Valid Player', async () => { - users.forEach((user) => { - let playerTest; - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - it('expect not to throw', async () => { - playerTest = await client.getPlayer(user.uuid, { guild: true }); - }).timeout(5000); - it('should be an object', () => { - expect(playerTest).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(playerTest).to.be.instanceOf(Player); - expect(playerTest.nickname).to.be.a('string'); - expect(playerTest.uuid).to.be.a('string'); - expect(playerTest.rank).to.be.a('string'); - if (playerTest.mcVersion) { - expect(playerTest.mcVersion).to.be.a('string'); - } - if (playerTest.firstLoginTimestamp) { - expect(playerTest.firstLoginTimestamp).to.be.a('number'); - } - if (playerTest.lastLoginTimestamp) { - expect(playerTest.lastLoginTimestamp).to.be.a('number'); - } - if (playerTest.lastLogoutTimestamp) { - expect(playerTest.lastLogoutTimestamp).to.be.a('number'); - } - if (playerTest.recentlyPlayedGame) { - expect(playerTest.recentlyPlayedGame).instanceOf(Game); - } - if (playerTest.plusColor) { - expect(playerTest.plusColor).instanceOf(Color); - } - if (playerTest.guild) { - expect(playerTest.guild).instanceOf(Guild); - } - expect(playerTest.karma).to.be.a('number'); - expect(playerTest.achievementPoints).to.be.a('number'); - expect(playerTest.totalExperience).to.be.a('number'); - expect(playerTest.level).to.be.a('number'); - expect(playerTest.socialMedia).to.be.an('array'); - if (playerTest.giftsSent) { - expect(playerTest.giftsSent).to.be.a('number'); - } - if (playerTest.giftsReceived) { - expect(playerTest.giftsReceived).to.be.a('number'); - } - if (playerTest.lastDailyRewardTimestamp) { - expect(playerTest.lastDailyRewardTimestamp).to.be.a('number'); - } - expect(playerTest.userLanguage).to.be.a('string'); - if (playerTest.claimedLevelingRewards.length) { - expect(playerTest.claimedLevelingRewards) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'number'); - }); - } - if (playerTest.globalCosmetics) { - expect(playerTest.globalCosmetics).to.be.instanceOf(PlayerCosmetics); - expect(playerTest.globalCosmetics.allCosmetics) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - if (playerTest.globalCosmetics.petManager) { - expect(playerTest.globalCosmetics.petManager).to.be.instanceOf(Pets); - expect(playerTest.globalCosmetics.petManager.pets) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => i instanceof Pet); - }); - if (playerTest.globalCosmetics.petManager.lastJourneyTimestamp) { - expect(playerTest.globalCosmetics.petManager.lastJourneyTimestamp).to.be.a('number'); - } - if (playerTest.globalCosmetics.petManager.lastJourneyAt) { - expect(playerTest.globalCosmetics.petManager.lastJourneyAt).to.be.instanceOf(Date); - } - if (playerTest.globalCosmetics.petManager.petConsumables) { - expect(playerTest.globalCosmetics.petManager.petConsumables).to.be.an('object'); - } - } - if (playerTest.globalCosmetics.suits) { - expect(playerTest.globalCosmetics.suits) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.hats) { - expect(playerTest.globalCosmetics.hats) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.gadgets) { - expect(playerTest.globalCosmetics.gadgets) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.morphs) { - expect(playerTest.globalCosmetics.morphs) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.cloaks) { - expect(playerTest.globalCosmetics.cloaks) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.rankColors) { - expect(playerTest.globalCosmetics.rankColors) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.particlePacks) { - expect(playerTest.globalCosmetics.particlePacks) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.clickEffects) { - expect(playerTest.globalCosmetics.clickEffects) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - } - if (playerTest.ranksPurchaseTime) { - if (playerTest.ranksPurchaseTime['VIP']) { - expect(playerTest.ranksPurchaseTime['VIP']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['VIP_PLUS']) { - expect(playerTest.ranksPurchaseTime['VIP_PLUS']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['MVP']) { - expect(playerTest.ranksPurchaseTime['MVP']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['MVP_PLUS']) { - expect(playerTest.ranksPurchaseTime['MVP_PLUS']).to.be.instanceOf(Date); - } - } - if (playerTest.stats) { - if (playerTest.stats.skywars) { - expect(playerTest.stats.skywars).instanceOf(SkyWars); - } - if (playerTest.stats.bedwars) { - expect(playerTest.stats.bedwars).instanceOf(BedWars); - } - if (playerTest.stats.uhc) { - expect(playerTest.stats.uhc).instanceOf(UHC); - } - if (playerTest.stats.speeduhc) { - expect(playerTest.stats.speeduhc).instanceOf(SpeedUHC); - } - if (playerTest.stats.murdermystery) { - expect(playerTest.stats.murdermystery).instanceOf(MurderMystery); - } - if (playerTest.stats.duels) { - expect(playerTest.stats.duels).instanceOf(Duels); - } - if (playerTest.stats.buildbattle) { - expect(playerTest.stats.buildbattle).instanceOf(BuildBattle); - } - if (playerTest.stats.megawalls) { - expect(playerTest.stats.megawalls).instanceOf(MegaWalls); - } - if (playerTest.stats.copsandcrims) { - expect(playerTest.stats.copsandcrims).instanceOf(CopsAndCrims); - } - if (playerTest.stats.tntgames) { - expect(playerTest.stats.tntgames).instanceOf(TNTGames); - } - if (playerTest.stats.smashheroes) { - expect(playerTest.stats.smashheroes).instanceOf(SmashHeroes); - } - if (playerTest.stats.vampirez) { - expect(playerTest.stats.vampirez).instanceOf(VampireZ); - } - if (playerTest.stats.blitzsg) { - expect(playerTest.stats.blitzsg).instanceOf(BlitzSurvivalGames); - } - if (playerTest.stats.arena) { - expect(playerTest.stats.arena).instanceOf(ArenaBrawl); - } - if (playerTest.stats.woolgames) { - expect(playerTest.stats.woolgames).instanceOf(WoolGames); - } - } - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - it('expect not to throw', async () => { - playerTest = await client.getPlayer(user.username, { guild: true }); - }).timeout(5000); - it('should be an object', () => { - expect(playerTest).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(playerTest).to.be.instanceOf(Player); - expect(playerTest.nickname).to.be.a('string'); - expect(playerTest.uuid).to.be.a('string'); - expect(playerTest.rank).to.be.a('string'); - if (playerTest.mcVersion) { - expect(playerTest.mcVersion).to.be.a('string'); - } - if (playerTest.firstLoginTimestamp) { - expect(playerTest.firstLoginTimestamp).to.be.a('number'); - } - if (playerTest.lastLoginTimestamp) { - expect(playerTest.lastLoginTimestamp).to.be.a('number'); - } - if (playerTest.lastLogoutTimestamp) { - expect(playerTest.lastLogoutTimestamp).to.be.a('number'); - } - if (playerTest.recentlyPlayedGame) { - expect(playerTest.recentlyPlayedGame).instanceOf(Game); - } - if (playerTest.plusColor) { - expect(playerTest.plusColor).instanceOf(Color); - } - if (playerTest.guild) { - expect(playerTest.guild).instanceOf(Guild); - } - expect(playerTest.karma).to.be.a('number'); - expect(playerTest.achievementPoints).to.be.a('number'); - expect(playerTest.totalExperience).to.be.a('number'); - expect(playerTest.level).to.be.a('number'); - expect(playerTest.socialMedia).to.be.an('array'); - if (playerTest.giftsSent) { - expect(playerTest.giftsSent).to.be.a('number'); - } - if (playerTest.giftsReceived) { - expect(playerTest.giftsReceived).to.be.a('number'); - } - if (playerTest.lastDailyRewardTimestamp) { - expect(playerTest.lastDailyRewardTimestamp).to.be.a('number'); - } - expect(playerTest.userLanguage).to.be.a('string'); - if (playerTest.claimedLevelingRewards.length) { - expect(playerTest.claimedLevelingRewards) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'number'); - }); - } - if (playerTest.globalCosmetics) { - expect(playerTest.globalCosmetics).to.be.instanceOf(PlayerCosmetics); - expect(playerTest.globalCosmetics.allCosmetics) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - if (playerTest.globalCosmetics.petManager) { - expect(playerTest.globalCosmetics.petManager).to.be.instanceOf(Pets); - expect(playerTest.globalCosmetics.petManager.pets) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => i instanceof Pet); - }); - if (playerTest.globalCosmetics.petManager.lastJourneyTimestamp) { - expect(playerTest.globalCosmetics.petManager.lastJourneyTimestamp).to.be.a('number'); - } - if (playerTest.globalCosmetics.petManager.lastJourneyAt) { - expect(playerTest.globalCosmetics.petManager.lastJourneyAt).to.be.instanceOf(Date); - } - if (playerTest.globalCosmetics.petManager.petConsumables) { - expect(playerTest.globalCosmetics.petManager.petConsumables).to.be.an('object'); - } - } - if (playerTest.globalCosmetics.suits) { - expect(playerTest.globalCosmetics.suits) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.hats) { - expect(playerTest.globalCosmetics.hats) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.gadgets) { - expect(playerTest.globalCosmetics.gadgets) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.morphs) { - expect(playerTest.globalCosmetics.morphs) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.cloaks) { - expect(playerTest.globalCosmetics.cloaks) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.rankColors) { - expect(playerTest.globalCosmetics.rankColors) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.particlePacks) { - expect(playerTest.globalCosmetics.particlePacks) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - if (playerTest.globalCosmetics.clickEffects) { - expect(playerTest.globalCosmetics.clickEffects) - .to.be.an('array') - .that.satisfies((v) => { - return v.every((i) => typeof i === 'string'); - }); - } - } - if (playerTest.ranksPurchaseTime) { - if (playerTest.ranksPurchaseTime['VIP']) { - expect(playerTest.ranksPurchaseTime['VIP']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['VIP_PLUS']) { - expect(playerTest.ranksPurchaseTime['VIP_PLUS']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['MVP']) { - expect(playerTest.ranksPurchaseTime['MVP']).to.be.instanceOf(Date); - } - if (playerTest.ranksPurchaseTime['MVP_PLUS']) { - expect(playerTest.ranksPurchaseTime['MVP_PLUS']).to.be.instanceOf(Date); - } - } - if (playerTest.stats) { - if (playerTest.stats.skywars) { - expect(playerTest.stats.skywars).instanceOf(SkyWars); - } - if (playerTest.stats.bedwars) { - expect(playerTest.stats.bedwars).instanceOf(BedWars); - } - if (playerTest.stats.uhc) { - expect(playerTest.stats.uhc).instanceOf(UHC); - } - if (playerTest.stats.speeduhc) { - expect(playerTest.stats.speeduhc).instanceOf(SpeedUHC); - } - if (playerTest.stats.murdermystery) { - expect(playerTest.stats.murdermystery).instanceOf(MurderMystery); - } - if (playerTest.stats.duels) { - expect(playerTest.stats.duels).instanceOf(Duels); - } - if (playerTest.stats.buildbattle) { - expect(playerTest.stats.buildbattle).instanceOf(BuildBattle); - } - if (playerTest.stats.megawalls) { - expect(playerTest.stats.megawalls).instanceOf(MegaWalls); - } - if (playerTest.stats.copsandcrims) { - expect(playerTest.stats.copsandcrims).instanceOf(CopsAndCrims); - } - if (playerTest.stats.tntgames) { - expect(playerTest.stats.tntgames).instanceOf(TNTGames); - } - if (playerTest.stats.smashheroes) { - expect(playerTest.stats.smashheroes).instanceOf(SmashHeroes); - } - if (playerTest.stats.vampirez) { - expect(playerTest.stats.vampirez).instanceOf(VampireZ); - } - if (playerTest.stats.blitzsg) { - expect(playerTest.stats.blitzsg).instanceOf(BlitzSurvivalGames); - } - if (playerTest.stats.arena) { - expect(playerTest.stats.arena).instanceOf(ArenaBrawl); - } - if (playerTest.stats.woolgames) { - expect(playerTest.stats.woolgames).instanceOf(WoolGames); - } - } - }); - }); - }); - }); - describe('Invalid Player', async () => { - describe('Invalid Username Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getPlayer('ThisUsernameIsInvalid', { guild: true }); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.PLAYER_DOES_NOT_EXIST); - } - }).timeout(5000); - }); - describe('Invalid UUID Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getPlayer('this-is-not-a-valid-uuid', { guild: true }); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.PLAYER_DOES_NOT_EXIST); - } - }).timeout(5000); - }); - describe('No input Test', async () => { - it('expect to throw', async () => { - try { - player = await client.getPlayer(); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.NO_NICKNAME_UUID); - } - }).timeout(5000); - }); - }); -}); diff --git a/tests/Client#getRecentGames.js b/tests/Client#getRecentGames.js deleted file mode 100644 index 922d460bf..000000000 --- a/tests/Client#getRecentGames.js +++ /dev/null @@ -1,88 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { users } = require('./data.js'); -const { expect } = require('chai'); - -describe('Client#getRecentGames', async () => { - users.forEach((user) => { - let recentGames; - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - it('expect not to throw', async () => { - recentGames = await client.getRecentGames(user.uuid); - }); - it('should be an array', () => { - expect(recentGames).to.be.an('array'); - }); - it('required keys should exist', () => { - if (recentGames.length === 0) return; - recentGames.forEach((game) => { - expect(game).to.have.keys([ - 'game', - 'id', - 'code', - 'name', - 'found', - 'dateTimestamp', - 'date', - 'mode', - 'map', - 'ongoing', - 'endedAt', - 'endedTimestamp' - ]); - expect(game.game).to.be.a('string'); - expect(game.id).to.be.a('number'); - expect(game.code).to.be.a('string'); - expect(game.name).to.be.a('string'); - expect(game.found).to.be.a('boolean'); - expect(game.dateTimestamp).to.be.a('number'); - expect(game.date).to.be.a('date'); - expect(game.mode).to.be.a('string'); - expect(game.map).to.be.a('string'); - expect(game.ongoing).to.be.a('boolean'); - expect(game.endedAt).to.be.a('date'); - expect(game.endedTimestamp).to.be.a('number'); - }); - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - it('expect not to throw', async () => { - recentGames = await client.getRecentGames(user.username); - }); - it('should be an array', () => { - expect(recentGames).to.be.an('array'); - }); - it('required keys should exist', () => { - if (recentGames.length === 0) return; - recentGames.forEach((game) => { - expect(game).to.have.keys([ - 'game', - 'id', - 'code', - 'name', - 'found', - 'dateTimestamp', - 'date', - 'mode', - 'map', - 'ongoing', - 'endedAt', - 'endedTimestamp' - ]); - expect(game.game).to.be.a('string'); - expect(game.id).to.be.a('number'); - expect(game.code).to.be.a('string'); - expect(game.name).to.be.a('string'); - expect(game.found).to.be.a('boolean'); - expect(game.dateTimestamp).to.be.a('number'); - expect(game.date).to.be.a('date'); - expect(game.mode).to.be.a('string'); - expect(game.map).to.be.a('string'); - expect(game.ongoing).to.be.a('boolean'); - expect(game.endedAt).to.be.a('date'); - expect(game.endedTimestamp).to.be.a('number'); - }); - }); - }); - }); -}); diff --git a/tests/Client#getServerInfo.js b/tests/Client#getServerInfo.js deleted file mode 100644 index c6975b6f8..000000000 --- a/tests/Client#getServerInfo.js +++ /dev/null @@ -1,184 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getServerInfo', async () => { - let server; - describe('No amount input test', async () => { - it('expect not to throw', async () => { - server = await client.getServerInfo(); - }); - it('should be an object', () => { - expect(server).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(server.protocolUsed).to.be.a('number'); - expect(server.versionInfo).to.be.a('string'); - expect(server.players).to.be.an('object'); - expect(server.players.max).to.be.a('number'); - expect(server.players.online).to.be.a('number'); - expect(server.players.players).to.be.an('array'); - if (server.rawMOTD) { - expect(server.rawMOTD).to.be.a('string'); - } - if (server.cleanMOTD) { - expect(server.cleanMOTD).to.be.a('string'); - } - if (server.textMOTD) { - expect(server.textMOTD).to.be.a('string'); - } - if (server.faviconB64) { - expect(server.faviconB64).to.be.a('string'); - } - if (server.favicon) { - expect(server.favicon).to.be.instanceOf(Buffer); - } - if (server.ping) { - expect(server.ping).to.be.a('number'); - } - }); - }); - server; - describe('Number', async () => { - describe('Valid amount test', async () => { - it('expect not to throw', async () => { - server = await client.getServerInfo(2); - }); - it('should be an object', () => { - expect(server).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(server.protocolUsed).to.be.a('number'); - expect(server.versionInfo).to.be.a('string'); - expect(server.players).to.be.an('object'); - expect(server.players.max).to.be.a('number'); - expect(server.players.online).to.be.a('number'); - expect(server.players.players).to.be.an('array'); - if (server.rawMOTD) { - expect(server.rawMOTD).to.be.a('string'); - } - if (server.cleanMOTD) { - expect(server.cleanMOTD).to.be.a('string'); - } - if (server.textMOTD) { - expect(server.textMOTD).to.be.a('string'); - } - if (server.faviconB64) { - expect(server.faviconB64).to.be.a('string'); - } - if (server.favicon) { - expect(server.favicon).to.be.instanceOf(Buffer); - } - if (server.ping) { - expect(server.ping).to.be.a('number'); - } - }); - }); - server; - describe('Invalid input test', async () => { - it('expect not to throw', async () => { - server = await client.getServerInfo(-1); - }); - it('should be an object', () => { - expect(server).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(server.protocolUsed).to.be.a('number'); - expect(server.versionInfo).to.be.a('string'); - expect(server.players).to.be.an('object'); - expect(server.players.max).to.be.a('number'); - expect(server.players.online).to.be.a('number'); - expect(server.players.players).to.be.an('array'); - if (server.rawMOTD) { - expect(server.rawMOTD).to.be.a('string'); - } - if (server.cleanMOTD) { - expect(server.cleanMOTD).to.be.a('string'); - } - if (server.textMOTD) { - expect(server.textMOTD).to.be.a('string'); - } - if (server.faviconB64) { - expect(server.faviconB64).to.be.a('string'); - } - if (server.favicon) { - expect(server.favicon).to.be.instanceOf(Buffer); - } - if (server.ping) { - expect(server.ping).to.be.a('number'); - } - }); - }); - }); - describe('String', async () => { - describe('Valid amount test', async () => { - it('expect not to throw', async () => { - server = await client.getServerInfo('2'); - }); - it('should be an object', () => { - expect(server).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(server.protocolUsed).to.be.a('number'); - expect(server.versionInfo).to.be.a('string'); - expect(server.players).to.be.an('object'); - expect(server.players.max).to.be.a('number'); - expect(server.players.online).to.be.a('number'); - expect(server.players.players).to.be.an('array'); - if (server.rawMOTD) { - expect(server.rawMOTD).to.be.a('string'); - } - if (server.cleanMOTD) { - expect(server.cleanMOTD).to.be.a('string'); - } - if (server.textMOTD) { - expect(server.textMOTD).to.be.a('string'); - } - if (server.faviconB64) { - expect(server.faviconB64).to.be.a('string'); - } - if (server.favicon) { - expect(server.favicon).to.be.instanceOf(Buffer); - } - if (server.ping) { - expect(server.ping).to.be.a('number'); - } - }); - }); - server; - describe('Invalid input test', async () => { - it('expect not to throw', async () => { - server = await client.getServerInfo('HI if u see this'); - }); - it('should be an object', () => { - expect(server).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(server.protocolUsed).to.be.a('number'); - expect(server.versionInfo).to.be.a('string'); - expect(server.players).to.be.an('object'); - expect(server.players.max).to.be.a('number'); - expect(server.players.online).to.be.a('number'); - expect(server.players.players).to.be.an('array'); - if (server.rawMOTD) { - expect(server.rawMOTD).to.be.a('string'); - } - if (server.cleanMOTD) { - expect(server.cleanMOTD).to.be.a('string'); - } - if (server.textMOTD) { - expect(server.textMOTD).to.be.a('string'); - } - if (server.faviconB64) { - expect(server.faviconB64).to.be.a('string'); - } - if (server.favicon) { - expect(server.favicon).to.be.instanceOf(Buffer); - } - if (server.ping) { - expect(server.ping).to.be.a('number'); - } - }); - }); - }); -}); diff --git a/tests/Client#getStatus.js b/tests/Client#getStatus.js deleted file mode 100644 index 5418c3e11..000000000 --- a/tests/Client#getStatus.js +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable */ -const { client } = require('./Client.js'); -const { users } = require('./data.js'); -const { Game } = require('../src'); -const { expect } = require('chai'); - -describe('Client#getStatus', () => { - let status; - - users.forEach((user) => { - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - it('expect not to throw', async () => { - status = await client.getStatus(user.uuid); - }); - it('should be an object', () => { - expect(status).to.be.an('object'); - }); - it('required keys should exist', () => { - if (status.online) { - expect(status.online).to.be.a('boolean'); - } - if (status.game) { - expect(status.game).instanceOf(Game); - } - if (status.map) { - expect(status.map).to.be.a('string'); - } - if (status.mode) { - expect(status.mode).to.be.a('string'); - } - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - it('expect not to throw', async () => { - status = await client.getStatus(user.username); - }); - it('should be an object', () => { - expect(status).to.be.an('object'); - }); - it('required keys should exist', () => { - if (status.online) { - expect(status.online).to.be.a('boolean'); - } - if (status.game) { - expect(status.game).instanceOf(Game); - } - if (status.map) { - expect(status.map).to.be.a('string'); - } - if (status.mode) { - expect(status.mode).to.be.a('string'); - } - }); - }); - }); -}); diff --git a/tests/Client#getWatchdogStats.js b/tests/Client#getWatchdogStats.js deleted file mode 100644 index 226b132cd..000000000 --- a/tests/Client#getWatchdogStats.js +++ /dev/null @@ -1,20 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('./Client.js'); -const { expect } = require('chai'); - -describe('Client#getWatchdogStats', () => { - let watchdog; - it('expect not to throw', async () => { - watchdog = await client.getWatchdogStats(); - }); - it('should be an object', () => { - expect(watchdog).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(watchdog.byStaffRollingDay).to.be.a('number'); - expect(watchdog.byStaffTotal).to.be.a('number'); - expect(watchdog.byWatchdogLastMinute).to.be.a('number'); - expect(watchdog.byWatchdogRollingDay).to.be.a('number'); - expect(watchdog.byWatchdogTotal).to.be.a('number'); - }); -}); diff --git a/tests/Client.js b/tests/Client.js deleted file mode 100644 index c71f113d0..000000000 --- a/tests/Client.js +++ /dev/null @@ -1,5 +0,0 @@ -/* eslint-disable no-undef */ -const { Client } = require('../src'); -module.exports = { - client: new Client(process.env.HYPIXEL_KEY) -}; diff --git a/tests/data.js b/tests/data.js deleted file mode 100644 index 27b0b8bcd..000000000 --- a/tests/data.js +++ /dev/null @@ -1,95 +0,0 @@ -/* eslint-disable */ -module.exports = { - users: [ - { - uuid: '37501e7512b845ab8796e2baf9e9677a', - username: 'ILoveWristSpasm', - skyblockProfileId: 'bcd05ba6-908f-4266-8862-c1649c2536a9' - }, - { - uuid: '4982eac19ae7422891b61a17a74c87a2', - username: 'JasperJazzyPants', - skyblockProfileId: '' - }, - { - uuid: '3b76b69ae5134296a730ed49171ad6f8', - username: 'WarOG', - skyblockProfileId: '3775f7d8-ccbc-46e7-bc76-b59a9b5e12d5' - }, - { - uuid: '14727faefbdc4aff848cd2713eb9939e', - username: 'Pixelic', - skyblockProfileId: '805c9751-0ff1-4cb6-8e9c-1067bf3bc601' - }, - { - uuid: 'ea805d40e8284d8d8e64e9fc8ac301ca', - username: 'Altpapier', - skyblockProfileId: 'ea805d40-e828-4d8d-8e64-e9fc8ac301ca' - }, - { - uuid: '4855c53ee4fb4100997600a92fc50984', - username: 'DuckySoSkilled', - skyblockProfileId: '00912956-3fd6-42ee-a166-3f649ceaf559' - }, - { - uuid: 'f025c1c7f55a4ea0b8d93f47d17dfe0f', - username: 'Plancke', - skyblockProfileId: 'f025c1c7-f55a-4ea0-b8d9-3f47d17dfe0f' - }, - { - uuid: 'fb3d96498a5b4d5b91b763db14b195ad', - username: 'DeathStreeks', - skyblockProfileId: 'fb3d9649-8a5b-4d5b-91b7-63db14b195ad' - }, - { - uuid: '28667672039044989b0019b14a2c34d6', - username: 'Refraction', - skyblockProfileId: 'd3df3ccc-ffd3-473f-bbba-311d5329bd25' - }, - { - uuid: '20934ef9488c465180a78f861586b4cf', - username: 'Minikloon', - skyblockProfileId: '974b2a9e-0d6d-4181-9dd1-8a05fb228965' - }, - { - uuid: 'ef962ec2df6e48a2ac9d6062c1b84652', - username: 'builder_247', - skyblockProfileId: '498228a7-32d4-4358-9aab-d1e97e6806cd' - } - ], - guilds: [ - { - name: 'PancakeSquad', - id: '557c75d90cf2ce51d4a92368', - uuid: 'f025c1c7f55a4ea0b8d93f47d17dfe0f' - }, - { - name: 'WristSpasm', - id: '5b8dd8cb0cf24573ab84c9ad', - uuid: '2700c8b565c74d8e9be5eb7a6ae19295' - }, - { - name: 'Pixelic', - id: '64b54f9d8ea8c96aaedafe84', - uuid: '14727faefbdc4aff848cd2713eb9939e' - }, - { - name: 'The Dawns Awakening', - id: '5ba94ed50cf2cc24cf043706', - uuid: '3b76b69ae5134296a730ed49171ad6f8' - } - ], - invalid: { - noSkyblockProfiles: [{ uuid: 'b45add7b081443909fb00aa9a3e15eb0' }], - noGuild: [{ uuid: '37501e7512b845ab8796e2baf9e9677a' }] - }, - houses: [ - '79006240d96a4464b4c6edaa82724a5f', - '3b76b69ae5134296a730ed49171ad6f8', - '9d9b5326e20943998c2167e8679e3d7c', - 'fb3d96498a5b4d5b91b763db14b195ad', - 'f0511d1334de468bbfbb31062204660c', - '20934ef9488c465180a78f861586b4cf', - '96f1641dde3441288f40ad8ecbfcb634' - ] -}; diff --git a/tests/housing/Client#getActiveHouses.js b/tests/housing/Client#getActiveHouses.js deleted file mode 100644 index 155ba69ed..000000000 --- a/tests/housing/Client#getActiveHouses.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable no-undef */ -const { House } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getActiveHouses', async () => { - let houses; - it('expect not to throw', async () => { - houses = await client.getActiveHouses(); - }); - it('should be an objecct', () => { - expect(houses).to.be.an('array'); - }); - it('required keys should exist', () => { - houses.forEach((apiHouse) => { - expect(apiHouse).instanceOf(House); - }); - }); -}); diff --git a/tests/housing/Client#getHouse.js b/tests/housing/Client#getHouse.js deleted file mode 100644 index 7473239ca..000000000 --- a/tests/housing/Client#getHouse.js +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable no-undef */ -const { House } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { houses } = require('../data.js'); -const { expect } = require('chai'); - -describe('Client#getHouse', async () => { - let apiHouse; - houses.forEach((houseUUID) => { - describe(`House Test ${houses.indexOf(houseUUID) + 1}`, async () => { - it('expect not to throw', async () => { - apiHouse = await client.getHouse(houseUUID); - }); - it('should be an objecct', () => { - expect(apiHouse).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(apiHouse).instanceOf(House); - }); - }); - }); -}); diff --git a/tests/housing/Client#getPlayerHouses.js b/tests/housing/Client#getPlayerHouses.js deleted file mode 100644 index e9f1ab0c2..000000000 --- a/tests/housing/Client#getPlayerHouses.js +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-disable no-undef */ -const { House } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { users } = require('../data.js'); -const { expect } = require('chai'); - -describe('Client#getPlayerHouses', async () => { - users.forEach((user) => { - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - let houses; - it('expect not to throw', async () => { - houses = await client.getPlayerHouses(user.uuid); - }); - it('should be an objecct', () => { - expect(houses).to.be.an('array'); - }); - it('required keys should exist', () => { - houses.forEach((apiHouse) => { - expect(apiHouse).instanceOf(House); - }); - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - let houses; - it('expect not to throw', async () => { - houses = await client.getPlayerHouses(user.username); - }); - it('should be an objecct', () => { - expect(houses).to.be.an('array'); - }); - it('required keys should exist', () => { - houses.forEach((apiHouse) => { - expect(apiHouse).instanceOf(House); - }); - }); - }); - }); -}); diff --git a/tests/skyblock/Client#getSkyblockBingo.js b/tests/skyblock/Client#getSkyblockBingo.js deleted file mode 100644 index 1eb311767..000000000 --- a/tests/skyblock/Client#getSkyblockBingo.js +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-disable no-undef */ -const { BingoData } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockBingo', async () => { - let bingo; - it('expect not to throw', async () => { - bingo = await client.getSkyblockBingo(); - }); - it('should be an objecct', () => { - expect(bingo).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(bingo).instanceOf(BingoData); - }); -}); diff --git a/tests/skyblock/Client#getSkyblockFireSales.js b/tests/skyblock/Client#getSkyblockFireSales.js deleted file mode 100644 index a2dc56381..000000000 --- a/tests/skyblock/Client#getSkyblockFireSales.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable no-undef */ -const { FireSale } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockFireSales', async () => { - let fireSales; - it('expect not to throw', async () => { - fireSales = await client.getSkyblockFireSales(); - }); - it('should be an objecct', () => { - expect(fireSales).to.be.an('array'); - }); - it('required keys should exist', () => { - fireSales.forEach((sale) => { - expect(sale).instanceOf(FireSale); - }); - }); -}); diff --git a/tests/skyblock/Client#getSkyblockGarden.js b/tests/skyblock/Client#getSkyblockGarden.js deleted file mode 100644 index 035470005..000000000 --- a/tests/skyblock/Client#getSkyblockGarden.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable no-undef */ -const { SkyblockGarden } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { users } = require('../data.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockGarden', async () => { - let garden; - users.forEach((user) => { - if (user.skyblockProfileId.length === 0) return; - describe(`User Test ${users.indexOf(user) + 1} | Skyblock Profile ID`, async () => { - it('expect not to throw', async () => { - garden = await client.getSkyblockGarden(user.skyblockProfileId); - }); - it('should be an objecct', () => { - expect(garden).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(garden).instanceOf(SkyblockGarden); - }); - }); - }); -}); diff --git a/tests/skyblock/Client#getSkyblockGovernment.js b/tests/skyblock/Client#getSkyblockGovernment.js deleted file mode 100644 index 4a47ac851..000000000 --- a/tests/skyblock/Client#getSkyblockGovernment.js +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable no-undef */ -const { Candidate } = require('../../src/index.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockGovernment', async () => { - let government; - it('expect not to throw', async () => { - government = await client.getSkyblockGovernment(); - }); - it('should be an objecct', () => { - expect(government).to.be.an('object'); - }); - it('required keys should exist', () => { - expect(government.lastUpdatedTimestamp).to.be.a('number'); - expect(government.lastUpdatedAt).to.be.a('date'); - government.lastElectionResults.forEach((mayor) => { - expect(mayor).instanceOf(Candidate); - }); - expect(government.mayor).instanceOf(Candidate); - expect(government.runningYear).to.be.a('number'); - if (government.currentElectionResults) { - expect(government.currentElectionResults).to.be.a('map'); - government.currentElectionResults.forEach((mayor) => { - expect(mayor).instanceOf(Candidate); - }); - } - if (government.currentElectionFor) { - expect(government.currentElectionFor).to.be.a('number'); - } - }); -}); diff --git a/tests/skyblock/Client#getSkyblockMember.js b/tests/skyblock/Client#getSkyblockMember.js deleted file mode 100644 index ce165c95b..000000000 --- a/tests/skyblock/Client#getSkyblockMember.js +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint-disable no-undef */ -const { SkyblockMember, Errors } = require('../../src/index.js'); -const { users, invalid } = require('../data.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockMember', async () => { - describe('Valid', async () => { - users.forEach((user) => { - let member; - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - it('expect not to throw', async () => { - member = await client.getSkyblockMember(user.uuid); - }); - it('should be an map', () => { - expect(member).to.be.an('map'); - }); - it('required keys should exist', () => { - member.forEach((profile) => { - expect(profile).instanceOf(SkyblockMember); - }); - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - it('expect not to throw', async () => { - member = await client.getSkyblockMember(user.username); - }); - it('should be an map', () => { - expect(member).to.be.an('map'); - }); - it('required keys should exist', () => { - member.forEach((profile) => { - expect(profile).instanceOf(SkyblockMember); - }); - }); - }); - }); - }); - describe('Invalid', async () => { - describe('Never Played skyblock', async () => { - invalid.noSkyblockProfiles.forEach((user) => { - it('expect to throw', async () => { - try { - member = await client.getSkyblockMember(user.uuid); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.NO_SKYBLOCK_PROFILES); - } - }).timeout(5000); - }); - }); - }); -}); diff --git a/tests/skyblock/Client#getSkyblockNews.js b/tests/skyblock/Client#getSkyblockNews.js deleted file mode 100644 index 736d2ea43..000000000 --- a/tests/skyblock/Client#getSkyblockNews.js +++ /dev/null @@ -1,21 +0,0 @@ -/* eslint-disable no-undef */ -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockNews', async () => { - let news; - it('expect not to throw', async () => { - news = await client.getSkyblockNews(); - }); - it('Should be an array', () => { - expect(news).to.be.an('array'); - }); - it('required keys should exist', () => { - for (const record of news) { - expect(record.title).to.be.a('string'); - expect(record.link).to.be.a('string'); - expect(record.date).instanceOf(Date); - expect(record.rawDate).to.be.a('string'); - } - }); -}); diff --git a/tests/skyblock/Client#getSkyblockProfiles.js b/tests/skyblock/Client#getSkyblockProfiles.js deleted file mode 100644 index d9c26bf9c..000000000 --- a/tests/skyblock/Client#getSkyblockProfiles.js +++ /dev/null @@ -1,108 +0,0 @@ -/* eslint-disable no-undef */ -const { SkyblockMember, Errors } = require('../../src/index.js'); -const { users, invalid } = require('../data.js'); -const { client } = require('../Client.js'); -const { expect } = require('chai'); - -describe('Client#getSkyblockProfiles', async () => { - describe('Valid', async () => { - users.forEach((user) => { - describe(`User Test ${users.indexOf(user) + 1} | UUID`, async () => { - let profiles; - it('expect not to throw', async () => { - profiles = await client.getSkyblockProfiles(user.uuid); - }); - it('should be an array', () => { - expect(profiles).to.be.an('array'); - }); - it('required keys should exist', () => { - profiles.forEach((profile) => { - expect(profile.profileId).to.be.a('string'); - expect(profile.profileName).to.be.oneOf([ - 'Apple', - 'Banana', - 'Blueberry', - 'Coconut', - 'Cucumber', - 'Grapes', - 'Kiwi', - 'Lemon', - 'Lime', - 'Mango', - 'Orange', - 'Papaya', - 'Pear', - 'Peach', - 'Pineapple', - 'Pomegranate', - 'Raspberry', - 'Strawberry', - 'Tomato', - 'Watermelon', - 'Zucchini' - ]); - profile.members.forEach((profile) => { - expect(profile).instanceOf(SkyblockMember); - }); - expect(profile.me).instanceOf(SkyblockMember); - }); - }); - }); - describe(`User Test ${users.indexOf(user) + 1} | Username`, async () => { - let profiles; - it('expect not to throw', async () => { - profiles = await client.getSkyblockProfiles(user.username); - }); - it('should be an array', () => { - expect(profiles).to.be.an('array'); - }); - it('required keys should exist', () => { - profiles.forEach((profile) => { - expect(profile.profileId).to.be.a('string'); - expect(profile.profileName).to.be.oneOf([ - 'Apple', - 'Banana', - 'Blueberry', - 'Coconut', - 'Cucumber', - 'Grapes', - 'Kiwi', - 'Lemon', - 'Lime', - 'Mango', - 'Orange', - 'Papaya', - 'Pear', - 'Peach', - 'Pineapple', - 'Pomegranate', - 'Raspberry', - 'Strawberry', - 'Tomato', - 'Watermelon', - 'Zucchini' - ]); - profile.members.forEach((profile) => { - expect(profile).instanceOf(SkyblockMember); - }); - expect(profile.me).instanceOf(SkyblockMember); - }); - }); - }); - }); - }); - describe('Invalid', async () => { - describe('Never played skyblock', async () => { - invalid.noSkyblockProfiles.forEach((user) => { - it('expect to throw', async () => { - try { - member = await client.getSkyblockProfiles(user.uuid); - throw new Error('Expected an error to be thrown, but no error was thrown.'); - } catch (error) { - expect(error.message).to.equal(Errors.NO_SKYBLOCK_PROFILES); - } - }).timeout(5000); - }); - }); - }); -}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..5836dc33e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "esModuleInterop": true, + "skipLibCheck": true, + "target": "ES2022", + "allowJs": false, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + "verbatimModuleSyntax": true, + + "strict": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "./dist", + "rootDir": "src", + + "sourceMap": true, + "declaration": true, + "declarationMap": true, + "forceConsistentCasingInFileNames": true, + "noUnusedLocals": true, + "noFallthroughCasesInSwitch": true, + "allowArbitraryExtensions": false, + "rewriteRelativeImportExtensions": true + }, + "include": ["./src"], + "exclude": ["**/*/*.test.*"] +} diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 000000000..d3c571138 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": ["src/"], + "out": "documentation", + "includeVersion": false, + "exclude": ["**/*.test.ts"], + "plugin": ["@8hobbies/typedoc-plugin-404", "typedoc-plugin-rename-defaults", "typedoc-material-theme"], + "entryPointStrategy": "expand", + "hideGenerator": true, + "cleanOutputDir": true, + "page404Content": "This page does not exist", + "useHostedBaseUrlForAbsoluteLinks": true, + "hostedBaseUrl": "https://hypixel-api-reborn.github.io/hypixel-api-reborn/", + "lang": "en", + "themeColor": "#2f3236" +} diff --git a/typings/index.d.ts b/typings/index.d.ts deleted file mode 100644 index 25eb165a2..000000000 --- a/typings/index.d.ts +++ /dev/null @@ -1,4335 +0,0 @@ -/* eslint-disable indent */ -/* eslint-disable max-len */ -/* eslint-disable camelcase */ -/* eslint-disable jsdoc/require-jsdoc */ -// Minimum TypeScript Version: 3.6 - -import { NetworthResult } from 'skyhelper-networth'; -import { EventEmitter } from 'events'; - -export type PLAYER_RANK = - | 'Default' - | 'VIP' - | 'VIP+' - | 'MVP' - | 'MVP+' - | 'MVP++' - | 'YouTube' - | 'Game Master' - | 'Admin' - | 'PIG+++' - | 'INNIT'; -export type GAME_NAME = - | 'Quake Craft' - | 'Walls' - | 'Paintball' - | 'Blitz Survival Games' - | 'The TNT Games' - | 'VampireZ' - | 'Mega Walls' - | 'Arcade' - | 'Arena Walls' - | 'UHC Champions' - | 'Cops and Crims' - | 'Warlords' - | 'Smash Heroes' - | 'Turbo Kart Racing' - | 'Housing' - | 'SkyWars' - | 'Crazy Walls' - | 'Speed UHC' - | 'SkyClash' - | 'Classic Games' - | 'Prototype' - | 'BedWars' - | 'Murder Mystery' - | 'Build Battle' - | 'Duels' - | 'SkyBlock' - | 'The Pit' - | 'Replay' - | 'Limbo' - | 'Queue' - | 'Main Lobby' - | 'Tournament Lobby' - | 'Idle' - | 'SMP' - | 'Wool Wars'; -export type GAME_ID = - | 2 - | 3 - | 4 - | 5 - | 6 - | 7 - | 13 - | 14 - | 17 - | 20 - | 21 - | 23 - | 24 - | 25 - | 26 - | 51 - | 52 - | 54 - | 55 - | 56 - | 57 - | 58 - | 59 - | 60 - | 61 - | 63 - | 64 - | 65 - | 67 - | 68 - | -1 - | -2 - | -3 - | -4 - | -5 - | -6; -export type GAME_CODE = - | 'QUAKECRAFT' - | 'WALLS' - | 'PAINTBALL' - | 'SURVIVAL_GAMES' - | 'TNTGAMES' - | 'VAMPIREZ' - | 'WALLS3' - | 'ARCADE' - | 'UHC' - | 'MCGO' - | 'BATTLEGROUND' - | 'SUPER_SMASH' - | 'GINGERBREAD' - | 'HOUSING' - | 'SKYWARS' - | 'TRUE_COMBAT' - | 'SPEED_UHC' - | 'SKYCLASH' - | 'LEGACY' - | 'PROTOTYPE' - | 'BEDWARS' - | 'MURDER_MYSTERY' - | 'BUILD_BATTLE' - | 'DUELS' - | 'SKYBLOCK' - | 'PIT' - | 'REPLAY' - | 'LIMBO' - | 'IDLE' - | 'QUEUE' - | 'MAIN_LOBBY' - | 'TOURNAMENT_LOBBY' - | 'SMP' - | 'WOOL_GAMES'; -export type SKYWARS_PRESTIGE = - | 'Iron' - | 'Iron' - | 'Gold' - | 'Diamond' - | 'Emerald' - | 'Sapphire' - | 'Ruby' - | 'Crystal' - | 'Opal' - | 'Amethyst' - | 'Rainbow' - | 'Mythic'; -export type SKYWARS_PRESTIGE_ICON = - | '⋆' - | '★' - | '☆' - | '⁕' - | '✶' - | '✳' - | '✴' - | '✷' - | '❋' - | '✼' - | '❂' - | '❁' - | '☬' - | '✙' - | '❤️' - | '☠' - | '✦' - | '✌' - | '❦' - | '✵' - | '❣' - | '☯' - | '✺' - | 'ಠ_ಠ' - | '⚔'; -export type BEDWARS_PRESTIGE = - | 'Iron' - | 'Gold' - | 'Diamond' - | 'Emerald' - | 'Sapphire' - | 'Ruby' - | 'Crystal' - | 'Opal' - | 'Amethyst' - | 'Rainbow' - | 'Iron Prime' - | 'Gold Prime' - | 'Diamond Prime' - | 'Emerald Prime' - | 'Sapphire Prime' - | 'Ruby Prime' - | 'Crystal Prime' - | 'Opal Prime' - | 'Amethyst Prime' - | 'Mirror' - | 'Light' - | 'Dawn' - | 'Dusk' - | 'Air' - | 'Wind' - | 'Nebula' - | 'Thunder' - | 'Earth' - | 'Water' - | 'Fire' - | 'Sunrise' - | 'Eclipse' - | 'Gamma' - | 'Majestic' - | 'Andesine' - | 'Marine' - | 'Element' - | 'Galaxy' - | 'Atomic' - | 'Sunset' - | 'Time' - | 'Winter' - | 'Obsidian' - | 'Spring' - | 'Ice' - | 'Summer' - | 'Spinel' - | 'Autumn' - | 'Mystic' - | 'Eternal'; -export type SkyblockRarity = - | 'VERY_SPECIAL' - | 'SPECIAL' - | 'SUPREME' - | 'MYTHIC' - | 'LEGENDARY' - | 'EPIC' - | 'RARE' - | 'UNCOMMON' - | 'COMMON'; -export type SOCIAL_MEDIA_ID = 'YOUTUBE' | 'DISCORD' | 'HYPIXEL' | 'TWITTER' | 'INSTAGRAM' | 'TWITCH'; -export type SKYWARS_KIT_TYPE = - | 'basic' - | 'supporting' - | 'mining' - | 'defending' - | 'attacking' - | 'advanced' - | 'enderchest'; -export type SKYWARS_KIT_GAMEMODE = 'solo' | 'team'; -export type BINGO_TYPE = 'ONE_TIME' | 'ONE_TIER' | 'TIERED'; -export type ACHIEVEMENT_TYPE = 'ONE_TIME' | 'TIERED'; -export type QUEST_TYPE = 'DAILY' | 'WEEKLY'; -export type GAME_STATIC = - | 'arcade' - | 'arena' - | 'bedwars' - | 'hungergames' - | 'buildbattle' - | 'truecombat' - | 'duels' - | 'mcgo' - | 'murdermystery' - | 'paintball' - | 'quake' - | 'skyclash' - | 'skywars' - | 'supersmash' - | 'speeduhc' - | 'gingerbread' - | 'tntgames' - | 'uhc' - | 'vampirez' - | 'walls3' - | 'walls' - | 'battleground' - | 'woolgames'; -export interface ChallengeData { - id: string; - name: string; - rewardType: string; - reward: number; -} -export interface Objective { - id: string; - type: 'Integer' | 'Boolean'; - amountNeeded: number; -} -export interface QuestReward { - type: string; - amount: number; -} -export type SKYBLOCK_BESTIARY = number; -export interface SKYBLOCK_BESTIARY_CATEGORY { - [key: string]: { - damage?: number; - head: string; - itemId?: string; - kills: number; - maxTier: number; - name: string; - tier: number; - }; -} -export interface SKYBLOCK_SKILL_DATA { - xp: number; - level: number; - maxLevel: number; - xpCurrent: number; - xpForNext: number; - progress: number; - cosmetic: boolean; -} -export interface SKYBLOCK_DUNGEONS_FLOOR_RUN { - timestamp: number; - score_exploration: number; - score_speed: number; - score_skill: number; - score_bonus: number; - dungeon_class: string; - teammates: string; - elapsed_time: number; - damage_dealt: number; - deaths: number; - mobs_killed: number; - secrets_found: number; - damage_mitigated: number; -} -export interface SKYBLOCK_DUNGEONS_FLOOR { - fastestRun: SKYBLOCK_DUNGEONS_FLOOR_RUN; - fastestSRun: SKYBLOCK_DUNGEONS_FLOOR_RUN; - fastestSPlusRun: SKYBLOCK_DUNGEONS_FLOOR_RUN; - completions: number; -} -export interface SKYBLOCK_GARDEN_CROPS { - wheat: number; - carrot: number; - sugarCane: number; - potato: number; - pumpkin: number; - melon: number; - cactus: number; - cocoaBeans: number; - mushroom: number; - netherWart: number; -} -export interface SKYBLOCK_GARDEN_COMPOSTER_UPGRADES { - speed: number; - multiDrop: number; - fuelCap: number; - organicMatterCap: number; - costReduction: number; -} -export interface SKYBLOCK_GARDEN_COMPOSTER { - organicMatter: number; - fuelUnits: number; - compostUnits: number; - compostItems: number; - conversionTicks: number; - upgrades: SKYBLOCK_GARDEN_COMPOSTER_UPGRADES; -} -export interface SKYBLOCK_GARDEN_VISITOR_SERVED { - total: number; - unique: number; -} -export interface SKYBLOCK_GARDEN_VISITOR { - visited: Record; - completed: Record; - served: SKYBLOCK_GARDEN_VISITOR_SERVED; -} -export interface SKYBLOCK_SLAYER_DATA { - xp: number; - tier1: number; - tier2: number; - tier3: number; - tier4: number; - tier5: number; - level: number; -} -export interface clientOptions { - cache?: boolean; - hypixelCacheTime?: number; - mojangCacheTime?: number; - cacheSize?: number; - cacheFilter?: string | string[] | { whitelist: string | string[]; blacklist: string | string[] }; - cacheHandler?: CacheHandler & unknown; - rateLimit?: 'HARD' | 'AUTO' | 'NONE'; - keyLimit?: number; - syncWithHeaders?: boolean; - silent?: boolean; - headers?: Record; - checkForUpdates?: boolean; -} -type PromiseLike = T | Promise; -type CacheHandler = { - set: (key: string, value: unknown) => PromiseLike; - get: (key: string) => PromiseLike; - has: (key: string) => PromiseLike; - delete: (key: string) => PromiseLike; - keys: () => PromiseLike; - size: () => PromiseLike; - clear: () => PromiseLike; -}; -export interface methodOptions { - raw?: boolean; - noCacheCheck?: boolean; - noCaching?: boolean; -} -export interface playerMethodOptions extends methodOptions { - guild?: boolean; - recentGames?: boolean; -} -export interface skyblockMemberOptions extends methodOptions { - fetchPlayer?: boolean; - getMuseum?: boolean; - getGarden?: boolean; -} -export interface auctionsOptions extends methodOptions { - noInfo?: boolean; - noAuctions?: boolean; - raw?: boolean; - retries?: number; - cooldown?: number; - race?: boolean; - includeItemBytes?: boolean; -} -export interface playerBingoOptions extends methodOptions { - fetchBingoData?: boolean; -} - -export interface LevelProgress { - currentXP: number; - remainingXP: number; - xpToNext: number; - percent: number; - percentRemaining: number; -} -declare module 'hypixel-api-reborn' { - const version: string; - const Errors: { - CACHE_FILTER_INVALID: string; - CACHE_LIMIT_MUST_BE_A_NUMBER: string; - CACHE_TIME_MUST_BE_A_NUMBER: string; - CONNECTION_ERROR: string; - ERROR_CODE_CAUSE: string; - ERROR_STATUSTEXT: string; - GUILD_DOES_NOT_EXIST: string; - INVALID_API_KEY: string; - INVALID_GUILD_ID: string; - INVALID_GUILD_SEARCH_PARAMETER: string; - INVALID_OPTION_VALUE: string; - INVALID_KEY_LIMIT_OPTION: string; - INVALID_HEADER_SYNC_OPTION: string; - INVALID_BURST_OPTION: string; - INVALID_RATE_LIMIT_OPTION: string; - INVALID_RESPONSE_BODY: string; - KEY_MUST_BE_A_STRING: string; - MALFORMED_UUID: string; - NO_API_KEY: string; - NO_GUILD_QUERY: string; - NO_NICKNAME_UUID: string; - NO_UUID: string; - OPTIONS_MUST_BE_AN_OBJECT: string; - PAGE_INDEX_ERROR: string; - PLAYER_DISABLED_ENDPOINT: string; - PLAYER_DOES_NOT_EXIST: string; - PLAYER_HAS_NEVER_LOGGED: string; - PLAYER_IS_INACTIVE: string; - RATE_LIMIT_INIT_ERROR: string; - SOMETHING_WENT_WRONG: string; - UUID_NICKNAME_MUST_BE_A_STRING: string; - MULTIPLE_INSTANCES: string; - UNEXPECTED_ERROR: string; - RATE_LIMIT_EXCEEDED: string; - }; - const Utils: { - arrayTools: { - /** - * @description Is input string or array? - */ - isStrArray(input: string | []): boolean; - /** - * @description String to array - */ - strToArray(input: string): string[]; - }; - Constants: { - duelsDivisions: [ - { name: 'Rookie'; key: 'rookie' }, - { name: 'Iron'; key: 'iron' }, - { name: 'Gold'; key: 'gold' }, - { name: 'Diamond'; key: 'diamond' }, - { name: 'Master'; key: 'master' }, - { name: 'Legend'; key: 'legend' }, - { name: 'Grandmaster'; key: 'grandmaster' }, - { name: 'Godlike'; key: 'godlike' }, - { name: 'WORLD ELITE'; key: 'world_elite' }, - { name: 'WORLD MASTER'; key: 'world_master' }, - { name: "WORLD'S BEST"; key: 'worlds_best' } - ]; - levelingXp: { - 1: 50; - 2: 125; - 3: 200; - 4: 300; - 5: 500; - 6: 750; - 7: 1000; - 8: 1500; - 9: 2000; - 10: 3500; - 11: 5000; - 12: 7500; - 13: 10000; - 14: 15000; - 15: 20000; - 16: 30000; - 17: 50000; - 18: 75000; - 19: 100000; - 20: 200000; - 21: 300000; - 22: 400000; - 23: 500000; - 24: 600000; - 25: 700000; - 26: 800000; - 27: 900000; - 28: 1000000; - 29: 1100000; - 30: 1200000; - 31: 1300000; - 32: 1400000; - 33: 1500000; - 34: 1600000; - 35: 1700000; - 36: 1800000; - 37: 1900000; - 38: 2000000; - 39: 2100000; - 40: 2200000; - 41: 2300000; - 42: 2400000; - 43: 2500000; - 44: 2600000; - 45: 2750000; - 46: 2900000; - 47: 3100000; - 48: 3400000; - 49: 3700000; - 50: 4000000; - }; - xpPast50: { - 51: 4300000; - 52: 4600000; - 53: 4900000; - 54: 5200000; - 55: 5500000; - 56: 5800000; - 57: 6100000; - 58: 6400000; - 59: 6700000; - 60: 7000000; - }; - runecraftingXp: { - 1: 50; - 2: 100; - 3: 125; - 4: 160; - 5: 200; - 6: 250; - 7: 315; - 8: 400; - 9: 500; - 10: 625; - 11: 785; - 12: 1000; - 13: 1250; - 14: 1600; - 15: 2000; - 16: 2465; - 17: 3125; - 18: 4000; - 19: 5000; - 20: 6200; - 21: 7800; - 22: 9800; - 23: 12200; - 24: 15300; - 25: 19050; - }; - skillsCap: { - taming: 60; - farming: 60; - mining: 60; - combat: 60; - foraging: 50; - fishing: 50; - enchanting: 60; - alchemy: 50; - carpentry: 50; - runecrafting: 25; - dungeons: 50; - social: 25; - }; - dungeonXp: { - 1: 50; - 2: 75; - 3: 110; - 4: 160; - 5: 230; - 6: 330; - 7: 470; - 8: 670; - 9: 950; - 10: 1340; - 11: 1890; - 12: 2665; - 13: 3760; - 14: 5260; - 15: 7380; - 16: 10300; - 17: 14400; - 18: 20000; - 19: 27600; - 20: 38000; - 21: 52500; - 22: 71500; - 23: 97000; - 24: 132000; - 25: 180000; - 26: 243000; - 27: 328000; - 28: 445000; - 29: 600000; - 30: 800000; - 31: 1065000; - 32: 1410000; - 33: 1900000; - 34: 2500000; - 35: 3300000; - 36: 4300000; - 37: 5600000; - 38: 7200000; - 39: 9200000; - 40: 1.2e7; - 41: 1.5e7; - 42: 1.9e7; - 43: 2.4e7; - 44: 3e7; - 45: 3.8e7; - 46: 4.8e7; - 47: 6e7; - 48: 7.5e7; - 49: 9.3e7; - 50: 1.1625e8; - }; - hotmXp: { - 1: 0; - 2: 3000; - 3: 9000; - 4: 25000; - 5: 60000; - 6: 100000; - 7: 150000; - }; - socialXp: { - 1: 50; - 2: 100; - 3: 150; - 4: 250; - 5: 500; - 6: 750; - 7: 1000; - 8: 1250; - 9: 1500; - 10: 2000; - 11: 2500; - 12: 3000; - 13: 3750; - 14: 4500; - 15: 6000; - 16: 8000; - 17: 10000; - 18: 12500; - 19: 15000; - 20: 20000; - 21: 25000; - 22: 30000; - 23: 35000; - 24: 40000; - 25: 50000; - }; - petScore: { - COMMON: 1; - UNCOMMON: 2; - RARE: 3; - EPIC: 4; - LEGENDARY: 5; - MYTHIC: 6; - }; - petRarityOffset: { - COMMON: 0; - UNCOMMON: 6; - RARE: 11; - EPIC: 16; - LEGENDARY: 20; - MYTHIC: 20; - }; - petLevels: [ - 100, - 110, - 120, - 130, - 145, - 160, - 175, - 190, - 210, - 230, - 250, - 275, - 300, - 330, - 360, - 400, - 440, - 490, - 540, - 600, - 660, - 730, - 800, - 880, - 960, - 1050, - 1150, - 1260, - 1380, - 1510, - 1650, - 1800, - 1960, - 2130, - 2310, - 2500, - 2700, - 2920, - 3160, - 3420, - 3700, - 4000, - 4350, - 4750, - 5200, - 5700, - 6300, - 7000, - 7800, - 8700, - 9700, - 10800, - 12000, - 13300, - 14700, - 16200, - 17800, - 19500, - 21300, - 23200, - 25200, - 27400, - 29800, - 32400, - 35200, - 38200, - 41400, - 44800, - 48400, - 52200, - 56200, - 60400, - 64800, - 69400, - 74200, - 79200, - 84700, - 90700, - 97200, - 104200, - 111700, - 119700, - 128200, - 137200, - 146700, - 156700, - 167700, - 179700, - 192700, - 206700, - 221700, - 237700, - 254700, - 272700, - 291700, - 311700, - 333700, - 357700, - 383700, - 411700, - 441700, - 476700, - 516700, - 561700, - 611700, - 666700, - 726700, - 791700, - 861700, - 936700, - 1016700, - 1101700, - 1191700, - 1286700, - 1386700, - 1496700, - 1616700, - 1746700, - 1886700, - 0, - 5555, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700, - 1886700 - ]; - leaderboardNames: { - ARENA: 'ARENA'; - COPS_AND_CRIMS: 'MCGO'; - WARLORDS: 'BATTLEGROUND'; - BLITZ_SURVIVAL_GAMES: 'SURVIVAL_GAMES'; - UHC: 'UHC'; - WALLS: 'WALLS'; - PROTOTYPE: 'PROTOTYPE'; - PAINTBALL: 'PAINTBALL'; - SKYWARS: 'SKYWARS'; - MURDER_MYSTERY: 'MURDER_MYSTERY'; - SMASH_HEROES: 'SUPER_SMASH'; - DUELS: 'DUELS'; - SPEED_UHC: 'SPEED_UHC'; - TNTGAMES: 'TNTGAMES'; - BEDWARS: 'BEDWARS'; - TURBO_KART_RACERS: 'GINGERBREAD'; - BUILD_BATTLE: 'BUILD_BATTLE'; - ARCADE: 'ARCADE'; - SKYCLASH: 'SKYCLASH'; - QUAKECRAFT: 'QUAKECRAFT'; - CRAZY_WALLS: 'TRUE_COMBAT'; - MEGA_WALLS: 'WALLS3'; - VAMPIREZ: 'VAMPIREZ'; - }; - MiniGamesString: { - QUAKECRAFT: 'Quakecraft'; - WALLS: 'Walls'; - PAINTBALL: 'Paintball'; - SURVIVAL_GAMES: 'Blitz Survival Games'; - TNTGAMES: 'The TNT Games'; - VAMPIREZ: 'VampireZ'; - WALLS3: 'Mega Walls'; - ARCADE: 'Arcade'; - ARENA: 'Arena Brawl'; - MCGO: 'Cops and Crims'; - UHC: 'UHC Champions'; - BATTLEGROUND: 'Warlords'; - SUPER_SMASH: 'Smash Heroes'; - GINGERBREAD: 'Turbo Kart Racers'; - HOUSING: 'Housing'; - SKYWARS: 'SkyWars'; - TRUE_COMBAT: 'Crazy Walls'; - SPEED_UHC: 'Speed UHC'; - SKYCLASH: 'SkyClash'; - LEGACY: 'Classic Games'; - PROTOTYPE: 'Prototype'; - BEDWARS: 'BedWars'; - MURDER_MYSTERY: 'Murder Mystery'; - BUILD_BATTLE: 'Build Battle'; - DUELS: 'Duels'; - PIT: 'The Pit'; - SKYBLOCK: 'SkyBlock'; - REPLAY: 'Replay'; - LIMBO: 'Limbo'; - IDLE: 'Idle'; - QUEUE: 'Queue'; - MAIN_LOBBY: 'Main Lobby'; - TOURNAMENT_LOBBY: 'Tournament Lobby'; - }; - SkyWarsPrestigeIcons: { - default: '⋆'; - angel_1: '★'; - angel_2: '☆'; - angel_3: '⁕'; - angel_4: '✶'; - angel_5: '✳'; - angel_6: '✴'; - angel_7: '✷'; - angel_8: '❋'; - angel_9: '✼'; - angel_10: '❂'; - angel_11: '❁'; - angel_12: '☬'; - iron_prestige: '✙'; - gold_prestige: '❤️'; - diamond_prestige: '☠'; - emerald_prestige: '✦'; - sapphire_prestige: '✌'; - ruby_prestige: '❦'; - crystal_prestige: '✵'; - opal_prestige: '❣'; - amethyst_prestige: '☯'; - rainbow_prestige: '✺'; - mythic_prestige: 'ಠ_ಠ'; - favor_of_the_angel_prestige: '⚔'; - }; - games: [ - { name: 'Quake Craft'; code: 'QUAKECRAFT'; id: 2 }, - { name: 'Walls'; code: 'WALLS'; id: 3 }, - { name: 'Paintball'; code: 'PAINTBALL'; id: 4 }, - { name: 'Blitz Survival Games'; code: 'SURVIVAL_GAMES'; id: 5 }, - { name: 'The TNT Games'; code: 'TNTGAMES'; id: 6 }, - { name: 'VampireZ'; code: 'VAMPIREZ'; id: 7 }, - { name: 'Mega Walls'; code: 'WALLS3'; id: 13 }, - { name: 'Arcade'; code: 'ARCADE'; id: 14 }, - { name: 'Arena Brawl'; code: 'ARENA'; id: 17 }, - { name: 'UHC Champions'; code: 'UHC'; id: 20 }, - { name: 'Cops and Crims'; code: 'MCGO'; id: 21 }, - { name: 'Warlords'; code: 'BATTLEGROUND'; id: 23 }, - { name: 'Smash Heroes'; code: 'SUPER_SMASH'; id: 24 }, - { name: 'Turbo Kart Racers'; code: 'GINGERBREAD'; id: 25 }, - { name: 'Housing'; code: 'HOUSING'; id: 26 }, - { name: 'SkyWars'; code: 'SKYWARS'; id: 51 }, - { name: 'Crazy Walls'; code: 'TRUE_COMBAT'; id: 52 }, - { name: 'Speed UHC'; code: 'SPEED_UHC'; id: 54 }, - { name: 'SkyClash'; code: 'SKYCLASH'; id: 55 }, - { name: 'Classic Games'; code: 'LEGACY'; id: 56 }, - { name: 'Prototype'; code: 'PROTOTYPE'; id: 57 }, - { name: 'BedWars'; code: 'BEDWARS'; id: 58 }, - { name: 'Murder Mystery'; code: 'MURDER_MYSTERY'; id: 59 }, - { name: 'Build Battle'; code: 'BUILD_BATTLE'; id: 60 }, - { name: 'Duels'; code: 'DUELS'; id: 61 }, - { name: 'SkyBlock'; code: 'SKYBLOCK'; id: 63 }, - { name: 'The Pit'; code: 'PIT'; id: 64 }, - { name: 'Replay'; code: 'REPLAY'; id: -1 }, - { name: 'Limbo'; code: 'LIMBO'; id: -2 }, - { name: 'Queue'; code: 'QUEUE'; id: -3 }, - { name: 'Main Lobby'; code: 'MAIN_LOBBY'; id: -4 }, - { name: 'Tournament Lobby'; code: 'TOURNAMENT_LOBBY'; id: -5 }, - { name: 'Idle'; code: 'IDLE'; id: -6 } - ]; - }; - /** - * @description Divides a by b - */ - divide(a: number, b: number): number; - guildExp: { - parseHistory(historyDate: Record): { day: string; date: Date; exp: number; totalExp: number }[]; - getGuildLevel(exp: number): number; - }; - oscillation: { - weekAB(date: Date): 'a' | 'b'; - monthAB(date: Date): 'a' | 'b'; - }; - /** - * @description Is this guild ID? - */ - isGuildID(id: string): boolean; - /** - * @description Is this uuid? - */ - isUUID(uuid: string): boolean; - removeSnakeCase: { - /** - * @description Validates JSON - */ - validateJSON(obj: Record): boolean; - /** - * @description Converts {str_str: {}} to {strStr: {}} without JSON validation - */ - single(obj: Record): Record; - /** - * @description Converts {str_str: {}} to {strStr: {}} - */ - recursive(obj: Record, lowerCase?: boolean): Record; - /** - * @description Converts 'str_str' to 'strStr' - */ - removeSnakeCaseString(str: string): string; - }; - rgbToHexColor(rgb: number[]): string; - SkyblockUtils: { - /** - * @description Decodes base64 to skyblock inventory data - */ - decode(base64: string): Promise>; - /** - * @description Get level by experience - */ - getLevelByXp(xp: number, type: string, levelCap: number | null): number; - /** - * @description Get level by achievement - */ - getLevelByAchievement( - achievementLevel: number, - type: string - ): { - xp: number; - level: number; - maxLevel: number; - xpCurrent: number; - xpForNext: number; - progress: number; - }; - /** - * @description Get slayer level - */ - getSlayerLevel(slayer: Record): { - xp: number; - tier1: number; - tier2: number; - tier3: number; - tier4: number; - level: number; - }; - }; - /** - * Calls Mojang API for player's nickname by uuid - * @param input Player UUID - */ - toIGN(input: string): Promise; - /** - * Calls Mojang API for player's uuid by nickname - * @param input Player nickname - */ - toUuid(input: string): Promise; - /** - * Converts varInts to js numbers - * @param bytes Array of numbers to be read as minecraft var ints. - */ - varInt(bytes: number[]): number; - }; - class Client extends EventEmitter { - constructor(key: string, options?: clientOptions); - /** - * @description API Key - */ - readonly key: string; - /** - * @description Client options - */ - readonly options: clientOptions; - /** - * @description Returns all cache entries - */ - readonly cache: Map; - /** - * @description Retrieves information about Hypixel achievements. - * @param {methodOptions} [options] - The method options. - */ - getAchievements(options?: methodOptions): Promise; - /** - * @description Parses the RSS feed from status.hypixel.net - * @param {methodOptions} [options] - The method options. - */ - getAPIStatus(options?: methodOptions): Promise; - /** - * @description Allows you to get all active boosters - * @param {methodOptions} [options] - The method options. - */ - getBoosters(options?: methodOptions): Promise; - /** - * @description Allows you to get information about hypixel challenges [NO KEY REQUIRED] - * @param {methodOptions} [options] - The method options. - */ - getChallenges(options?: methodOptions): Promise; - /** - * @description Allows you to get player count along with the player count of each public game - * @param {methodOptions} [options] - The method options. - */ - getGameCounts(options?: methodOptions): Promise; - /** - * @description Allows you to get statistics of hypixel guild - * @param {"id"|"name"|"player"} searchParameter - How you want to search - * @param {string} query - guild name, player nickname or guild id - * @param {methodOptions} [options] - The method options. - */ - getGuild(searchParameter: 'id' | 'name' | 'player', query: string, options?: methodOptions): Promise; - /** - * @description Allows you to get information about hypixel guild achievements [NO KEY REQUIRED] - * @param {methodOptions} [options] - The method options. - */ - getGuildAchievements(options?: methodOptions): Promise; - /** - * @description Allows you to get leaderboards of each mini-game - * @param {methodOptions} [options] - The method options. - */ - getLeaderboards(options?: methodOptions): Promise<{ - ARENA: Leaderboard[]; - COPS_AND_CRIMS: Leaderboard[]; - WARLORDS: Leaderboard[]; - BLITZ_SURVIVAL_GAMES: Leaderboard[]; - UHC: Leaderboard[]; - WALLS: Leaderboard[]; - PROTOTYPE: Leaderboard[]; - PAINTBALL: Leaderboard[]; - SKYWARS: Leaderboard[]; - MURDER_MYSTERY: Leaderboard[]; - SMASH_HEROES: Leaderboard[]; - DUELS: Leaderboard[]; - SPEED_UHC: Leaderboard[]; - TNTGAMES: Leaderboard[]; - BEDWARS: Leaderboard[]; - TURBO_KART_RACERS: Leaderboard[]; - BUILD_BATTLE: Leaderboard[]; - ARCADE: Leaderboard[]; - SKYCLASH: Leaderboard[]; - QUAKECRAFT: Leaderboard[]; - CRAZY_WALLS: Leaderboard[]; - MEGA_WALLS: Leaderboard[]; - VAMPIREZ: Leaderboard[]; - }>; - /** - * @description Allows you to get statistics of player - * @param {string} query - player nickname or uuid - * @param {playerMethodOptions} [options] - player search options - */ - getPlayer(query: string, options?: playerMethodOptions): Promise; - /** - * @description Allows you to get information about hypixel quests [NO KEY REQUIRED] - * @param {methodOptions} [options] - Options - */ - getQuests(options?: methodOptions): Promise; - /** - * @description Allows you to get recent games of a player - * @param {string} query - player nickname or uuid - * @param {methodOptions} [options] - Options - */ - getRecentGames(query: string, options?: methodOptions): Promise; - /** - * @description Parses information returned by hypixel upon a status request packet - * @param {number} repeats Amount of times to ping hypixel, preferably between 1 and 10 times. - */ - getServerInfo(repeats?: number): Promise; - /** - * @description Allows you to get player's network status - * @param {string} query - player nickname or uuid - * @param {methodOptions} [options] - Options - */ - getStatus(query: string, options?: methodOptions): Promise; - /** - * @description Allows you to get statistics of watchdog anticheat - * @param {methodOptions} [options] - Options - */ - getWatchdogStats(options?: methodOptions): Promise; - /** - * @description Allows you to get filtered skyblock auctions. Using auction ID will return an array of at most 1 element - * @name Client#getSkyblockAuction - * @param {'PROFILE' | 'PLAYER' | 'AUCTION'} type - Filter to use - * @param {string} query - uuid of profile, player, or auction. IGN can be used as well - * @param {boolean} includeItemBytes - include item bytes (optional) - * @param {methodOptions} [options] - Options - */ - getSkyblockAuction( - type: 'PROFILE' | 'PLAYER' | 'AUCTION', - query: string, - includeItemBytes?: boolean, - options?: methodOptions - ): Promise; - /** - * Allows you to get skyblock auctions - * @param {string|number|number[]} page - "*", a page number, or an array with the start and the end page number ( automatically sorted ) - * @param {auctionsOptions} [options={}] Options - * @return {Promise<{info:AuctionInfo,Auctions:Auction[]}>} - */ - getSkyblockAuctions( - page: string | number | number[], - options?: auctionsOptions - ): Promise<{ info: AuctionInfo; Auctions: Auction[] }>; - /** - * @description Allows you to get all auctions of player - * @param {string} query - player nickname or uuid - * @param {boolean} includeItemBytes - include item bytes (optional) - * @param {methodOptions} [options] - Options - */ - getSkyblockAuctionsByPlayer(query: string, includeItemBytes?: boolean, options?: methodOptions): Promise; - /** - * @description Allows you to get list of products - * @param {methodOptions} [options] - Options - */ - getSkyblockBazaar(options?: methodOptions): Promise; - /** - * @description Gets bingo data - * @param {methodOptions} [options] - Options - */ - getSkyblockBingo(options?: methodOptions): Promise; - /** - * @description Gets bingo data of a player - * @param {string} query - UUID/IGN of player - * @param {methodOptions} [options] - Options - */ - getSkyblockBingoByPlayer(query: string, options?: playerBingoOptions): Promise; - /** - * @description Allows you to get list of active skyblock firesales - * @param {methodOptions} [options] - Options - */ - getSkyblockFireSales(options?: methodOptions): Promise; - /** - * @description Allows you to get a profiles skyblock garden - * @param {methodOptions} [options] - Options - */ - getSkyblockGarden(profileId: string, options?: methodOptions); - /** - * @description Gets data of skyblock government - * @param {methodOptions} [options] - Options - */ - getSkyblockGovernment(options?: methodOptions): Promise; - /** - * @description Allows you to get a player's skyblock member data from all their profiles - * @param query - player nickname or uuid - * @param {methodOptions} [options] - Options - */ - getSkyblockMember(query: string, options?: skyblockMemberOptions): Promise>; - /** - * @description Allows you to get statistics of player - * @param {string} query - player nickname or uuid - * @param {string} profileId - profile id - * @param {methodOptions} [options] - Options - */ - getSkyblockMuseum(query: string, profileId: string, options?: methodOptions); - /** - * @description Allows you to get skyblock news - * @param {methodOptions} [options] - Options - */ - getSkyblockNews(options?: methodOptions): Promise; - /** - * @description Allows you to get a player's skyblock profiles - * @param query - player nickname or uuid - * @param {methodOptions} [options] - Options - */ - getSkyblockProfiles(query: string, options?: skyblockMemberOptions): Promise; - /** - * @description Get a array of active houses - * @param {methodOptions} [options] - Options - */ - getActiveHouses(options?: methodOptions): Promise; - /** - * @description Get a array of houses for a user - * @param query - UUID / IGN of player - * @param {methodOptions} [options] - Options - */ - getPlayerHouses(query: string, options?: methodOptions): Promise; - /** - * @description Get a house - * @param query - house uuid - * @param {methodOptions} [options] - Options - */ - getHouse(query: string, options?: methodOptions): Promise; - /** - * @param amount - Amount of cache entries to delete - * @description Allows you to clear cache - */ - sweepCache(amount?: number): void; - on(event: 'outgoingRequest', listener: (url: string, options: Record) => void): this; - on(event: 'warn', listener: (error: string) => void): this; - /** - * @description Emitted ( only once ) when rate limiter is ready. ( You don't have to wait for this event to emit UNLESS you are planning to do data scraping which means spamming requests ) - */ - once(event: 'ready', listener: () => void): this; - } - class Player { - constructor(data: Record); - nickname: string; - uuid: string; - history: string[]; - rank: PLAYER_RANK; - mcVersion: string; - channel: string; - lastLoginTimestamp: number; - lastLogin?: Date; - lastLogoutTimestamp: number; - lastLogout?: Date; - firstLoginTimestamp: number; - firstLogin: Date; - recentlyPlayedGame: Game; - plusColor?: Color; - prefixColor?: Color; - karma: number; - achievements: Record; - achievementPoints: number; - totalExperience: number; - level: number; - socialMedia: { name: string; link: string; id: SOCIAL_MEDIA_ID }[]; - giftsSent?: number; - giftBundlesSent?: number; - giftBundlesReceived?: number; - levelProgress: LevelProgress; - isOnline: boolean; - userLanguage: string; - lastDailyReward?: Date; - lastDailyRewardTimestamp?: number; - totalRewards?: number; - totalDailyRewards?: number; - rewardStreak?: number; - rewardScore?: number; - rewardHighScore?: number; - claimedLevelingRewards: number[]; - globalCosmetics: PlayerCosmetics; - ranksPurchaseTime: { - VIP: Date | null; - VIP_PLUS: Date | null; - MVP: Date | null; - MVP_PLUS: Date | null; - }; - guild?: Guild; - stats?: { - skywars?: SkyWars; - bedwars?: BedWars; - uhc?: UHC; - speeduhc?: SpeedUHC; - murdermystery?: MurderMystery; - duels?: Duels; - buildbattle?: BuildBattle; - megawalls?: MegaWalls; - copsandcrims?: CopsAndCrims; - tntgames?: TNTGames; - smashheroes?: SmashHeroes; - vampirez?: VampireZ; - blitzsg?: BlitzSurvivalGames; - arena?: ArenaBrawl; - paintball?: Paintball; - quakecraft?: Quakecraft; - turbokartracers?: TurboKartRacers; - walls?: Walls; - warlords?: Warlords; - arcade?: Arcade; - woolgames?: WoolGames; - pit?: Pit; - }; - getRecentGames(): Promise; - recentGames?: RecentGame[]; - toString(): string; - } - class Pit { - static calcLevel(prestige: number, xp: number): number; - constructor(data: Record); - prestige: number; - xp: number; - level: number; - kills: number; - deaths: number; - KDRatio: number; - assists: number; - maxKillStreak: number; - playtime: number; - joins: number; - damageReceived: number; - damageDealt: number; - damageRatio: number; - meleeDamageReceived: number; - meleeDamageDealt: number; - swordHits: number; - leftClicks: number; - meleeAccuracy: number; - meleeDamageRatio: number; - bowDamageReceived: number; - bowDamageDealt: number; - arrowsHit: number; - arrowsFired: number; - bowAccuracy: number; - bowDamageRatio: number; - goldenHeadsEaten: number; - getInventory(): Promise; - getEnterChest(): Promise; - getArmor(): Promise; - } - class PitInventoryItem { - constructor(data: Record); - itemId: number; - count: number; - name: string | null; - lore: string | null; - loreArray: string[] | []; - extraAttributes: string | null; - toString(): string; - } - class WoolWarsClass { - constructor(data: Record); - wins: number; - kills: number; - assists: number; - deaths: number; - KDRatio: number; - gamesPlayed: number; - woolsPlaced: number; - blocksBroken: number; - placeBreakRatio: number; - powerups: number; - } - class WoolWars { - constructor(data: Record); - selectedClass: 'ASSAULT' | 'TANK' | 'GOLEM' | 'SWORDSMAN' | 'ENGINEER' | 'ARCHER' | 'NONE'; - wins: number; - kills: number; - assists: number; - deaths: number; - KDRatio: number; - gamesPlayed: number; - woolsPlaced: number; - blocksBroken: number; - placeBreakRatio: number; - powerups: number; - assault: WoolWarsClass; - tank: WoolWarsClass; - golem: WoolWarsClass; - swordsman: WoolWarsClass; - engineer: WoolWarsClass; - archer: WoolWarsClass; - } - class CaptureTheWool { - constructor(data: Record); - kills: number; - assists: number; - deaths: number; - KDRatio: number; - killsWithWool: number; - deathsWithWool: number; - KDRatioWithWool: number; - woolCaptured: number; - woolStolen: number; - woolCaptureStolenRatio: number; - } - class SheepWars { - constructor(data: Record); - wins: number; - kills: number; - killsVoid: number; - killsBow: number; - killsExplosive: number; - deaths: number; - deathsVoid: number; - deathsMelee: number; - deathsExplosive: number; - KDRatio: number; - losses: number; - WLRatio: number; - gamesPlayed: number; - damageDealt: number; - sheepThrown: number; - magicWoolHit: number; - } - type PrivateGamesConfig = { - one_hit_one_kill: boolean; - rainbow_wool: 'Enabled' | 'Disabled'; - health_buff: string; - game_speed: string; - speed: string; - no_class: 'Enabled' | 'Disabled'; - respawn_enable: boolean; - }; - class WoolGames { - constructor(data: Record); - layers: number; - xp: number; - exactLevel: number; - level: number; - coins: number; - ownedCosmetics: string[]; - privateGamesConfig: PrivateGamesConfig; - playtime: number; - woolWars: WoolWars; - captureTheWool: CaptureTheWool; - sheepWars: SheepWars; - } - class PlayerCosmetics { - constructor(data: Record); - allCosmetics: string[]; - petManager: Pets | null; - get suits(): string[]; - get hats(): string[]; - get gadgets(): string[]; - get morphs(): string[]; - get cloaks(): string[]; - get taunts(): string[]; - get rankColors(): string[]; - get clickEffects(): string[]; - } - class Pets { - constructor(pets: string[], data: Record); - pets: Pet[]; - lastJourneyTimestamp: number | null; - lastJourneyAt: Date | null; - petConsumables: PetConsumables; - } - class Pet { - constructor(name: string, data: Record); - isFavorite: boolean; - name: string; - active: boolean; - stats?: { - hunger: number | null; - lastFed: number | null; - lastFedAt: Date | null; - thirst: number | null; - lastDrank: number | null; - lastDrankAt: Date | null; - exercise: number | null; - lastExercised: number | null; - lastExercisedAt: Date | null; - }; - rawNickname: string | null; - nickname: string | null; - experience: number; - } - class PetConsumables { - BAKED_POTATO: number; - COOKIE: number; - FEATHER: number; - HAY_BLOCK: number; - SLIME_BALL: number; - COOKED_BEEF: number; - RED_ROSE: number; - WATER_BUCKET: number; - MELON: number; - STICK: number; - WOOD_SWORD: number; - MILK_BUCKET: number; - GOLD_RECORD: number; - LEASH: number; - LAVA_BUCKET: number; - BONE: number; - MAGMA_CREAM: number; - WHEAT: number; - MUSHROOM_SOUP: number; - BREAD: number; - PUMPKIN_PIE: number; - APPLE: number; - CARROT_ITEM: number; - RAW_FISH: number; - PORK: number; - CAKE: number; - ROTTEN_FLESH: number; - } - class Leaderboard { - constructor(data: Record); - name: string; - title: string; - playerCount: number; - leaders: string[]; - } - /** - * @description Typings might be different. Hypixel: Due to the large amount of modes and that they can change at anytime we don't currently have a friendly list of mode keys to clean names. This may be added at a later date. - */ - class GameCounts { - constructor(data: Record); - playerCount: number; - mainLobby: { players: number }; - tournamentLobby: { players: number }; - megaWalls: { - players: number; - modes: { standard: number; faceOff: number }; - }; - classicGames: { - players: number; - modes: { - paintball: number; - walls: number; - quakecraft: number; - gingerbread: number; - arena: number; - vampirez: number; - }; - }; - thePit: { players: number; modes: { pit: number } }; - blitzSurvivalGames: { - players: number; - modes: { soloNormal: number; teamsNormal: number }; - }; - duels: { - players: number; - modes: { - duelsBowspleefDuel: number; - duelsBowDuel: number; - duelsBridge_2v2v2v2: number; - duelsMwDuel: number; - duelsUhcFour: number; - duelsUhcMeetup: number; - duelsBridgeDoubles: number; - duelsSwDoubles: number; - duelsUhcDoubles: number; - duelsBridgeFour: number; - duelsBridge_3v3v3v3: number; - duelsSumoDuel: number; - duelsUhcDuel: number; - duelsOpDoubles: number; - duelsOpDuel: number; - duelsMwDoubles: number; - duelsBlitzDuel: number; - duelsPotionDuel: number; - duelsClassicDuel: number; - duelsComboDuel: number; - duelsBridgeDuel: number; - duelsSwDuel: number; - }; - }; - uhcChampions: { players: number; modes: { teams: number; solo: number } }; - speedUhc: { players: number; modes: { soloNormal: number } }; - theTntGames: { - players: number; - modes: { - pvprun: number; - tntag: number; - tntrun: number; - bowspleef: number; - capture: number; - }; - }; - prototype: { - players: number; - modes: { towerwarsSolo: number; towerwarsTeamOfTwo: number }; - }; - smashHeroes: { - players: number; - modes: { - '1v1Normal': number; - friendsNormal: number; - soloNormal: number; - '2v2Normal': number; - teamsNormal: number; - }; - }; - bedwars: { - players: number; - modes: { - bedwarsTwoFour: number; - bedwarsFourFourRush: number; - bedwarsEightOne: number; - bedwarsEightTwoRush: number; - bedwarsEightTwoVoidless: number; - bedwarsEightTwoArmed: number; - bedwarsEightTwo: number; - bedwarsFourFour: number; - bedwarsEightTwoLucky: number; - bedwarsFourThree: number; - bedwarsFourFourVoidless: number; - bedwarsFourFourLucky: number; - bedwarsEightTwoUltimate: number; - }; - }; - buildBattle: { - players: number; - modes: { - buildBattleSoloNormalLatest: number; - buildBattleGuessTheBuild: number; - buildBattleTeamsNormal: number; - buildBattleSoloPro: number; - buildBattleSoloNormal: number; - }; - }; - housing: { players: number }; - skywars: { - players: number; - modes: { - soloInsaneLucky: number; - soloInsaneSlime: number; - teamsInsaneSlime: number; - teamsInsaneRush: number; - teamsInsane: number; - soloNormal: number; - soloInsaneHuntersVsBeasts: number; - soloInsaneTntMadness: number; - soloInsaneRush: number; - soloInsane: number; - teamsNormal: number; - megaNormal: number; - }; - }; - replay: { players: number; modes: { base: number } }; - skyblock: { - players: number; - modes: { - dungeonHub: number; - mining_2: number; - farming_2: number; - farming_1: number; - mining_3: number; - combat_3: number; - dynamic: number; - combat_1: number; - foraging_1: number; - hub: number; - dungeon: number; - combat_2: number; - mining_1: number; - }; - }; - copsAndCrims: { - players: number; - modes: { normal: number; deathmatch: number }; - }; - murderMystery: { - players: number; - modes: { - murderDoubleUp: number; - murderInfection: number; - murderAssassins: number; - murderClassic: number; - }; - }; - arcade: { - players: number; - modes: { - party: number; - holeInTheWall: number; - defender: number; - miniWalls: number; - simonSays: number; - zombiesBadBlood: number; - hideAndSeekPartyPooper: number; - dayone: number; - drawTheirThing: number; - zombiesAlienArcadium: number; - oneinthequiver: number; - soccer: number; - pvpCtw: number; - ender: number; - throwOut: number; - starwars: number; - dragonwars2: number; - zombiesDeadEnd: number; - farmHunt: number; - hideAndSeekPropHunt: number; - }; - }; - warlords: { - players: number; - modes: { ctfMini: number; domination: number; teamDeathmatch: number }; - }; - limbo: { players: number }; - idle: { players: number }; - queue: { players: number }; - } - class Arcade { - constructor(data?: Record); - lastTourneyAdTimestamp: number; - lastTourneyAdAt: Date; - coins: number; - weeklyCoins: number; - monthlyCoins: number; - hintsDisabled: boolean; - flashDisabled: boolean; - blockingDead: BlockingDead; - bountyHunters: BountyHunters; - dragonWars: DragonWars; - dropper: Dropper; - enderSpleef: EnderSpleef; - farmHunt: FarmHunt; - football: Football; - galaxyWars: GalaxyWars; - hideAndSeek: HideAndSeek; - holeInTheWall: HoleInTheWall; - hypixelSays: HypixelSays; - miniWalls: MiniWalls; - pixelParty: PixelParty; - zombies: Zombies; - } - class BlockingDead { - constructor(data: Record); - wins: number; - kills: number; - headshots: number; - } - class BountyHunters { - constructor(data: Record); - wins: number; - kills: number; - deaths: number; - KDRatio: number; - bountyKills: number; - bowKills: number; - swordKills: number; - } - class DragonWars { - constructor(data: Record); - wins: number; - kills: number; - } - class DropperMap { - constructor(data: Record, mapName: string); - bestTime: number; - completions: number; - } - class Dropper { - constructor(data: Record); - wins: number; - fails: number; - fastestGame: number; - flawlessGames: number; - gamesPlayed: number; - mapsCompleted: number; - gamesFinished: number; - maps: Record; - } - class EnderSpleef { - constructor(data: Record); - wins: number; - kills: number; - trail: string; - blocksDestroyed: number; - bigShotActivations: number; - tripleShotActivations: number; - totalPowerUpActivations: number; - } - class FarmHunt { - constructor(data: Record); - wins: number; - winsAsAnimal: number; - winsAsHunter: number; - kills: number; - killsAsAnimal: number; - killsAsHunter: number; - tauntsUsed: number; - riskyTauntsUsed: number; - safeTauntsUsed: number; - dangerousTauntsUsed: number; - fireworkTauntsUsed: number; - poop: number; - } - class Football { - constructor(data: Record); - wins: number; - kicks: number; - powerKicks: number; - goals: number; - } - class GalaxyWars { - constructor(data: Record); - wins: number; - kills: number; - deaths: number; - shotsFired: number; - weeklyKills: number; - monthlyKills: number; - attackerKills: number; - defenderKills: number; - } - class PartyPooper { - constructor(data: Record); - winsAsSeeker: number; - winsAsHider: number; - wins: number; - } - class PropHunt { - constructor(data: Record); - winsAsSeeker: number; - winsAsHider: number; - wins: number; - } - class HideAndSeek { - constructor(data: Record); - partyPooper: PartyPooper; - propHunt: PropHunt; - winsAsSeeker: number; - winsAsHider: number; - } - class HoleInTheWall { - constructor(data: Record); - wins: number; - rounds: number; - scoreRecordFinals: number; - scoreRecordNormal: number; - scoreRecordOverall: number; - } - class HypixelSays { - constructor(data: Record); - wins: number; - rounds: number; - roundWins: number; - topScore: number; - } - class MiniWalls { - constructor(data: Record); - kit: string; - wins: number; - kills: number; - deaths: number; - KDRatio: number; - finalKills: number; - witherKills: number; - witherDamage: number; - arrowsShot: number; - arrowsHit: number; - bowAccuracy: number; - } - class PixelPartyGameMode { - constructor(data: Record, modeName: string); - wins: number; - gamesPlayed: number; - losses: number; - WLRatio: number; - roundsPlayed: number; - powerUpsCollected: number; - } - class PixelParty { - constructor(data: Record); - wins: number; - gamesPlayed: number; - losses: number; - WLRatio: number; - roundsPlayed: number; - powerUpsCollected: number; - normal: PixelPartyGameMode; - hyper: PixelPartyGameMode; - highestRound: number; - musicVolume: number; - colorBlind: object; - } - class ThrowOut { - constructor(data: Record); - wins: number; - kills: number; - deaths: number; - KDRatio: number; - } - class Zombies { - constructor(data: Record); - overall: ZombiesStats; - deadEnd: ZombiesStats; - badBlood: ZombiesStats; - alienArcadium: ZombiesStats; - prison: ZombiesStats; - killsByZombie: Record; - bulletsHit: number; - bulletsShot: number; - gunAccuracy: number; - headshots: number; - headshotAccuracy: number; - } - class ZombiesStats { - constructor(data: Record, type?: string); - bestRound: number; - deaths: number; - doorsOpened: number; - fastestRound10: number; - fastestRound20: number; - fastestRound30: number; - playersRevived: number; - timesKnockedDown: number; - roundsSurvived: number; - windowsRepaired: number; - wins: number; - zombieKills: number; - } - - class ArenaBrawlMode { - constructor(data: Record); - damage: number; - kills: number; - deaths: number; - KDRatio: number; - healed: number; - wins: number; - losses: number; - WLRatio: number; - games: number; - winstreak: number; - } - class ArenaBrawl { - constructor(data: Record); - coins: number; - coinsSpent: number; - wins: number; - keys: number; - chests: number; - rune: string; - '1v1': ArenaBrawlMode; - '2v2': ArenaBrawlMode; - '4v4': ArenaBrawlMode; - } - class Paintball { - constructor(data: Record); - coins: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - shotsFired: number; - killstreaks: number; - forceFieldTime: number; - hat: string; - adrenaline: number; - endurance: number; - fortune: number; - godfather: number; - superluck: number; - transfusion: number; - } - class QuakecraftMode { - constructor(data: Record); - wins: number; - kills: number; - deaths: number; - KDRatio: number; - killstreaks: number; - distanceTravelled: number; - shotsFired: number; - headshots: number; - } - class Quakecraft { - constructor(data: Record); - coins: number; - solo: QuakecraftMode; - teams: QuakecraftMode; - wins: number; - kills: number; - deaths: number; - KDRatio: number; - killstreaks: number; - distanceTravelled: number; - shotsFired: number; - headshots: number; - instantRespawn: boolean; - killPrefixColor: string; - showPrefix: boolean; - killSound: string; - barrel: string; - case: string; - muzzle: string; - sight: string; - trigger: string; - } - class TurboKartRacersMap { - constructor(data: Record, mapName: string); - map: string; - plays: number; - boxPickups: number; - bronzeTrophies: number; - silverTrophies: number; - goldTrophies: number; - } - class TurboKartRacers { - constructor(data: Record); - coins: number; - wins: number; - completedLaps: number; - bronzeTrophies: number; - silverTrophies: number; - goldTrophies: number; - boxPickups: number; - horn: - | 'DEFAULT' - | 'SHY' - | 'ALIEN' - | 'TAXI' - | 'KLAXON' - | 'TRICYCLE' - | 'ALARM' - | 'KLOON' - | 'TEDDY' - | 'TRUCK' - | 'JERRY'; - retro: TurboKartRacersMap; - hypixelgp: TurboKartRacersMap; - olympus: TurboKartRacersMap; - junglerush: TurboKartRacersMap; - canyon: TurboKartRacersMap; - bananaHitsReceived: number; - bananaHitsSent: number; - blueTorpedoHit: number; - grandPrix: boolean; - grandPrixTokens: number; - } - class Walls { - constructor(data: Record); - coins: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - assists: number; - } - class WarlordsClass { - constructor(data: Record, className: string); - wins: number; - losses: number; - WLRatio: number; - gamesPlayed: number; - damage: number; - heal: number; - damagePrevented: number; - } - class Warlords { - constructor(data: Record); - coins: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - winstreak: number; - assists: number; - class: string; - pyromancer: WarlordsClass; - mage: WarlordsClass; - thunderlord: WarlordsClass; - shaman: WarlordsClass; - earthwarden: WarlordsClass; - aquamancer: WarlordsClass; - paladin: WarlordsClass; - avenger: WarlordsClass; - warrior: WarlordsClass; - defender: WarlordsClass; - cryomancer: WarlordsClass; - crusader: WarlordsClass; - berserker: WarlordsClass; - protector: WarlordsClass; - revenant: WarlordsClass; - spiritguard: WarlordsClass; - } - class BlitzSGKit { - constructor(data: Record, kitName: string); - level: number; - exp: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - gamesPlayed: number; - losses: number; - WLRatio: number; - arrowsShot: number; - arrowsHit: number; - bowAccuracy: number; - damage: number; - damageTaken: number; - potionsDrunk: number; - potionsThrown: number; - playTime: number; - mobsSpawned: number; - chestsOpened: number; - } - class BlitzSurvivalGames { - constructor(data: Record); - coins: number; - kills: number; - kit: string; - killsSolo: number; - killsTeams: number; - deaths: number; - KDRatio: number; - wins: number; - winsSolo: number; - winsTeam: number; - gamesPlayed: number; - losses: number; - WLRatio: number; - arrowsShot: number; - arrowsHit: number; - bowAccuracy: number; - damage: number; - damageTaken: number; - potionsDrunk: number; - potionsThrown: number; - mobsSpawned: number; - playTime: number; - blitzUses: number; - chestsOpened: number; - archer: BlitzSGKit; - meatmaster: BlitzSGKit; - speleologist: BlitzSGKit; - baker: BlitzSGKit; - knight: BlitzSGKit; - guardian: BlitzSGKit; - scout: BlitzSGKit; - hunter: BlitzSGKit; - hypeTrain: BlitzSGKit; - fisherman: BlitzSGKit; - armorer: BlitzSGKit; - horsetamer: BlitzSGKit; - astronaut: BlitzSGKit; - troll: BlitzSGKit; - reaper: BlitzSGKit; - shark: BlitzSGKit; - reddragon: BlitzSGKit; - toxicologist: BlitzSGKit; - rogue: BlitzSGKit; - warlock: BlitzSGKit; - slimeyslime: BlitzSGKit; - jockey: BlitzSGKit; - golem: BlitzSGKit; - viking: BlitzSGKit; - shadowKnight: BlitzSGKit; - pigman: BlitzSGKit; - paladin: BlitzSGKit; - necromancer: BlitzSGKit; - florist: BlitzSGKit; - diver: BlitzSGKit; - arachnologist: BlitzSGKit; - blaze: BlitzSGKit; - wolftamer: BlitzSGKit; - tim: BlitzSGKit; - farmer: BlitzSGKit; - creepertamer: BlitzSGKit; - snowman: BlitzSGKit; - } - class VampireZRole { - constructor(data: Record, role: string); - kills: number; - deaths: number; - KDRatio: number; - wins: number; - } - class VampireZ { - constructor(data: Record); - coins: number; - goldBought: number; - blood: boolean; - zombieKills: number; - human: VampireZRole; - vampire: VampireZRole; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - } - class SmashHeroesMode { - constructor(data: Record, mode: string); - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - } - class SmashHeoresHero { - constructor(data: Record, hero: string); - name: string; - level: number; - xp: number; - prestige: number; - playedGames: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - } - class SmashHeroes { - constructor(data: Record); - coins: number; - level: number; - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - smashed: number; - '1v1v1v1': SmashHeroesMode; - '2v2': SmashHeroesMode; - '2v2v2': SmashHeroesMode; - activeClass: string; - theBulk: SmashHeoresHero; - cakeMonster: SmashHeoresHero; - generalCluck: SmashHeoresHero; - botmun: SmashHeoresHero; - marauder: SmashHeoresHero; - pug: SmashHeoresHero; - tinman: SmashHeoresHero; - spoderman: SmashHeoresHero; - frosty: SmashHeoresHero; - sergeantShield: SmashHeoresHero; - skullfire: SmashHeoresHero; - goku: SmashHeoresHero; - sanic: SmashHeoresHero; - duskCrawler: SmashHeoresHero; - shoopDaWhoop: SmashHeoresHero; - greenHood: SmashHeoresHero; - } - class SkyblockNews { - constructor(data: Record); - title: string; - link: string; - rawDate: string; - date: Date; - version: string | null; - } - class TNTGames { - constructor(data: Record); - coins: number; - winstreak: number; - wins: number; - tntrun: { - wins: number; - deaths: number; - record: number; - }; - pvprun: { - kills: number; - wins: number; - deaths: number; - KDRatio: number; - record: number; - }; - tnttag: { - kills: number; - wins: number; - speed: number; - }; - bowspleef: { - wins: number; - tags: number; - deaths: number; - }; - wizards: { - points: number; - class: string; - kills: number; - assists: number; - wins: number; - deaths: number; - KDRatio: number; - }; - } - class Status { - constructor(data: Record); - online: boolean; - game?: Game; - mode?: string; - map?: string; - } - class Guild { - constructor(data: Record); - id: string; - name: string; - description: string; - experience: number; - level: number; - createdAtTimestamp: number; - createdAt: Date; - joinable: boolean; - publiclyListed: boolean; - tag: string; - tagColor: Color; - legacyRank: number; - expHistory: { day: string; date: Date; exp: number; totalExp: number }[]; - achievements: { - winners: number; - experienceKings: number; - onlinePlayers: number; - }; - me?: GuildMember; - chatMuteUntilTimestamp: number; - chatMuteUntil: Date; - banner: { Base: string; Patterns: [{ Pattern: string; Color: string }] }; - preferredGames: Game[]; - members: GuildMember[]; - ranks: GuildRank[]; - totalWeeklyGexp: number; - get guildMaster(): GuildMember; - getRanksByNewest(): GuildRank[]; - getRankByPriority(priority: number): GuildRank; - getMemberUUIDMap(): Map; - toString(): string; - } - class BaseAuction { - constructor(data: Record); - auctionId: string; - auctioneerUuid: string; - auctioneerProfile: string; - bin: boolean; - itemBytes: ItemBytes | null; - } - class Auction extends BaseAuction { - constructor(data: Record); - coop: string[] | []; - auctionStartTimestamp: number; - auctionEndTimestamp: number; - auctionStart: Date; - auctionEnd: Date; - item: string; - itemLore: string; - itemLoreRaw: string; - rarity: string; - startingBid: number; - highestBid: number; - bids: Bid[]; - claimed: boolean; - claimedBidders: string[]; - } - class PartialAuction extends BaseAuction { - constructor(data: Record); - buyer: string; - price: number; - } - class AuctionInfo { - constructor(data: Record); - age: number; - lastUpdatedAt: Date; - lastUpdated: number; - totalPages: number; - page: number; - totalAuctions: number; - failedPages: number[]; - } - class Bid { - constructor(data: Record); - auctionId: string; - profileId: string; - amount: number; - timestamp: number; - at: Date; - bidder: string; - } - class Product { - constructor(data: Record); - productId: string; - sellSummary: Order[]; - buySummary: Order[]; - status: { - sellPrice: number; - buyPrice: number; - sellVolume: number; - buyVolume: number; - sellMovingWeek: number; - buyMovingWeek: number; - sellOrders: number; - buyOrders: number; - }; - } - class Order { - constructor(data: Record); - amount: number; - pricePerUnit: number; - totalPrice: number; - orders: number; - } - class BingoData { - constructor(data: Record); - lastUpdatedTimestamp: number; - lastUpdatedAt: Date | null; - id: number | null; - goals: Bingo[] | null; - getGoal(column: number, row: number): Bingo | undefined; - } - class PlayerBingo { - constructor(data: Record, bingoData: BingoData | null); - dataPerEvent: PlayerBingoDataPerEvent[]; - } - type PlayerBingoDataPerEvent = { - eventId: number; - points: number; - enrichedGoals: boolean; - goalsCompleted: SpecialBingoArray | string[]; - }; - type SpecialBingoArray = Bingo[] & { - unachievedGoals: Bingo[]; - }; - class GovernmentData { - constructor(data: Record); - lastUpdatedTimestamp: number; - lastUpdatedAt: Date | null; - lastElectionResults: Map; - mayor: Candidate; - runningYear: number; - currentElectionResults: Map | null; - currentElectionFor: number | null; - } - class Perk { - name: string; - description: string; - } - class Candidate { - constructor(data: Record, isMayor?: boolean | undefined, isMinister?: boolean | undefined); - name: string; - keyBenefit: string; - perk: Perk | null; - perks: Perk[]; - isMayor: boolean; - isMinister: boolean; - votesReceived: number; - toString(): string; - } - class FireSale { - constructor(data: Record); - itemId: string; - startTimestamp: number; - startAt: Date; - endTimestamp: number; - endAt: Date; - amount: number; - price: number; - toString(): string; - } - class WatchdogStats { - constructor(data: Record); - byWatchdogTotal: number; - byWatchdogLastMinute: number; - byWatchdogRollingDay: number; - byStaffTotal: number; - byStaffRollingDay: number; - } - class GuildMember { - constructor(data: Record); - uuid: string; - joinedAtTimestamp: number; - joinedAt: Date; - questParticipation: number; - rank: string; - weeklyExperience: number; - mutedUntilTimestamp: number; - mutedUntil: Date; - expHistory: { day: string; date: Date; exp: number; totalExp: number }[]; - } - class GuildRank { - constructor(data: Record); - name: string; - default: boolean; - tag: string | null; - createdAtTimestamp: number; - createdAt: Date; - priority: number; - } - class Booster { - constructor(data: Record); - purchaser: string; - amount: number; - originalLength: number; - remaining: number; - activatedTimestamp: number; - activated: Date; - game?: Game; - isActive: boolean; - type: 'QUEUED' | 'STACKED' | 'ACTIVE'; - stackers: string[]; - expired: boolean; - } - class SkyblockProfile { - constructor(data: Record); - profileId: string; - profileName: string; - members: SkyblockMember[]; - me: SkyblockMember; - selected: boolean; - garden?: SkyblockGarden; - } - class SkyblockPet { - constructor(data: Record); - uuid: string; - type: string; - xp: number; - active: boolean; - rarity: SkyblockRarity; - petScore: number; - heldItem: string | null; - candyUsed: number; - skin: string | null; - } - class SkyblockMuseumItem { - constructor(data: Record); - name: string | null; - items: SkyblockInventoryItem[]; - donatedTime: number; - donatedTimeAt: Date; - borrowing: boolean; - featuredSlot: string | null; - } - class SkyblockMuseum { - constructor(data: Record); - raw: object; - getWardrobe(): Promise; - getWardrobe(): Promise; - } - class SkyblockGarden { - constructor(data: Record); - level: SKYBLOCK_SKILL_DATA; - barnSkin: string; - unlockedPlots: string[]; - visitors: SKYBLOCK_GARDEN_VISITOR; - cropMilestones: { - wheat: SKYBLOCK_SKILL_DATA; - carrot: SKYBLOCK_SKILL_DATA; - sugarCane: SKYBLOCK_SKILL_DATA; - potato: SKYBLOCK_SKILL_DATA; - pumpkin: SKYBLOCK_SKILL_DATA; - melon: SKYBLOCK_SKILL_DATA; - cactus: SKYBLOCK_SKILL_DATA; - cocoaBeans: SKYBLOCK_SKILL_DATA; - mushroom: SKYBLOCK_SKILL_DATA; - netherWart: SKYBLOCK_SKILL_DATA; - }; - composter: SKYBLOCK_GARDEN_COMPOSTER; - cropUpgrades: SKYBLOCK_GARDEN_CROPS; - } - class SkyblockMember { - constructor(data: Record); - uuid: string; - player: Player | null; - museum: SkyblockMuseum | null; - garden: SkyblockGarden | null; - gameMode: string | null; - selected: boolean; - profileName: string; - profileId: string; - firstJoinTimestamp: number; - firstJoinAt: Date; - experience: number; - level: number; - hotm: { - experience: SKYBLOCK_SKILL_DATA; - ability: string; - powder: { - mithril: { - spent: number; - current: number; - total: number; - }; - gemstone: { - spent: number; - current: number; - total: number; - }; - glacite: { - spent: number; - current: number; - total: number; - }; - }; - }; - highestMagicalPower: number; - fairySouls: number; - fairyExchanges: number; - skills: { - combat: SKYBLOCK_SKILL_DATA; - farming: SKYBLOCK_SKILL_DATA; - fishing: SKYBLOCK_SKILL_DATA; - mining: SKYBLOCK_SKILL_DATA; - foraging: SKYBLOCK_SKILL_DATA; - enchanting: SKYBLOCK_SKILL_DATA; - alchemy: SKYBLOCK_SKILL_DATA; - carpentry: SKYBLOCK_SKILL_DATA; - runecrafting: SKYBLOCK_SKILL_DATA; - taming: SKYBLOCK_SKILL_DATA; - social: SKYBLOCK_SKILL_DATA; - average: number; - }; - bestiary: number; - slayer: { - zombie: SKYBLOCK_SLAYER_DATA; - spider: SKYBLOCK_SLAYER_DATA; - wolf: SKYBLOCK_SLAYER_DATA; - enderman: SKYBLOCK_SLAYER_DATA; - blaze: SKYBLOCK_SLAYER_DATA; - vampire: SKYBLOCK_SLAYER_DATA; - } | null; - crimson: { - faction: 'mages' | 'barbarians' | null; - repuation: { - barbarians: number; - mages: number; - }; - trophyFish: { - rank: 'Diamond' | 'Gold' | 'Silver' | 'Bronze' | null; - caught: { - total: number; - bronze: number; - silver: number; - gold: number; - diamond: number; - }; - }; - kuudra: { - none: number; - hot: number; - burning: number; - fiery: number; - highestWaveHot: number; - highestWaveFiery: number; - infernal: number; - highestWaveInfernal: number; - highestWaveBurning: number; - }; - }; - dungeons: { - experience: SKYBLOCK_SKILL_DATA; - secrets: number; - completions: { - catacombs: Record; - masterCatacombs: Record; - }; - floors: { - entrance: SKYBLOCK_DUNGEONS_FLOOR; - floor1: SKYBLOCK_DUNGEONS_FLOOR; - floor2: SKYBLOCK_DUNGEONS_FLOOR; - floor3: SKYBLOCK_DUNGEONS_FLOOR; - floor4: SKYBLOCK_DUNGEONS_FLOOR; - floor5: SKYBLOCK_DUNGEONS_FLOOR; - floor6: SKYBLOCK_DUNGEONS_FLOOR; - floor7: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs1: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs2: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs3: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs4: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs5: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs6: SKYBLOCK_DUNGEONS_FLOOR; - masterCatacombs7: SKYBLOCK_DUNGEONS_FLOOR; - }; - classes: { - healer: SKYBLOCK_SKILL_DATA; - mage: SKYBLOCK_SKILL_DATA; - berserk: SKYBLOCK_SKILL_DATA; - archer: SKYBLOCK_SKILL_DATA; - tank: SKYBLOCK_SKILL_DATA; - selected: string; - }; - essence: { - diamond: number; - dragon: number; - spider: number; - wither: number; - undead: number; - gold: number; - ice: number; - crimson: number; - }; - } | null; - collections: object; - purse: number; - stats: object; - pets: SkyblockPet[]; - jacob: { - medals: { - bronze: number; - silver: number; - gold: number; - }; - perks: { - doubleDrops: number; - farmingLevelCap: number; - personalBests: boolean; - }; - contests: object; - }; - chocolate: { - employees: { - bro: number; - cousin: number; - sis: number; - father: number; - grandma: number; - dog: number; - uncle: number; - }; - chocolate: { - current: number; - total: number; - sincePrestige: number; - }; - timeTower: { - charges: number; - level: number; - }; - upgrades: { - click: number; - multiplier: number; - rabbitRarity: number; - }; - goldenClick: { - amount: number; - year: number; - }; - barnCapacity: number; - prestige: number; - }; - getArmor(): Promise<{ - helmet: SkyblockInventoryItem; - chestplate: SkyblockInventoryItem; - leggings: SkyblockInventoryItem; - boots: SkyblockInventoryItem; - }>; - getWardrobe(): Promise; - getEnderChest(): Promise; - getInventory(): Promise; - getPetScore(): number; - getEquipment(): Promise<{ - gauntlet: SkyblockInventoryItem; - belt: SkyblockInventoryItem; - cloak: SkyblockInventoryItem; - necklace: SkyblockInventoryItem; - }>; - getPersonalVault(): Promise; - getNetworth(): Promise; - } - class Color { - constructor(color: string); - toCode(): string; - toHex(): string; - toString(): string; - toInGameCode(): string; - } - class SkyblockInventoryItem { - constructor(data: Record); - itemId: number; - count: number; - name: string; - lore: string; - loreArray: string[]; - loreForEmbed: string; - color: string | null; - enchantments: Record; - reforge: string; - gemstones?: { - type?: string; - quality?: string; - }[]; - damage: number; - rarity: string; - dungeonStars: number; - gearScore: number; - uuid: string; - soulbound: boolean; - artOfWar: number; - rune: object; - hotPotatoBooks: number; - recombobulated: boolean; - attributes: object; - hecatomb: number; - champion: number; - cultivating: number; - expertise: number; - compact: number; - blocksWalked: number; - toString(): string; - } - class Game { - constructor(game: string | number); - toString(): GAME_NAME; - code: GAME_CODE; - id: GAME_ID; - name: GAME_NAME; - found: boolean; - private game: GAME_CODE | GAME_ID | GAME_NAME; - static IDS: GAME_ID[]; - static CODES: GAME_CODE[]; - static NAMES: GAME_NAME[]; - } - class SkyWarsMode { - constructor(data: Record, gamemode: string); - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - } - class SkywarsModeStats { - constructor(data: Record, gamemode: string); - activeKit: string; - killstreak: number; - kills: number; - voidKills: number; - meleeKills: number; - bowKills: number; - mobKills: number; - assists: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - gamesPlayed: number; - survivedPlayers: number; - chestsOpened: number; - timePlayed: number; - shard: number; - longestBowShot: number; - arrowsShot: number; - arrowsHit: number; - bowAccuracy: number; - fastestWin: number; - heads: number; - } - class SkywarsMode { - constructor(data: Record, gamemode: string); - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - } - class SkyWars { - constructor(data: Record); - coins: number; - souls: number; - tokens: number; - experience: number; - level: number; - levelProgress: LevelProgress; - levelFormatted: string; - prestige: SKYWARS_PRESTIGE; - prestigeIcon: SKYWARS_PRESTIGE_ICON; - opals: number; - avarice: number; - tenacity: number; - shards: number; - angelOfDeathLevel: number; - killstreak: number; - kills: number; - voidKills: number; - meleeKills: number; - bowKills: number; - mobKills: number; - assists: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - gamesPlayed: number; - survivedPlayers: number; - chestsOpened: number; - timePlayed: number; - shard: number; - longestBowShot: number; - arrowsShot: number; - arrowsHit: number; - bowAccuracy: number; - fastestWin: number; - heads: number; - blocksPlaced: number; - blocksBroken: number; - eggThrown: number; - enderpearlsThrown: number; - solo: SkywarsModeStats; - soloNormal: SkywarsMode; - soloInsane: SkywarsMode; - team: SkywarsModeStats; - teamNormal: SkywarsMode; - mega: SkywarsMode; - megaDoubles: SkywarsMode; - lab: SkywarsMode; - packages: SkywarsPackages; - } - class SkywarsPackages { - constructor(data: string[]); - rawPackages: string[]; - cages: string[]; - kits: SkywarsKits; - } - class SkywarsKits { - constructor(kits: Record); - kits: SkywarsKit[]; - get(gameMode: SKYWARS_KIT_GAMEMODE, type: SKYWARS_KIT_TYPE): SkywarsKit[]; - } - class SkywarsKit { - constructor(kit: string); - private _kitData: string[] | null; - isKit: boolean; - gameMode?: SKYWARS_KIT_GAMEMODE; - kitType?: SKYWARS_KIT_TYPE; - kitName?: string; - } - class CopsAndCrims { - constructor(data: Record); - coins: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - roundWins: number; - shotsFired: number; - headshotKills: number; - bombsDefused: number; - bombsPlanted: number; - killsAsCrim: number; - killsAsCop: number; - deathmatch: { - kills: number; - deaths: number; - KDRatio: number; - killsAsCrim: number; - killsAsCop: number; - }; - } - class BedWars { - constructor(data: Record); - tokens: number; - level: number; - experience: number; - prestige: BEDWARS_PRESTIGE; - playedGames: number; - wins: number; - winstreak: number; - kills: number; - finalKills: number; - losses: number; - deaths: number; - finalDeaths: number; - collectedItemsTotal: { - iron: number; - gold: number; - diamond: number; - emerald: number; - }; - beds: { - lost: number; - broken: number; - BLRatio: number; - }; - avg: { - finalKills: number; - kills: number; - bedsBroken: number; - }; - KDRatio: number; - finalKDRatio: number; - WLRatio: number; - solo: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - threes: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - '4v4': { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - dream: { - ultimate: { - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - }; - rush: { - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - }; - armed: { - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - }; - lucky: { - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - }; - voidless: { - doubles: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - fours: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - KDRatio: number; - WLRatio: number; - finalKDRatio: number; - }; - }; - }; - castle: { - winstreak: number; - playedGames: number; - kills: number; - deaths: number; - wins: number; - losses: number; - finalKills: number; - finalDeaths: number; - beds: { - broken: number; - lost: number; - BLRatio: number; - }; - avg: { - kills: number; - finalKills: number; - bedsBroken: number; - }; - }; - practice: { - selected: string; - bridging: { - blocksPlaced: number; - attempts: { - failed: number; - successful: number; - total: number; - }; - records: { - '30Blocks': { - elevation: { - none: { - straight: number; - diagonal: number; - }; - slight: { - straight: number; - diagonal: number; - }; - staircase: { - straight: number; - diagonal: number; - }; - }; - }; - '50Blocks': { - elevation: { - none: { - straight: number; - diagonal: number; - }; - slight: { - straight: number; - diagonal: number; - }; - staircase: { - straight: number; - diagonal: number; - }; - }; - }; - '100Blocks': { - elevation: { - none: { - straight: number; - diagonal: number; - }; - slight: { - straight: number; - diagonal: number; - }; - staircase: { - straight: number; - diagonal: number; - }; - }; - }; - }; - }; - fireballJumping: { - blocksPlaced: number; - attempts: { - failed: number; - successful: number; - total: number; - }; - }; - pearlClutching: { - attempts: { - failed: number; - successful: number; - total: number; - }; - }; - mlg: { - blocksPlaced: number; - attempts: { - failed: number; - successful: number; - total: number; - }; - }; - }; - slumberTickets: number; - totalSlumberTickets: number; - } - - class UHCGamemode { - constructor(data: Record, mode: string); - kills: number; - deaths: number; - wins: number; - headsEaten: number; - ultimatesCrafted: number; - extraUltimatesCrafted: number; - } - class UHC { - constructor(data: Record); - coins: number; - score: number; - kit: string; - solo: UHCGamemode; - team: UHCGamemode; - redVsBlue: UHCGamemode; - noDiamond: UHCGamemode; - brawl: UHCGamemode; - soloBrawl: UHCGamemode; - duoBrawl: UHCGamemode; - wins: number; - kills: number; - deaths: number; - KDRatio: number; - headsEaten: number; - ultimatesCrafted: number; - extraUltimatesCrafted: number; - starLevel: number; - } - class SpeedUHCMode { - constructor(data: Record, mode: string); - kills: number; - deaths: number; - wins: number; - losses: number; - playedGames: number; - winstreak: number; - killStreak: number; - assists: number; - } - class SpeedUHC { - constructor(data: Record); - coins: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - winstreak: number; - killstreak: number; - blocksBroken: number; - blocksPlaced: number; - quits: number; - itemsEnchanted: number; - assists: number; - solo: SpeedUHCMode; - soloNormal: SpeedUHCMode; - soloInsane: SpeedUHCMode; - team: SpeedUHCMode; - teamNormal: SpeedUHCMode; - teamInsane: SpeedUHCMode; - } - class MurderMysteryModeStats { - constructor(data: Record, gamemode: string); - goldPickedUp: number; - kills: number; - thrownKnifeKills: number; - knifeKills: number; - bowKills: number; - trapKills: number; - deaths: number; - suicides: number; - KDRatio: number; - wins: number; - winsAsDetective: number; - winsAsMurderer: number; - winsAsHero: number; - playedGames: number; - } - class MurderMystery { - constructor(data: Record); - tokens: number; - goldPickedUp: number; - playedGames: number; - kills: number; - thrownKnifeKills: number; - knifeKills: number; - trapKills: number; - bowKills: number; - killsAsMurderer: number; - deaths: number; - KDRatio: number; - winsAsMurderer: number; - winsAsDetective: number; - winsAsHero: number; - fastestWinAsMurderer: number; - fastestWinAsDetective: number; - totalTimeSurvived: number; - wins: number; - suicides: number; - classic: MurderMysteryModeStats; - assassins: MurderMysteryModeStats; - doubleUp: MurderMysteryModeStats; - infection: MurderMysteryModeStats; - } - class DuelsGamemode { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - goals: number; - } - class DuelsUHC { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - solo: DuelsGamemode; - doubles: DuelsGamemode; - fours: DuelsGamemode; - deathmatch: DuelsGamemode; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - } - class DuelsSkyWars { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - solo: DuelsGamemode; - doubles: DuelsGamemode; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - } - class DuelsMegaWalls { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - solo: DuelsGamemode; - doubles: DuelsGamemode; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - } - class DuelsOP { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - solo: DuelsGamemode; - doubles: DuelsGamemode; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - } - class DuelsBridge { - constructor(data: Record, mode: string, title: string); - title: string; - winstreak: number; - bestWinstreak: number; - solo: DuelsGamemode; - doubles: DuelsGamemode; - threes: DuelsGamemode; - fours: DuelsGamemode; - '2v2v2v2': DuelsGamemode; - '3v3v3v3': DuelsGamemode; - ctf: DuelsGamemode; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - blocksPlaced: number; - healthRegenerated: number; - goldenApplesEatan: number; - goals: number; - } - class Duels { - constructor(data: Record); - tokens: number; - title: string | null; - kills: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - playedGames: number; - winstreak: number; - bestWinstreak: number; - ping: number; - blocksPlaced: number; - swings: number; - hits: number; - meleeAccuracy: number; - bowShots: number; - bowHits: number; - bowAccuracy: number; - healthRegenerated: number; - goldenApplesEatan: number; - uhc: DuelsUHC; - skywars: DuelsSkyWars; - megawalls: DuelsMegaWalls; - blitz: DuelsGamemode; - op: DuelsOP; - classic: DuelsGamemode; - bow: DuelsGamemode; - noDebuff: DuelsGamemode; - combo: DuelsGamemode; - bowSpleef: DuelsGamemode; - sumo: DuelsGamemode; - bridge: DuelsBridge; - parkour: DuelsGamemode; - arena: DuelsGamemode; - } - class BuildBattle { - constructor(data: Record); - score: number; - totalWins: number; - games: number; - WLRatio: number; - superVotes: number; - coins: number; - totalVotes: number; - wins: { - solo: number; - teams: number; - pro: number; - gtb: number; - }; - } - class RecentGame extends Game { - constructor(data: Record); - dateTimestamp?: number; - date?: Date; - mode?: string; - map?: string; - ongoing?: boolean; - endedAt?: Date; - endedTimestamp?: number; - } - class MegaWallsModeStats { - constructor(data: Record, mode: string, kit?: string); - kills: number; - assists: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - finalKills: number; - finalAssists: number; - finalDeaths: number; - finalKDRatio: number; - playedGames: number; - witherDamage: number; - defenderKills: number; - walked: number; - blocksPlaced: number; - blocksBroken: number; - meleeKills: number; - damageDealt: number; - } - class MegaWallsKitStats { - constructor(data: Record, kit: string); - kills: number; - assists: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - finalKills: number; - finalAssists: number; - finalDeaths: number; - finalKDRatio: number; - playedGames: number; - witherDamage: number; - defenderKills: number; - walked: number; - blocksPlaced: number; - blocksBroken: number; - meleeKills: number; - damageDealt: number; - faceOff: MegaWallsModeStats; - casualBrawl: MegaWallsModeStats; - } - class MegaWalls { - constructor(data: Record); - selectedClass: string | null; - coins: number; - kills: number; - assists: number; - deaths: number; - KDRatio: number; - wins: number; - losses: number; - WLRatio: number; - finalKills: number; - finalAssists: number; - finalDeaths: number; - finalKDRatio: number; - playedGames: number; - witherDamage: number; - defenderKills: number; - walked: number; - blocksPlaced: number; - blocksBroken: number; - meleeKills: number; - damageDealt: number; - faceOff: MegaWallsModeStats; - casualBrawl: MegaWallsModeStats; - cow: MegaWallsKitStats; - hunter: MegaWallsKitStats; - shark: MegaWallsKitStats; - arcanist: MegaWallsKitStats; - deadlord: MegaWallsKitStats; - golem: MegaWallsKitStats; - herobrine: MegaWallsKitStats; - pigman: MegaWallsKitStats; - zombie: MegaWallsKitStats; - blaze: MegaWallsKitStats; - enderman: MegaWallsKitStats; - shaman: MegaWallsKitStats; - squid: MegaWallsKitStats; - creeper: MegaWallsKitStats; - pirate: MegaWallsKitStats; - sheep: MegaWallsKitStats; - skeleton: MegaWallsKitStats; - spider: MegaWallsKitStats; - werewolf: MegaWallsKitStats; - angel: MegaWallsKitStats; - assassin: MegaWallsKitStats; - automaton: MegaWallsKitStats; - moleman: MegaWallsKitStats; - phoenix: MegaWallsKitStats; - renegade: MegaWallsKitStats; - snowman: MegaWallsKitStats; - } - class APIStatus { - constructor(data: Record); - sourceUrl: string; - title: string; - description: string; - incidents: APIIncident[]; - currentIncidents: APIIncident[]; - } - class APIIncident { - constructor(data: Record); - link: string; - start: Date; - startFormatted: string; - startTimestamp: number; - author: string; - HTMLContent: string; - snippet: string; - guid: string; - categories: string[]; - isResolved: boolean; - } - class ItemBytes { - constructor(data: Record); - bytesBuffer: Buffer; - base64(): string; - /** - * @description Reads the bytes as a NBT tag - */ - readNBT(): Promise; - } - class ServerInfo { - constructor(data: Record, ping: number); - protocolUsed: number; - versionInfo: string; - players: { - max: number; - online: number; - players: string[]; - }; - rawMOTD: string; - cleanMOTD: string; - textMOTD: string; - faviconB64: string; - favicon: Buffer; - ping: number; - } - - class Achievements { - lastUpdatedTimestamp: number; - lastUpdatedAt: Date; - achievementsPerGame: { - arcade: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - arena: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - bedwars: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - blitz: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - buildbattle: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - christmas2017: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - copsandcrims: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - duels: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - easter: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - general: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - gingerbread: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - halloween2017: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - housing: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - murdermystery: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - paintball: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - pit: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - quake: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - skyblock: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - skyclash: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - skywars: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - speeduhc: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - summer: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - supersmash: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - tntgames: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - truecombat: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - uhc: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - vampirez: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - walls: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - walls3: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - warlords: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - woolgames: { - category: string; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - }; - }; - } - class Achievement { - constructor(data: Record); - name: string; - codeName: string; - description: string; - type: ACHIEVEMENT_TYPE; - rarity: { - local?: number; - localPercentage?: number; - global?: number; - globalPercentage?: number; - }; - tierInformation?: AchievementTier; - points: number; - totalAmountRequired?: number; - toString(): string; - } - class AchievementTier { - constructor(data: Record); - maxTier: number; - getTier(tier: number): { - pointsRewarded?: number; - amountRequired?: number; - }; - } - class Challenges { - constructor(data: Record); - lastUpdatedTimestamp: number; - lastUpdatedAt: Date; - challengesPerGame: Record; - } - class GameAchievement { - constructor(data: Record); - category: GAME_STATIC; - totalPoints: number; - totalLegacyPoints: number; - achievements: Achievement[]; - } - class GameChallenges { - constructor(data: Record); - category: GAME_STATIC; - challenges: Map; - } - class GameQuests { - constructor(data: Record); - game: GAME_STATIC; - quests: Quest[]; - } - class GuildAchievements { - constructor(data: Record); - lastUpdatedTimestamp: number; - lastUpdatedAt: Date; - achievements: Record; - } - class Quest { - constructor(data: Record); - questName: string; - questID: string; - description: string; - type: QUEST_TYPE; - objectives: Objective[]; - rewards: QuestReward[]; - toString(): string; - } - class Quests { - constructor(data: Record); - lastUpdatedTimestamp: number; - lastUpdatedAt: Date; - questsPerGame: Record; - } - class Bingo { - constructor(data: Record); - name: string; - id: string; - row?: number; - column?: number; - rawLore: string; - lore: string; - tiers: number[]; - type: BINGO_TYPE; - tierStep?: number; - requiredAmount?: number; - toString(): string; - } - class House { - constructor(data: Record); - name: string; - uuid: string; - owner: string; - createdAtTimestamp: number; - createdAt: Date; - players: number; - cookies: number; - toString(): string; - } -} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 000000000..8b2f7cd0a --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,19 @@ +import { configDefaults, defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + exclude: [...configDefaults.exclude, 'dist/**', 'coverage/**', 'docs/**', '.github/**'], + setupFiles: ['./vitest.setup.ts'], + testTimeout: 30000, + coverage: { + exclude: [ + ...(configDefaults.coverage.exclude || []), + 'dist/**', + 'coverage/**', + 'docs/**', + 'src/Types/**', + '.github/**' + ] + } + } +}); diff --git a/vitest.setup.ts b/vitest.setup.ts new file mode 100644 index 000000000..b02f100e3 --- /dev/null +++ b/vitest.setup.ts @@ -0,0 +1,31 @@ +import 'dotenv/config'; + +if ((process.env.HYPIXEL_KEY || '').length < 1) throw new Error('No API Key specified!'); + +export const defaultRequestData = { + ok: true, + status: 200, + json: () => Promise.resolve({ success: true }), + headers: new Headers(), + redirected: false, + statusText: '', + type: 'basic', + url: '', + clone: (): Response => { + throw new Error('Function not implemented.'); + }, + body: null, + bodyUsed: false, + arrayBuffer: (): Promise => { + throw new Error('Function not implemented.'); + }, + blob: (): Promise => { + throw new Error('Function not implemented.'); + }, + formData: (): Promise => { + throw new Error('Function not implemented.'); + }, + text: (): Promise => { + throw new Error('Function not implemented.'); + } +};