├── .eslintignore ├── .npmrc ├── .gitattributes ├── public ├── logo.png └── logo_text.png ├── packages ├── beapi │ ├── src │ │ ├── client │ │ │ └── index.ts │ │ ├── decorators │ │ │ ├── index.ts │ │ │ └── setProto.ts │ │ ├── item │ │ │ └── index.ts │ │ ├── agent │ │ │ ├── index.ts │ │ │ └── Directions.ts │ │ ├── world │ │ │ └── index.ts │ │ ├── entity │ │ │ └── index.ts │ │ ├── block │ │ │ ├── index.ts │ │ │ ├── BlockType.ts │ │ │ └── Permutation.ts │ │ ├── inventory │ │ │ └── index.ts │ │ ├── player │ │ │ └── index.ts │ │ ├── polyfill │ │ │ └── index.ts │ │ ├── scoreboard │ │ │ ├── identity │ │ │ │ ├── index.ts │ │ │ │ ├── Fake.ts │ │ │ │ ├── Entity.ts │ │ │ │ └── Player.ts │ │ │ └── index.ts │ │ ├── types │ │ │ ├── Gamemode.ts │ │ │ ├── Util.ts │ │ │ ├── Scoreboards.ts │ │ │ ├── Formatting.ts │ │ │ ├── Timers.ts │ │ │ ├── ServerCommand.ts │ │ │ ├── Item.ts │ │ │ ├── Database.ts │ │ │ ├── Location.ts │ │ │ ├── index.ts │ │ │ ├── Dimension.ts │ │ │ ├── Forms.ts │ │ │ ├── Block.ts │ │ │ ├── World.ts │ │ │ └── Player.ts │ │ ├── commands │ │ │ └── index.ts │ │ ├── forms │ │ │ └── index.ts │ │ ├── database │ │ │ ├── index.ts │ │ │ ├── DatabaseUtil.ts │ │ │ └── Document.ts │ │ ├── utils │ │ │ ├── object.ts │ │ │ ├── index.ts │ │ │ ├── between.ts │ │ │ ├── destruct.ts │ │ │ ├── binary.ts │ │ │ ├── uuidv4.ts │ │ │ ├── getUniqueId.ts │ │ │ ├── formatting.ts │ │ │ ├── getCoordinatesBetween.ts │ │ │ ├── runCommand.ts │ │ │ ├── getEnchantments.ts │ │ │ └── ids.ts │ │ ├── version.ts │ │ ├── index.ts │ │ ├── poly.ts │ │ └── events │ │ │ ├── Swing.ts │ │ │ ├── ItemDropped.ts │ │ │ ├── Landed.ts │ │ │ ├── StartedSneaking.ts │ │ │ ├── StoppedSneaking.ts │ │ │ ├── Jump.ts │ │ │ ├── Respawn.ts │ │ │ ├── StoppedBurning.ts │ │ │ ├── Death.ts │ │ │ ├── StartedMoving.ts │ │ │ ├── StartedRiding.ts │ │ │ ├── StoppedMoving.ts │ │ │ ├── StartedBurning.ts │ │ │ ├── StartedSleeping.ts │ │ │ ├── StoppedRiding.ts │ │ │ ├── EnteredWater.ts │ │ │ ├── StartedSprinting.ts │ │ │ ├── StartedSwimming.ts │ │ │ ├── StoppedSleeping.ts │ │ │ ├── StoppedSwimming.ts │ │ │ ├── OnJoin.ts │ │ │ ├── ExitedWater.ts │ │ │ ├── StoppedSprinting.ts │ │ │ ├── AbstractEvent.ts │ │ │ ├── EntityKilled.ts │ │ │ ├── PlayerKilled.ts │ │ │ ├── OnLeave.ts │ │ │ ├── Explosion.ts │ │ │ ├── Piston.ts │ │ │ ├── Tick.ts │ │ │ ├── ItemUse.ts │ │ │ ├── EntityCreated.ts │ │ │ ├── EffectAdded.ts │ │ │ ├── WeatherUpdated.ts │ │ │ ├── OnChat.ts │ │ │ ├── ChestOpened.ts │ │ │ ├── ItemEventTrigger.ts │ │ │ ├── PlayerTag.ts │ │ │ ├── EntityTag.ts │ │ │ ├── ItemEvent.ts │ │ │ ├── BlockHit.ts │ │ │ ├── EntityDestroyed.ts │ │ │ ├── PlayerEventTrigger.ts │ │ │ └── EntityEventTrigger.ts │ ├── tsconfig.eslint.json │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── package.json │ └── README.md ├── tsconfig.json └── create-beapi │ ├── template-javascript │ ├── pack_icon.png │ ├── _gitignore │ ├── package.json │ ├── animation_controllers │ │ ├── swing.json │ │ ├── jump.json │ │ ├── land.json │ │ ├── death.json │ │ ├── move.json │ │ ├── sleep.json │ │ ├── fire.json │ │ ├── riding.json │ │ ├── sneak.json │ │ ├── swim.json │ │ ├── inwater.json │ │ └── sprint.json │ ├── manifest.json │ └── src │ │ └── index.js │ ├── template-typescript │ ├── pack_icon.png │ ├── _gitignore │ ├── tsconfig.json │ ├── package.json │ ├── animation_controllers │ │ ├── swing.json │ │ ├── jump.json │ │ ├── land.json │ │ ├── death.json │ │ ├── move.json │ │ ├── sleep.json │ │ ├── fire.json │ │ ├── riding.json │ │ ├── sneak.json │ │ ├── swim.json │ │ ├── inwater.json │ │ └── sprint.json │ ├── manifest.json │ └── src │ │ └── index.ts │ ├── package.json │ └── README.md ├── .github ├── FUNDING.yml ├── workflows │ ├── label.yml │ ├── stale.yml │ └── codeql-analysis.yml ├── labeler.yml └── ISSUE_TEMPLATE │ ├── config.yml │ └── proposal.yml ├── .husky ├── commit-msg └── pre-commit ├── .lintstagedrc.json ├── .vscode └── settings.json ├── .prettierrc.json ├── tsconfig.eslint.json ├── .commitlintrc.json ├── tsup.config.ts ├── jest.config.js ├── SECURITY.md ├── lerna.json ├── .eslintrc ├── LICENSE.md ├── tsconfig.json ├── .gitignore ├── package.json └── README.md /.eslintignore: -------------------------------------------------------------------------------- 1 | docs -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | audit=false 2 | fund=false -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.json linguist-language=JSON-with-Comments -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beapijs/beapi/HEAD/public/logo.png -------------------------------------------------------------------------------- /packages/beapi/src/client/index.ts: -------------------------------------------------------------------------------- 1 | // Centralized export. 2 | export * from './Client' 3 | -------------------------------------------------------------------------------- /packages/beapi/tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.eslint.json" 3 | } 4 | -------------------------------------------------------------------------------- /public/logo_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beapijs/beapi/HEAD/public/logo_text.png -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [nobu-sh] 4 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit $1 -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | npm run build -------------------------------------------------------------------------------- /packages/beapi/src/decorators/index.ts: -------------------------------------------------------------------------------- 1 | // Export all for centralized imports. 2 | export * from './setProto' 3 | -------------------------------------------------------------------------------- /packages/beapi/src/item/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything from item for centralized import. 2 | export * from './Item' 3 | -------------------------------------------------------------------------------- /packages/beapi/src/agent/index.ts: -------------------------------------------------------------------------------- 1 | // Centralized export. 2 | export * from './Agent' 3 | export * from './Directions' 4 | -------------------------------------------------------------------------------- /.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.{mjs,js,ts}": "eslint --fix --ext mjs,js,ts", 3 | "*.{json,yml,yaml}": "prettier --write" 4 | } 5 | -------------------------------------------------------------------------------- /packages/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "composite": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "files.eol": "\n", 4 | "files.associations": { "*.json": "jsonc" } 5 | } 6 | -------------------------------------------------------------------------------- /packages/beapi/src/world/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything from world manager. 2 | export * from './WorldManager' 3 | export * from './Dimension' 4 | -------------------------------------------------------------------------------- /packages/beapi/src/entity/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything for centralized imports. 2 | export * from './Entity' 3 | export * from './EntityManager' 4 | -------------------------------------------------------------------------------- /packages/beapi/src/block/index.ts: -------------------------------------------------------------------------------- 1 | // Centralized export. 2 | export * from './Block' 3 | export * from './BlockType' 4 | export * from './Permutation' 5 | -------------------------------------------------------------------------------- /packages/beapi/src/inventory/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything for centralized imports. 2 | export * from './EntityInventory' 3 | export * from './BlockInventory' 4 | -------------------------------------------------------------------------------- /packages/beapi/src/player/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything from player for centralized imports. 2 | export * from './Player' 3 | export * from './PlayerManager' 4 | -------------------------------------------------------------------------------- /packages/beapi/src/polyfill/index.ts: -------------------------------------------------------------------------------- 1 | // Export other polyfills for centralized imports 2 | export * from './EventEmitter' 3 | 4 | // DO NOT EXPORT TIMERS. 5 | -------------------------------------------------------------------------------- /packages/beapi/src/scoreboard/identity/index.ts: -------------------------------------------------------------------------------- 1 | // Export all identities. 2 | export * from './Player' 3 | export * from './Entity' 4 | export * from './Fake' 5 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Gamemode.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Gamemode status types. 3 | */ 4 | export type Gamemode = 'creative' | 'adventure' | 'survival' | 'unknown' 5 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/pack_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beapijs/beapi/HEAD/packages/create-beapi/template-javascript/pack_icon.png -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/pack_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/beapijs/beapi/HEAD/packages/create-beapi/template-typescript/pack_icon.png -------------------------------------------------------------------------------- /packages/beapi/src/commands/index.ts: -------------------------------------------------------------------------------- 1 | // Centralized export. 2 | export * from './CommandTypes' 3 | export * from './CommandManager' 4 | export * from './CommandExecState' 5 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "quoteProps": "as-needed", 5 | "trailingComma": "all", 6 | "endOfLine": "lf", 7 | "semi": false 8 | } 9 | -------------------------------------------------------------------------------- /packages/beapi/src/forms/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything for one centralized import. 2 | export * from './ModalForm' 3 | export * from './MessageForm' 4 | export * from './ActionForm' 5 | -------------------------------------------------------------------------------- /packages/beapi/src/scoreboard/index.ts: -------------------------------------------------------------------------------- 1 | // Export all from scoreboard manager. 2 | export * from './ScoreboardManager' 3 | export * from './Objective' 4 | export * from './identity' 5 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Util.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Awaitable is a type helper for types that 3 | * can be async but dont need to be. 4 | */ 5 | export type Awaitable = T | PromiseLike 6 | -------------------------------------------------------------------------------- /packages/beapi/src/database/index.ts: -------------------------------------------------------------------------------- 1 | // Expoort everything for centralized imports. 2 | export * from './Document' 3 | export * from './Modal' 4 | export * from './Schema' 5 | export * from './SchemaTypes' 6 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Scoreboards.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Scoreboard objective object representatation. 3 | */ 4 | 5 | /** 6 | * Scoreboard slot area. 7 | */ 8 | export type ScoreboardSlot = 'sidebar' | 'list' | 'belowname' 9 | -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | // Eslint Project Config 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "allowJs": true 6 | }, 7 | "include": ["**/*.ts", "**/*.js", "**/*.test.ts", "**/*.test.js"] 8 | } 9 | -------------------------------------------------------------------------------- /.commitlintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["@commitlint/config-angular"], 3 | "rules": { 4 | "scope-case": [2, "always", "lower-case"], 5 | "type-enum": [2, "always", ["feat", "fix", "docs", "refactor", "test", "chore", "misc"]] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | name: 'Pull Request Labeler' 2 | on: 3 | - pull_request_target 4 | 5 | jobs: 6 | triage: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/labeler@v3 10 | with: 11 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 12 | -------------------------------------------------------------------------------- /packages/beapi/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { tsup as conf } from '../../tsup.config' 2 | import type { Options } from 'tsup' 3 | 4 | export const tsup: Options = { 5 | ...conf, 6 | // We only need esm 7 | format: ['esm'], 8 | // We want ES6 for gametest 9 | target: 'es2020', 10 | } 11 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/object.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Gets all entries on an object. 3 | * @param data Object to use. 4 | * @returns 5 | */ 6 | export function entries = Record>(data: K): [keyof K, K[keyof K]][] { 7 | return Object.keys(data).map((i: keyof K) => [i, data[i]]) 8 | } 9 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | '@beapi/core': 2 | - 'packages/beapi/*' 3 | - 'packages/beapi/**/*' 4 | 5 | '@beapi/scaffolder': 6 | - 'packages/create-beapi/*' 7 | - 'packages/create-beapi/**/*' 8 | 9 | '@beapi/docs': 10 | - 'docs/*' 11 | - 'docs/**/*' 12 | 13 | '@gh': 14 | - '.github/*' 15 | - '.github/**/*' 16 | -------------------------------------------------------------------------------- /packages/beapi/src/decorators/setProto.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Object decorator thats sets predefined class properties 3 | * prototype to the same value. 4 | * @param value Value to set 5 | * @returns 6 | */ 7 | export function setProto(value: T) { 8 | return (target: Record, key: K) => { 9 | target[key] = value 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Formatting.ts: -------------------------------------------------------------------------------- 1 | export type CamelToSnakeCase = S extends `${infer T}${infer U}` 2 | ? `${T extends Capitalize ? '_' : ''}${Lowercase}${CamelToSnakeCase}` 3 | : S 4 | 5 | export type SnakeToCamelCase = S extends `${infer T}_${infer U}` 6 | ? `${T}${Capitalize>}` 7 | : S 8 | -------------------------------------------------------------------------------- /packages/beapi/src/version.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore Get version from package.json 2 | import { version as v } from '../package.json' 3 | 4 | // Export BeAPI core version. 5 | export const version = v 6 | 7 | // Export MCBE version correlating with BeAPI. 8 | export const mcbe = '1.18.30' 9 | 10 | // Export MCBE protcol version correlating with BeAPI. 11 | export const protocol = 503 12 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Timers.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal timer object. 3 | * Contains needed data for doing timer methods. 4 | */ 5 | export interface Timer { 6 | /** 7 | * Function to be called. 8 | */ 9 | cb: CallableFunction 10 | /** 11 | * Tick wait amount. 12 | */ 13 | tick: number 14 | /** 15 | * Original execution tick. 16 | */ 17 | og?: number 18 | } 19 | -------------------------------------------------------------------------------- /packages/beapi/src/agent/Directions.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Agent direction enumable. 3 | */ 4 | export enum AgentDirection { 5 | forward = 'forward', 6 | back = 'back', 7 | up = 'up', 8 | down = 'down', 9 | left = 'left', 10 | right = 'right', 11 | } 12 | 13 | /** 14 | * Agent rotation enumable. 15 | */ 16 | export enum AgentRotation { 17 | left = 'left', 18 | right = 'right', 19 | } 20 | -------------------------------------------------------------------------------- /packages/beapi/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | // ES2020 = Gametest 5 | "module": "ES2020", 6 | "moduleResolution": "node", 7 | "target": "ES2020", 8 | "lib": ["ES2020"], 9 | 10 | // Paths 11 | "sourceRoot": "./", 12 | "rootDir": "./src", 13 | "outDir": "dist" 14 | }, 15 | "include": ["src/**/*.ts"] 16 | } 17 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import type { Options } from 'tsup' 2 | 3 | export const tsup: Options = { 4 | // Compilation 5 | clean: true, 6 | minify: true, 7 | dts: false, 8 | 9 | // Module 10 | target: 'es2020', 11 | format: ['esm', 'cjs'], 12 | skipNodeModulesBundle: true, 13 | 14 | // Decaration Emission 15 | sourcemap: true, 16 | 17 | // Entry 18 | entryPoints: ['src/index.ts'], 19 | } 20 | -------------------------------------------------------------------------------- /packages/beapi/src/types/ServerCommand.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Server command response data. 3 | */ 4 | export interface ServerCommandResponse { 5 | /** 6 | * Message response from server. 7 | */ 8 | statusMessage: string 9 | /** 10 | * Data associated with the response. 11 | */ 12 | data: T | undefined | null 13 | /** 14 | * Response is an error? 15 | */ 16 | err: boolean 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/_gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | scripts/beapi_modules 12 | dist 13 | scripts 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/_gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | scripts/beapi_modules 12 | dist 13 | scripts 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @type {import('@jest/types').Config.InitialOptions} 3 | */ 4 | module.exports = { 5 | testMatch: ['**/+(*.)+(test).+(ts|js)?(x)'], 6 | testEnvironment: 'node', 7 | collectCoverage: true, 8 | coverageProvider: 'v8', 9 | coverageDirectory: 'coverage', 10 | coverageReporters: ['html', 'text', 'clover'], 11 | roots: ['packages/'], 12 | coveragePathIgnorePatterns: ['/node_modules/'], 13 | } 14 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | // Export everything from all files 2 | // For centralized imports. 3 | export * from './uuidv4' 4 | export * from './getCoordinatesBetween' 5 | export * from './between' 6 | export * from './runCommand' 7 | export * from './binary' 8 | export * from './object' 9 | export * from './ids' 10 | export * from './getUniqueId' 11 | export * from './destruct' 12 | export * from './getEnchantments' 13 | export * from './formatting' 14 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beapi-starter", 3 | "version": "1.0.0", 4 | "main": "src/index.js", 5 | "beapiModule": true, 6 | "include": [ 7 | "scripts", 8 | "manifest.json", 9 | "animation_controllers", 10 | "entities", 11 | "pack_icon.png" 12 | ], 13 | "scripts": { 14 | "build": "beapi build", 15 | "bundle": "beapi bundle" 16 | }, 17 | "dependencies": { 18 | "beapi-core": "^2.4.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Reporting and Fixing Security Issues 2 | 3 | Please do not open GitHub issues or pull requests - this makes the problem immediately visible to everyone, including malicious actors. Security issues in this open source project can be safely reported via below: 4 | 5 | - DM Nobu#1122 or PMK744#5874 on Discord. 6 | - Email chat@nobu.sh

7 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Item.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { MinecraftEnchantmentTypes, MinecraftItemTypes } from 'mojang-minecraft' 3 | 4 | /** 5 | * Get only enchant names on MinecraftEnchantmentTypes. 6 | */ 7 | export type EnchantTypes = T extends 'prototype' ? never : T 8 | 9 | /** 10 | * Get only item names on MinecraftItemTypes. 11 | */ 12 | export type ItemTypes = T extends 'prototype' ? never : T 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: ❓ Questions - Discord chat 4 | url: https://discord.gg/DPRYsU4yf4 5 | about: This issue tracker is not for technical support. Please use our Discord chat, and ask the community for help. 6 | - name: ❓ Questions - Stack Overflow 7 | url: https://stackoverflow.com/questions/tagged/BeAPI 8 | about: This issue tracker is not for technical support. Please use Stack Overflow, and ask the community for help. 9 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Database.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Serialized data representation. 3 | */ 4 | export type Serialized = T 5 | /** 6 | * Deserialized data representation. 7 | */ 8 | export type Deserialized = T 9 | 10 | /** 11 | * Raw data object. 12 | */ 13 | export interface RawData { 14 | /** 15 | * Collection name. 16 | */ 17 | name: string 18 | /** 19 | * Document id. 20 | */ 21 | id: string 22 | /** 23 | * Bin dump data. 24 | */ 25 | bin: string 26 | } 27 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Location.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Coordinate location object. 3 | */ 4 | export interface Location { 5 | /** 6 | * X Coordinate. 7 | */ 8 | x: number 9 | /** 10 | * Y Coordinate. 11 | */ 12 | y: number 13 | /** 14 | * Z Coordinate. 15 | */ 16 | z: number 17 | } 18 | 19 | /** 20 | * Rotation object. 21 | */ 22 | export interface Rotation { 23 | /** 24 | * X Coordinate. 25 | */ 26 | x?: number 27 | /** 28 | * Y Coordinate. 29 | */ 30 | y?: number 31 | } 32 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ES6", 4 | "moduleResolution": "node", 5 | "target": "ES6", 6 | "lib": ["ES2016"], 7 | "outDir": "dist", 8 | "allowSyntheticDefaultImports": true, 9 | "noImplicitAny": true, 10 | "preserveConstEnums": true, 11 | "sourceMap": false, 12 | "skipLibCheck": true, 13 | // Set declaratoin to true when creating a module. 14 | "declaration": false 15 | }, 16 | "include": ["src"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beapi-typescript-starter", 3 | "version": "1.0.0", 4 | "main": "dist/index.js", 5 | "beapiModule": true, 6 | "include": [ 7 | "scripts", 8 | "manifest.json", 9 | "animation_controllers", 10 | "entities", 11 | "pack_icon.png" 12 | ], 13 | "scripts": { 14 | "build": "tsc && beapi build", 15 | "bundle": "tsc && beapi bundle" 16 | }, 17 | "dependencies": { 18 | "beapi-core": "^2.4.0", 19 | "typescript": "^4.5.4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "independent", 3 | "npmClient": "npm", 4 | "useWorkspaces": true, 5 | "command": { 6 | "publish": { 7 | "ignoreChanges": ["ignored-file", "**/*.md", "**/__tests__/**"], 8 | "message": "chore(release): publish", 9 | "conventionalCommits": true, 10 | "push": true 11 | }, 12 | "version": { 13 | "allowBranch": ["production", "beta"], 14 | "conventionalCommits": true, 15 | "push": true, 16 | "createRelease": "github" 17 | } 18 | }, 19 | "packages": ["packages/*"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/between.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Checks if `cur` is between `first` and `second`. 3 | * @param first First number. 4 | * @param second Second number. 5 | * @param cur Number to check. 6 | * @returns 7 | */ 8 | export function between(first: number, second: number, cur: number): boolean { 9 | // Get highest number. 10 | const max = Math.max(first, second) 11 | // Get lowest number. 12 | const min = Math.min(first, second) 13 | 14 | // If cur more than or equal to min 15 | // and cur is less than or equal to max 16 | return cur >= min && cur <= max 17 | } 18 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/destruct.ts: -------------------------------------------------------------------------------- 1 | // Sourced from: https://flaviocopes.com/how-to-list-object-methods-javascript/ 2 | 3 | /** 4 | * Lists all methods on an object, helpful for undocumented 5 | * Minecraft objects added. 6 | * @param obj Object to destruct. 7 | * @returns 8 | */ 9 | export const destruct = (obj: object): any[] => { 10 | const properties = new Set() 11 | let currentObj = obj 12 | do { 13 | Object.getOwnPropertyNames(currentObj).map((item) => properties.add(item)) 14 | } while ((currentObj = Object.getPrototypeOf(currentObj) as object)) 15 | return [...properties.keys()] 16 | } 17 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/binary.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts binary string to utf-8 string. 3 | * @param bin Raw binary string. 4 | * @returns 5 | */ 6 | export function binToString(bin: string): string { 7 | return bin 8 | .split(' ') 9 | .map((char) => String.fromCharCode(parseInt(char, 2))) 10 | .join('') 11 | } 12 | 13 | /** 14 | * Converts utf-8 text to raw binary string. 15 | * @param str utf-8 text. 16 | * @returns 17 | */ 18 | export function stringToBin(str: string): string { 19 | return str 20 | .split('') 21 | .map((char) => char.charCodeAt(0).toString(2)) 22 | .join(' ') 23 | } 24 | -------------------------------------------------------------------------------- /packages/beapi/src/types/index.ts: -------------------------------------------------------------------------------- 1 | // Export all files for centralized imports. 2 | export * from './Block' 3 | export * from './Client' 4 | export * from './Dimension' 5 | export * from './ServerCommand' 6 | export * from './Location' 7 | export * from './Gamemode' 8 | export * from './Commands' 9 | export * from './Util' 10 | export * from './_overrides' 11 | export * from './Timers' 12 | export * from './Database' 13 | export * from './Formatting' 14 | export * from './Forms' 15 | export * from './Item' 16 | export * from './Player' 17 | export * from './Entity' 18 | export * from './World' 19 | export * from './Scoreboards' 20 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "marine/prettier/node", 3 | "parserOptions": { 4 | "project": "./tsconfig.eslint.json" 5 | }, 6 | "ignorePatterns": ["**/dist/*"], 7 | "env": { 8 | "jest": true 9 | }, 10 | "rules": { 11 | "indent": ["error", 2, { "SwitchCase": 1 }], 12 | "@typescript-eslint/restrict-template-expressions": 0, 13 | "@typescript-eslint/no-unnecessary-condition": 0, 14 | "@typescript-eslint/prefer-ts-expect-error": 0, 15 | "@typescript-eslint/no-use-before-define": 0, 16 | "@typescript-eslint/no-namespace": 0, 17 | "no-use-before-define": 0, 18 | "no-redeclare": 0 19 | } 20 | } -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/swing.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.swing": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "variable.attack_time > 0.50" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:swing\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "(1.0)" 18 | } 19 | ] 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/swing.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.swing": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "variable.attack_time > 0.50" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:swing\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "(1.0)" 18 | } 19 | ] 20 | } 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/jump.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.jump": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_jumping" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:jump\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_jumping" 18 | } 19 | ], 20 | "on_exit": [""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/jump.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.jump": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_jumping" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:jump\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_jumping" 18 | } 19 | ], 20 | "on_exit": [""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/land.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.land": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_on_ground" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:land\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_on_ground" 18 | } 19 | ], 20 | "on_exit": [""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/land.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.land": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_on_ground" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:land\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_on_ground" 18 | } 19 | ], 20 | "on_exit": [""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/death.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.death": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_alive" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:respawn\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_alive" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:died\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/move.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.move": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_moving" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_move\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_moving" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_move\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/sleep.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sleep": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sleeping" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:sleep\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sleeping" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:wake\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/death.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.death": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_alive" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:respawn\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_alive" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:died\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/move.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.move": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_moving" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_move\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_moving" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_move\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/sleep.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sleep": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sleeping" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:sleep\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sleeping" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:wake\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/beapi/src/scoreboard/identity/Fake.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Client } from '../../' 3 | import type { ScoreboardIdentity as IIdentity } from 'mojang-minecraft' 4 | 5 | export class FakeIdentity { 6 | protected readonly client: Client 7 | protected readonly IIdentity: IIdentity 8 | 9 | public constructor(client: Client, IIdentity: IIdentity) { 10 | this.client = client 11 | this.IIdentity = IIdentity 12 | } 13 | 14 | public getIIdentity(): IIdentity { 15 | return this.IIdentity 16 | } 17 | 18 | public getId(): number { 19 | return this.IIdentity.id 20 | } 21 | 22 | public getDisplay(): string { 23 | return this.IIdentity.displayName 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/fire.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.fire": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_on_fire" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_fire\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_on_fire" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_fire\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/riding.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.riding": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_riding" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_ride\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_riding" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_ride\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/sneak.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sneak": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sneaking" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:sneak\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sneaking" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:unsneak\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/swim.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.swim": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_swimming" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_swim\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_swimming" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_swim\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/fire.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.fire": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_on_fire" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_fire\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_on_fire" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_fire\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/riding.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.riding": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_riding" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_ride\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_riding" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_ride\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/sneak.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sneak": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sneaking" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:sneak\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sneaking" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:unsneak\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/swim.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.swim": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_swimming" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_swim\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_swimming" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_swim\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/inwater.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.inwater": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_in_water" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:in_water\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_in_water" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:exit_water\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/animation_controllers/sprint.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sprint": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sprinting" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_sprint\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sprinting" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_sprint\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/inwater.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.inwater": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_in_water" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:in_water\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_in_water" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:exit_water\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/animation_controllers/sprint.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": "1.10.0", 3 | "animation_controllers": { 4 | "controller.animation.sprint": { 5 | "states": { 6 | "default": { 7 | "transitions": [ 8 | { 9 | "scroll": "query.is_sprinting" 10 | } 11 | ], 12 | "on_exit": ["/tag @s add \"beapi:on_sprint\""] 13 | }, 14 | "scroll": { 15 | "transitions": [ 16 | { 17 | "default": "!query.is_sprinting" 18 | } 19 | ], 20 | "on_exit": ["/tag @s add \"beapi:off_sprint\""] 21 | } 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Dimension.ts: -------------------------------------------------------------------------------- 1 | import type { Color, Vector } from 'mojang-minecraft' 2 | import type { Entity } from '..' 3 | 4 | /** 5 | * Dimension names. 6 | */ 7 | export type DimensionType = 'overworld' | 'nether' | 'the end' 8 | 9 | /** 10 | * Dimension namespaces 11 | */ 12 | export type DimensionNamespace = 'minecraft:overworld' | 'minecraft:nether' | 'minecraft:the_end' 13 | 14 | export interface ParticleOptions { 15 | id: string 16 | type: 'RGB' | 'RGBA' | 'SpeedAndDirection' | 'Vector' 17 | color?: Color 18 | speed?: number 19 | vector?: Vector 20 | } 21 | 22 | export interface ExplosionOptions { 23 | allowUnderwater: boolean 24 | breaksBlocks: boolean 25 | causesFire: boolean 26 | source: Entity 27 | } 28 | -------------------------------------------------------------------------------- /packages/beapi/src/index.ts: -------------------------------------------------------------------------------- 1 | // Initialize the polyfill. 2 | import './poly' 3 | 4 | // BeAPI exports. 5 | export * from './types' 6 | export * from './decorators' 7 | export * from './database' 8 | export * from './agent' 9 | export * from './block' 10 | export * from './client' 11 | export * from './commands' 12 | export * from './entity' 13 | export * from './events' 14 | export * from './forms' 15 | export * from './inventory' 16 | export * from './item' 17 | export * from './player' 18 | export * from './scoreboard' 19 | export * from './polyfill' 20 | export * from './utils' 21 | export * from './world' 22 | export * from './version' 23 | 24 | // Circular Mojang exports. 25 | export * as Minecraft from 'mojang-minecraft' 26 | export * as Gametest from 'mojang-gametest' 27 | -------------------------------------------------------------------------------- /packages/beapi/src/scoreboard/identity/Entity.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Client, Entity } from '../../' 3 | import type { ScoreboardIdentity as IIdentity } from 'mojang-minecraft' 4 | 5 | export class EntityIdentity { 6 | protected readonly client: Client 7 | protected readonly IIdentity: IIdentity 8 | 9 | public constructor(client: Client, IIdentity: IIdentity) { 10 | this.client = client 11 | this.IIdentity = IIdentity 12 | } 13 | 14 | public getIIdentity(): IIdentity { 15 | return this.IIdentity 16 | } 17 | 18 | public getId(): number { 19 | return this.IIdentity.id 20 | } 21 | 22 | public getDisplay(): string { 23 | return this.IIdentity.displayName 24 | } 25 | 26 | public getEntity(): Entity | undefined { 27 | const Entity = this.client.entities.getByIEntity(this.IIdentity.getEntity()) 28 | 29 | return Entity 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/beapi/src/scoreboard/identity/Player.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Client, Player } from '../../' 3 | import type { ScoreboardIdentity as IIdentity, Player as IPlayer } from 'mojang-minecraft' 4 | 5 | export class PlayerIdentity { 6 | protected readonly client: Client 7 | protected readonly IIdentity: IIdentity 8 | 9 | public constructor(client: Client, IIdentity: IIdentity) { 10 | this.client = client 11 | this.IIdentity = IIdentity 12 | } 13 | 14 | public getIIdentity(): IIdentity { 15 | return this.IIdentity 16 | } 17 | 18 | public getId(): number { 19 | return this.IIdentity.id 20 | } 21 | 22 | public getDisplay(): string { 23 | return this.IIdentity.displayName 24 | } 25 | 26 | public getPlayer(): Player | undefined { 27 | const player = this.client.players.getByIPlayer(this.IIdentity.getEntity() as IPlayer) 28 | 29 | return player 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/uuidv4.ts: -------------------------------------------------------------------------------- 1 | // Source From: https://dirask.com/posts/JavaScript-UUID-function-in-Vanilla-JS-1X9kgD 2 | 3 | /** 4 | * Generates a random UUID4. This method does not utilize Date, 5 | * it utilizes random bytes therefore duplicates are possible. 6 | * But very small chance. 7 | * @returns {string} 8 | */ 9 | export function genUuid(): string { 10 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { 11 | const r = (Math.random() * 16) | 0 12 | const v = c === 'x' ? r : (r & 0x3) | 0x8 13 | 14 | return v.toString(16) 15 | }) 16 | } 17 | 18 | /** 19 | * Verifies the uuid given is a valid uuid format. 20 | * @param {string} uuid UUID to verify. 21 | * @returns {boolean} 22 | */ 23 | export function verifyUuid(uuid: string): boolean { 24 | return /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/gi.test(uuid) 25 | } 26 | // [string] 27 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | # This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time. 2 | # 3 | # You can adjust the behavior by modifying this file. 4 | # For more information, see: 5 | # https://github.com/actions/stale 6 | name: Mark stale issues and pull requests 7 | 8 | on: 9 | schedule: 10 | - cron: '41 23 * * *' 11 | 12 | jobs: 13 | stale: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | issues: write 17 | pull-requests: write 18 | 19 | steps: 20 | - uses: actions/stale@v3 21 | with: 22 | repo-token: ${{ secrets.GITHUB_TOKEN }} 23 | stale-issue-message: 'Issue activity has been deciphered as stale. Marking issue with `stale` label' 24 | stale-pr-message: 'Pull request activity has been deciphered as stale. Marking pull request with `stale` label' 25 | stale-issue-label: 'stale' 26 | stale-pr-label: 'stale' 27 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/getUniqueId.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { genUuid, runCommand } from '..' 3 | 4 | // Type imports. 5 | import type { Entity } from '..' 6 | 7 | interface ParseResult { 8 | statusCode: string 9 | statusMessage: string 10 | } 11 | 12 | /** 13 | * Attempts to get the minecraft assigned unique id for 14 | * the given entity. 15 | * @param entity Entity to try get id for. 16 | * @returns 17 | */ 18 | export function getUniqueId(entity: Entity): number { 19 | const objective = genUuid().substring(0, 16) 20 | runCommand(`scoreboard objectives add "${objective}" dummy`) 21 | const { err, statusMessage } = entity.executeCommand(`scoreboard players test @s "${objective}" * *`) 22 | runCommand(`scoreboard objectives remove "${objective}"`) 23 | if (!err) return 0 24 | 25 | const raw: ParseResult = JSON.parse(statusMessage) as ParseResult 26 | const id = Number(raw.statusMessage.split(' ')[1]) 27 | 28 | return id 29 | } 30 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/formatting.ts: -------------------------------------------------------------------------------- 1 | import type { CamelToSnakeCase, SnakeToCamelCase } from '..' 2 | 3 | /** 4 | * Convert snake case to camel case. 5 | * @param input snake input. 6 | * @returns {string} camel output. 7 | */ 8 | export function snakeCaseToCamelCase(input: CamelToSnakeCase): SnakeToCamelCase { 9 | return input 10 | .split('_') 11 | .reduce( 12 | (res, word, i) => 13 | i === 0 ? word.toLowerCase() : `${res}${word.charAt(0).toUpperCase()}${word.substr(1).toLowerCase()}`, 14 | '', 15 | ) as SnakeToCamelCase 16 | } 17 | 18 | /** 19 | * Convert camel case to snake case. 20 | * @param input Camel case input 21 | * @returns 22 | */ 23 | export function camelCaseToSnakeCase(input: SnakeToCamelCase): CamelToSnakeCase { 24 | return input 25 | .replace(/([A-Z])/g, ' $1') 26 | .split(' ') 27 | .join('_') 28 | .toLowerCase() as CamelToSnakeCase 29 | } 30 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Forms.ts: -------------------------------------------------------------------------------- 1 | // TODO: Add generics to modal responses for typings 2 | // TODO: Add type turnary so isCanceled extends false selection is not optional 3 | 4 | /** 5 | * Modal response from form. 6 | */ 7 | export interface ModalFormResponse { 8 | /** 9 | * Values in order. 10 | */ 11 | readonly formValues?: any[] 12 | /** 13 | * Form was canceled? 14 | */ 15 | readonly isCanceled: boolean 16 | } 17 | 18 | /** 19 | * Message response from form. 20 | */ 21 | export interface MessageFormResponse { 22 | /** 23 | * Selected value. 24 | */ 25 | readonly selection?: number 26 | /** 27 | * Form was canceled? 28 | */ 29 | readonly isCanceled: boolean 30 | } 31 | 32 | /** 33 | * Action response from form. 34 | */ 35 | export interface ActionFormResponse { 36 | /** 37 | * Selected value. 38 | */ 39 | readonly selection?: number 40 | /** 41 | * Form was canceled? 42 | */ 43 | readonly isCanceled: boolean 44 | } 45 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/getCoordinatesBetween.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Coordinates as array `[x, y, z]`. 3 | */ 4 | export type Coord = [number, number, number] 5 | 6 | /** 7 | * Attempts to get all coordinates between two points. 8 | * @param a First coordinate set. 9 | * @param b Second coordinate set. 10 | * @returns 11 | */ 12 | export function getCoordinatesBetween(a: Coord, b: Coord): Coord[] { 13 | // Intialize empty coord array. 14 | const coords: Coord[] = [] 15 | 16 | // For X of a; while less than X of b; X++; 17 | for (let x = Math.min(a[0], b[0]); x <= Math.max(a[0], b[0]); x++) 18 | // For Y of a; while less than Y of b; Y++; 19 | for (let y = Math.min(a[1], b[1]); y <= Math.max(a[1], b[1]); y++) 20 | // For Z of a; while less than Z of b; Z++ 21 | // Push [X, Y, Z] results to coords array 22 | for (let z = Math.min(a[2], b[2]); z <= Math.max(a[2], b[2]); z++) coords.push([x, y, z]) 23 | 24 | // Return results. 25 | return coords 26 | } 27 | -------------------------------------------------------------------------------- /packages/beapi/src/types/Block.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | BlockPistonComponent, 3 | BlockInventoryComponent, 4 | BlockRecordPlayerComponent, 5 | BlockLavaContainerComponent, 6 | BlockSnowContainerComponent, 7 | BlockWaterContainerComponent, 8 | BlockPotionContainerComponent, 9 | MinecraftBlockTypes, 10 | } from 'mojang-minecraft' 11 | 12 | export interface BlockComponents { 13 | piston: BlockPistonComponent 14 | inventory: BlockInventoryComponent 15 | record_player: BlockRecordPlayerComponent 16 | lava_container: BlockLavaContainerComponent 17 | snow_container: BlockSnowContainerComponent 18 | water_container: BlockWaterContainerComponent 19 | potion_container: BlockPotionContainerComponent 20 | } 21 | 22 | /** 23 | * Get only block names on MinecraftBlockTypes. 24 | */ 25 | export type BlockTypes = T extends 'prototype' 26 | ? never 27 | : T extends 'get' 28 | ? never 29 | : T extends 'getAllBlockTypes' 30 | ? never 31 | : T 32 | -------------------------------------------------------------------------------- /packages/create-beapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-beapi", 3 | "version": "2.2.1", 4 | "license": "MIT", 5 | "author": "MCBE - Utilites", 6 | "main": "index.js", 7 | "engines": { 8 | "node": ">=12.0.0" 9 | }, 10 | "files": [ 11 | "index.js", 12 | "template-*" 13 | ], 14 | "bin": { 15 | "create-beapi": "index.js", 16 | "cba": "index.js" 17 | }, 18 | "scripts": { 19 | "i": "npm install", 20 | "build": "echo \"create-beapi does not need compilation\" && exit 0" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/MCBE-Utilities/BeAPI.git" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/MCBE-Utilities/BeAPI/issues" 28 | }, 29 | "homepage": "https://github.com/MCBE-Utilities/BeAPI/packages/create-beapi#readme", 30 | "dependencies": { 31 | "kolorist": "^1.5.0", 32 | "minimist": "^1.2.5", 33 | "prompts": "^2.4.2" 34 | }, 35 | "publishConfig": { 36 | "access": "public" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": 2, 3 | "header": { 4 | "description": "Advanced API Wrapper for GameTests.", 5 | "name": "§l§9BeAPI Starter§r", 6 | "uuid": "|UUID1|", 7 | "version": [0, 0, 1], 8 | "min_engine_version": [1, 14, 0] 9 | }, 10 | "modules": [ 11 | { 12 | "type": "data", 13 | "uuid": "|UUID2|", 14 | "version": [1, 0, 0] 15 | }, 16 | { 17 | "description": "Advanced API Wrapper for GameTests.", 18 | "language": "javascript", 19 | "type": "script", 20 | "uuid": "|UUID3|", 21 | "version": [0, 0, 1], 22 | "entry": "scripts/index.js" 23 | } 24 | ], 25 | "dependencies": [ 26 | { 27 | "uuid": "b26a4d4c-afdf-4690-88f8-931846312678", 28 | "version": [0, 1, 0] 29 | }, 30 | { 31 | "uuid": "6f4b6893-1bb6-42fd-b458-7fa3d0c89616", 32 | "version": [0, 1, 0] 33 | }, 34 | { 35 | "uuid": "2bd50a27-aB5f-4f40-a596-3641627c635e", 36 | "version": [0, 1, 0] 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "format_version": 2, 3 | "header": { 4 | "description": "Advanced API Wrapper for GameTests.", 5 | "name": "§l§9BeAPI Typescript Starter§r", 6 | "uuid": "|UUID1|", 7 | "version": [0, 0, 1], 8 | "min_engine_version": [1, 14, 0] 9 | }, 10 | "modules": [ 11 | { 12 | "type": "data", 13 | "uuid": "|UUID2|", 14 | "version": [1, 0, 0] 15 | }, 16 | { 17 | "description": "Advanced API Wrapper for GameTests.", 18 | "language": "javascript", 19 | "type": "script", 20 | "uuid": "|UUID3|", 21 | "version": [0, 0, 1], 22 | "entry": "scripts/index.js" 23 | } 24 | ], 25 | "dependencies": [ 26 | { 27 | "uuid": "b26a4d4c-afdf-4690-88f8-931846312678", 28 | "version": [0, 1, 0] 29 | }, 30 | { 31 | "uuid": "6f4b6893-1bb6-42fd-b458-7fa3d0c89616", 32 | "version": [0, 1, 0] 33 | }, 34 | { 35 | "uuid": "2bd50a27-aB5f-4f40-a596-3641627c635e", 36 | "version": [0, 1, 0] 37 | } 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 MCBE Utilities 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/create-beapi/template-javascript/src/index.js: -------------------------------------------------------------------------------- 1 | import { Client, CommandTypes } from 'beapi-core' 2 | 3 | const client = new Client() 4 | 5 | client.commands.register('ping', 'Ping BeAPI script.', (sender) => { 6 | sender.sendMessage('§ePong!§r') 7 | }) 8 | 9 | client.commands.register( 10 | 'aliastest', 11 | 'Test command aliases,', 12 | { 13 | aliases: ['at'], 14 | }, 15 | (sender) => { 16 | sender.sendMessage('Hello World!') 17 | }, 18 | ) 19 | 20 | client.commands.register( 21 | 'argtest', 22 | 'Test argument system.', 23 | { 24 | string: CommandTypes.String, 25 | optionalNumber: [CommandTypes.Number, true], 26 | optionalBoolean: [CommandTypes.Boolean, true], 27 | }, 28 | (sender, args) => { 29 | sender.sendMessage(`${args.string} ${args.optionalNumber} ${args.optionalBoolean}`) 30 | }, 31 | ) 32 | 33 | client.commands.register( 34 | 'aliasargtest', 35 | 'Test argument system with aliases.', 36 | { 37 | aliases: ['aat'], 38 | }, 39 | { 40 | string: CommandTypes.String, 41 | optionalNumber: [CommandTypes.Number, true], 42 | optionalBoolean: [CommandTypes.Boolean, true], 43 | }, 44 | (sender, args) => { 45 | sender.sendMessage(`${args.string} ${args.optionalNumber} ${args.optionalBoolean}`) 46 | }, 47 | ) 48 | -------------------------------------------------------------------------------- /packages/create-beapi/template-typescript/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Client, CommandTypes } from 'beapi-core' 2 | 3 | const client = new Client() 4 | 5 | client.commands.register('ping', 'Ping BeAPI script.', (sender) => { 6 | sender.sendMessage('§ePong!§r') 7 | }) 8 | 9 | client.commands.register( 10 | 'aliastest', 11 | 'Test command aliases,', 12 | { 13 | aliases: ['at'], 14 | }, 15 | (sender) => { 16 | sender.sendMessage('Hello World!') 17 | }, 18 | ) 19 | 20 | client.commands.register( 21 | 'argtest', 22 | 'Test argument system.', 23 | { 24 | string: CommandTypes.String, 25 | optionalNumber: [CommandTypes.Number, true], 26 | optionalBoolean: [CommandTypes.Boolean, true], 27 | }, 28 | (sender, args) => { 29 | sender.sendMessage(`${args.string} ${args.optionalNumber} ${args.optionalBoolean}`) 30 | }, 31 | ) 32 | 33 | client.commands.register( 34 | 'aliasargtest', 35 | 'Test argument system with aliases.', 36 | { 37 | aliases: ['aat'], 38 | }, 39 | { 40 | string: CommandTypes.String, 41 | optionalNumber: [CommandTypes.Number, true], 42 | optionalBoolean: [CommandTypes.Boolean, true], 43 | }, 44 | (sender, args) => { 45 | sender.sendMessage(`${args.string} ${args.optionalNumber} ${args.optionalBoolean}`) 46 | }, 47 | ) 48 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Formatting 4 | "strict": true, 5 | "allowUnreachableCode": false, 6 | "allowUnusedLabels": false, 7 | "exactOptionalPropertyTypes": true, 8 | "noFallthroughCasesInSwitch": true, 9 | "noImplicitOverride": true, 10 | "noImplicitReturns": false, 11 | "noUnusedLocals": true, 12 | "noUnusedParameters": true, 13 | "useUnknownInCatchVariables": true, 14 | 15 | // Module 16 | "module": "CommonJS", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | 20 | // Decaration Emission 21 | "declaration": true, 22 | "importHelpers": true, 23 | "importsNotUsedAsValues": "error", 24 | "inlineSources": true, 25 | "newLine": "lf", 26 | "noEmitHelpers": true, 27 | "preserveConstEnums": true, 28 | "removeComments": false, 29 | "sourceMap": true, 30 | "esModuleInterop": true, 31 | "forceConsistentCasingInFileNames": true, 32 | 33 | // ModuleType & Formatting 34 | "emitDecoratorMetadata": true, 35 | "experimentalDecorators": true, 36 | "lib": ["ESNext"], 37 | "target": "ES2020", 38 | "useDefineForClassFields": true, 39 | 40 | // Libs have broken typescript :shrug: 41 | "skipLibCheck": true 42 | }, 43 | "exclude": ["**/*.test.ts"] 44 | } 45 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/runCommand.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { world } from 'mojang-minecraft' 3 | 4 | // Type imports. 5 | import type { ServerCommandResponse } from '..' 6 | import type { DimensionType } from '../types' 7 | 8 | /** 9 | * Standalone method for running a command. Worlds the same as `Client#runCommand`. 10 | * @param {string} cmd Command to execute. 11 | * @param {Dimension} dimension Dimension to use. 12 | * @param {boolean} debug Pipe errors to content log? 13 | * @returns {ServerCommandResponse} 14 | */ 15 | export function runCommand( 16 | cmd: string, 17 | dimension: DimensionType = 'overworld', 18 | debug = false, 19 | ): ServerCommandResponse { 20 | try { 21 | // Try execute command. 22 | const command = world.getDimension(dimension).runCommand(cmd) 23 | 24 | // If able to return ServerCommandResponse 25 | // Then successful execute 26 | return { 27 | statusMessage: command.statusMessage, 28 | data: command, 29 | err: false, 30 | } 31 | } catch (error) { 32 | // If debug error then do so. 33 | if (debug) console.debug(`[runCommand] [error] (standalone): ${String(error)}`) 34 | 35 | // Return error data. 36 | return { 37 | statusMessage: String(error), 38 | data: null, 39 | err: true, 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/beapi/src/types/World.ts: -------------------------------------------------------------------------------- 1 | import type * as Minecraft from 'mojang-minecraft' 2 | import type { Location } from './Location' 3 | /** 4 | * Weather status types. 5 | */ 6 | export type Weather = 'clear' | 'rain' | 'thunder' 7 | 8 | /** 9 | * Difficulty status types. 10 | */ 11 | export type Difficulty = 'peaceful' | 'easy' | 'normal' | 'hard' 12 | 13 | export type PropertyType = 'string' | 'number' | 'boolean' 14 | 15 | export type PropertyValue = string | number | boolean 16 | export interface DynamicPropertiesDefinition { 17 | defineNumber(id: string): void 18 | defineString(id: string, maxLength: number): void 19 | defineBoolean(id: string): void 20 | } 21 | 22 | export interface PropertyRegistry { 23 | registerEntityTypeDynamicProperties( 24 | property: DynamicPropertiesDefinition, 25 | entityType: any /* Minecraft.EntityType */, 26 | ): void 27 | registerWorldDynamicProperties(property: DynamicPropertiesDefinition): void 28 | } 29 | 30 | export interface World extends Minecraft.World { 31 | setDynamicProperty(id: string, value: string | boolean | number): boolean 32 | removeDynamicProperty(id: string): boolean 33 | getDynamicProperty(id: string): string | boolean | number 34 | } 35 | 36 | export interface SoundOptions { 37 | location?: Location 38 | pitch?: number 39 | volume?: number 40 | } 41 | 42 | export interface MusicOptions { 43 | fade?: number 44 | loop?: boolean 45 | volume?: number 46 | } 47 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/getEnchantments.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { ItemEnchantsComponent, ItemStack, MinecraftEnchantmentTypes, Enchantment } from 'mojang-minecraft' 3 | 4 | /** 5 | * Attempts to get all enchantments on an item. 6 | * @param item Item to get enchantments from. 7 | * @returns 8 | */ 9 | export function getEnchantments(item: ItemStack): Enchantment[] { 10 | // Intitialize enchaments return array. 11 | const enchantments: Enchantment[] = [] 12 | 13 | // If not an item or item does not have enchantments nbt component return empty array. 14 | if (!item || !item.hasComponent('minecraft:enchantments')) return enchantments 15 | 16 | // Get the enchantment nbt component and typecast it as ItemEnchantsComponent. 17 | const component = item.getComponent('minecraft:enchantments') as ItemEnchantsComponent 18 | 19 | // For every key on MinecraftEnchantmentTypes execute some code. 20 | for (const enchant of Object.keys(MinecraftEnchantmentTypes) as (keyof MinecraftEnchantmentTypes)[]) { 21 | // If not item enchantments has enchant key in current iteration continue to next iteration. 22 | if (!component.enchantments.hasEnchantment(MinecraftEnchantmentTypes[enchant])) continue 23 | // Otherwise get level of current enchant on item provided. 24 | const value = component.enchantments.getEnchantment(MinecraftEnchantmentTypes[enchant]) 25 | // Push data to final enchantment array 26 | enchantments.push(value) 27 | } 28 | 29 | // Return enchantments 30 | return enchantments 31 | } 32 | -------------------------------------------------------------------------------- /packages/beapi/src/block/BlockType.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Client } from '..' 3 | import type { BlockType as IBlockType, BlockPermutation } from 'mojang-minecraft' 4 | 5 | /** 6 | * BeAPI wrapped Minecraft BlockType for BeAPIs Block counterpart. 7 | */ 8 | export class BlockType { 9 | /** 10 | * Protected client reference. 11 | */ 12 | protected readonly _client: Client 13 | /** 14 | * Protected block type to wrap. 15 | */ 16 | protected readonly _IBlockType: IBlockType 17 | 18 | /** 19 | * BeAPI wrapped Minecraft BlockType for BeAPIs Block counterpart. 20 | * @param client Client reference. 21 | * @param IBlockType Block type to wrap. 22 | */ 23 | public constructor(client: Client, IBlockType: IBlockType) { 24 | this._client = client 25 | this._IBlockType = IBlockType 26 | } 27 | 28 | /** 29 | * Gets the Minecraft IBlockType being wrapped. 30 | * @returns 31 | */ 32 | public getIBlockType(): IBlockType { 33 | return this._IBlockType 34 | } 35 | 36 | /** 37 | * Gets the block types identifier. 38 | * @returns 39 | */ 40 | public getId(): string { 41 | return this._IBlockType.id 42 | } 43 | 44 | /** 45 | * Can the block have water in it? 46 | * @returns 47 | */ 48 | public canBeWaterLogged(): boolean { 49 | return this._IBlockType.canBeWaterlogged 50 | } 51 | 52 | /** 53 | * Creates a new permutation for the block. 54 | * @returns 55 | */ 56 | public createPermutation(): BlockPermutation { 57 | return this._IBlockType.createDefaultBlockPermutation() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /packages/beapi/src/utils/ids.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple safe id's. 3 | * Provide the class a unique number not being used 4 | * and it will generate ids based off the current epoch 5 | * with a generation increment that resets every 10000. 6 | * 7 | * This is a very simple system proved to work with database entries. 8 | */ 9 | export class SafeIds { 10 | /** 11 | * Protected epoch store. 12 | */ 13 | protected epoch: number 14 | /** 15 | * Protected unique id store. 16 | */ 17 | protected unique: number 18 | /** 19 | * Protected current generation store. 20 | */ 21 | protected inc = 0 22 | 23 | /** 24 | * Simple safe id's. 25 | * Provide the class a unique number not being used 26 | * and it will generate ids based off the current epoch 27 | * with a generation increment that resets every 10000. 28 | * 29 | * This is a very simple system proved to work with database entries. 30 | * @param unique Ensure this is unique for 99.9% safe ids. 31 | * @param epoch Optional amount to subtract from current time. 32 | */ 33 | public constructor(unique: number, epoch = 0) { 34 | this.epoch = epoch 35 | this.unique = unique 36 | } 37 | 38 | /** 39 | * Get the next increment. 40 | */ 41 | protected get increment() { 42 | if (this.inc === 10000) return (this.inc = 0) 43 | return this.inc++ 44 | } 45 | 46 | /** 47 | * Generate a new (99.9% hopefully unique) id. 48 | * @returns 49 | */ 50 | public generate(): string { 51 | const now = Date.now() 52 | 53 | return `${Math.abs(now - this.epoch)}_${this.increment}_${this.unique}` 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /packages/beapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beapi-core", 3 | "version": "2.4.0", 4 | "scripts": { 5 | "i": "npm install", 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "tsup && tsc --emitDeclarationOnly", 8 | "prepack": "npm run build" 9 | }, 10 | "main": "./dist/index.mjs", 11 | "module": "./dist/index.mjs", 12 | "typings": "./dist/index.d.ts", 13 | "exports": { 14 | "import": "./dist/index.mjs", 15 | "require": "./dist/index.mjs" 16 | }, 17 | "bin": { 18 | "beapi": "./bin/beapi.js" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/MCBE-Utilities/BeAPI" 23 | }, 24 | "homepage": "https://github.com/MCBE-Utilities/BeAPI/packages/beapi-core#readme", 25 | "bugs": { 26 | "url": "https://github.com/MCBE-Utilities/BeAPI/issues" 27 | }, 28 | "license": "MIT", 29 | "directories": { 30 | "lib": "src", 31 | "test": "__tests__", 32 | "bin": "bin", 33 | "doc": "docs" 34 | }, 35 | "files": [ 36 | "dist", 37 | "bin", 38 | "public" 39 | ], 40 | "keywords": [ 41 | "minecraft", 42 | "bedrock", 43 | "mcbe", 44 | "gametest" 45 | ], 46 | "publishConfig": { 47 | "access": "public" 48 | }, 49 | "dependencies": { 50 | "@types/mojang-gametest": "^0.1.4", 51 | "@types/mojang-minecraft": "^0.1.5", 52 | "@types/uuid-1345": "^0.99.22", 53 | "@types/yargs": "^17.0.2", 54 | "@typescript-eslint/eslint-plugin": "^4.31.0", 55 | "babel-eslint": "^10.1.0", 56 | "boxen": "^5.0.1", 57 | "chalk": "^4.1.2", 58 | "copy-dir": "^1.3.0", 59 | "eslint": "^7.32.0", 60 | "semver": "^7.3.5", 61 | "ts-node": "^10.2.1", 62 | "typescript": "^4.4.2", 63 | "update-notifier": "^5.1.0", 64 | "uuid-1345": "^1.0.2", 65 | "yargs": "^17.1.1", 66 | "zip-a-folder": "^1.1.0" 67 | }, 68 | "engines": { 69 | "node": ">=16" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /packages/beapi/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 |

11 | 12 | ## About 13 | BeAPI (an abbreviation for "Bedrock edition API") is a tool that aims 14 | for a faster and more reliable development experience when working 15 | with Minecraft Bedrock edition gametests. We achieve these goals by putting together some of the most brilliant minds in the Minecraft Bedrock developer community to scheme up alternative ways to utilize the gametest framework so it's easier for you! 16 | 17 | ## Support 18 | Gametest currently only supports [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript); because of this we are only really left with two primary language support options; [Typescript](https://www.typescriptlang.org/) and [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) project scaffolds. 19 | 20 | ## How It Works 21 | BeAPI uses NPM's cli create app feature to provide you with a setup to scaffold your projects. This allows for a clean working environment separated from the core codebase. We also provide a cli for building and bundling your packs. 22 | 23 | ## Where Do I Start? 24 | Check out our [docs](https://mcbe-utilities.github.io/BeAPI)! 25 | 26 | ## Issues / Feature Request 27 | Please submit an issue following the proper templates 28 | ## Contributing 29 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 30 | 31 | Please make be sure to **TEST** all functionality before requesting 32 | 33 | ## License 34 | [MIT](https://choosealicense.com/licenses/mit/) 35 | -------------------------------------------------------------------------------- /packages/create-beapi/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 |

11 | 12 | ## About 13 | BeAPI (an abbreviation for "Bedrock edition API") is a tool that aims 14 | for a faster and more reliable development experience when working 15 | with Minecraft Bedrock edition gametests. We achieve these goals by putting together some of the most brilliant minds in the Minecraft Bedrock developer community to scheme up alternative ways to utilize the gametest framework so it's easier for you! 16 | 17 | ## Support 18 | Gametest currently only supports [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript); because of this we are only really left with two primary language support options; [Typescript](https://www.typescriptlang.org/) and [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) project scaffolds. 19 | 20 | ## How It Works 21 | BeAPI uses NPM's cli create app feature to provide you with a setup to scaffold your projects. This allows for a clean working environment separated from the core codebase. We also provide a cli for building and bundling your packs. 22 | 23 | ## Where Do I Start? 24 | Check out our [docs](https://mcbe-utilities.github.io/BeAPI)! 25 | 26 | ## Issues / Feature Request 27 | Please submit an issue following the proper templates 28 | ## Contributing 29 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 30 | 31 | Please make be sure to **TEST** all functionality before requesting 32 | 33 | ## License 34 | [MIT](https://choosealicense.com/licenses/mit/) 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | scripts 85 | 86 | # Gatsby files 87 | .cache/ 88 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 89 | # https://nextjs.org/blog/next-9-1#public-directory-support 90 | # public 91 | 92 | # vuepress build output 93 | .vuepress/dist 94 | 95 | # Serverless directories 96 | .serverless/ 97 | 98 | # FuseBox cache 99 | .fusebox/ 100 | 101 | # DynamoDB Local files 102 | .dynamodb/ 103 | 104 | # TernJS port file 105 | .tern-port -------------------------------------------------------------------------------- /packages/beapi/src/types/Player.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { 3 | EntityLavaMovementComponent, 4 | EntityBreathableComponent, 5 | EntityHealthComponent, 6 | EntityInventoryComponent, 7 | EntityMovementComponent, 8 | EntityRideableComponent, 9 | EntityUnderwaterMovementComponent, 10 | } from 'mojang-minecraft' 11 | 12 | /** 13 | * Currently used player NBT components. 14 | */ 15 | // TODO: fill all available ones 16 | // TODO: Add types for ones left as any 17 | export interface PlayerComponents { 18 | /** 19 | * Defines the base movement speed in lava of this entity. 20 | */ 21 | 'minecraft:lava_movement': EntityLavaMovementComponent 22 | /** 23 | * Defines what blocks this entity can breathe in and gives them the ability to suffocate. 24 | */ 25 | 'minecraft:breathable': EntityBreathableComponent 26 | /** 27 | * Defines the health properties of an entity. 28 | */ 29 | 'minecraft:health': EntityHealthComponent 30 | /** 31 | * Defines this entity's inventory properties. 32 | */ 33 | 'minecraft:inventory': EntityInventoryComponent 34 | /** 35 | * Defines entities transparency when invisible. 36 | */ 37 | 'minecraft:is_hidden_when_invisible': any 38 | /** 39 | * Defines the general movement speed of this entity. 40 | */ 41 | 'minecraft:movement': EntityMovementComponent 42 | /** 43 | * Defines capability that an entity can be ridden by another entity. 44 | */ 45 | 'minecraft:rideable': EntityRideableComponent 46 | /** 47 | * Defines the general movement speed underwater of this entity. 48 | */ 49 | 'minecraft:underwater_movement': EntityUnderwaterMovementComponent 50 | /** 51 | * Defines capability of climbing. 52 | */ 53 | 'minecraft:can_climb': any 54 | } 55 | 56 | /** 57 | * Fog types. 58 | */ 59 | export type FogType = 'pop' | 'push' | 'remove' 60 | 61 | /** 62 | * Camera shake types. 63 | */ 64 | export type CameraShakeType = 'positional' | 'rotational' | 'clear' 65 | 66 | /** 67 | * Options for title displays. 68 | */ 69 | export interface TitleOptions { 70 | fadeInSeconds?: number 71 | fadeOutSeconds?: number 72 | staySeconds?: number 73 | subtitle?: string 74 | } 75 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beapi-monorepo", 3 | "version": "1.0.0", 4 | "description": "MCBE gametest wrapper monorepo", 5 | "private": true, 6 | "scripts": { 7 | "i": "npm install && npm run i --workspaces", 8 | "build": "npm run build --workspaces", 9 | "clean": "rimraf packages/*/dist packages/*/*.tsbuildinfo", 10 | "commit": "commit", 11 | "format": "prettier --write **/*.{ts,js,json,yml,yaml}", 12 | "lint": "eslint packages --ext mjs,js,ts", 13 | "lint:fix": "eslint packages --ext mjs,js,ts --fix", 14 | "prepare": "husky install", 15 | "pretest": "npm run build", 16 | "lerna": "env-cmd lerna", 17 | "canary-release": "env-cmd lerna publish --conventional-prerelease --pre-dist-tag beta --preid beta", 18 | "graduate-release": "env-cmd lerna publish --conventional-graduate", 19 | "test": "jest --pass-with-no-tests", 20 | "test:ci": "jest --no-stack-trace --verbose --pass-with-no-tests" 21 | }, 22 | "license": "MIT", 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/MCBE-Utilities/BeAPI.git" 26 | }, 27 | "bugs": { 28 | "url": "https://github.com/MCBE-Utilities/BeAPI/issues" 29 | }, 30 | "homepage": "https://github.com/MCBE-Utilities/BeAPI#readme", 31 | "keywords": [ 32 | "minecraft", 33 | "bedrock", 34 | "mcbe", 35 | "gametest" 36 | ], 37 | "workspaces": [ 38 | "packages/*" 39 | ], 40 | "devDependencies": { 41 | "@commitlint/cli": "^16.0.1", 42 | "@commitlint/config-angular": "^16.0.0", 43 | "@commitlint/prompt-cli": "^16.0.0", 44 | "@types/jest": "^27.0.3", 45 | "@typescript-eslint/eslint-plugin": "^5.8.1", 46 | "@typescript-eslint/parser": "^5.8.1", 47 | "env-cmd": "^10.1.0", 48 | "eslint": "^8.5.0", 49 | "eslint-config-marine": "^9.1.0", 50 | "eslint-config-prettier": "^8.3.0", 51 | "eslint-plugin-import": "^2.25.3", 52 | "eslint-plugin-prettier": "^4.0.0", 53 | "husky": "^7.0.4", 54 | "jest": "^27.4.5", 55 | "lerna": "^4.0.0", 56 | "lint-staged": "^12.1.4", 57 | "prettier": "^2.5.1", 58 | "tsup": "^5.11.9", 59 | "typescript": "^4.5.4" 60 | }, 61 | "dependencies": { 62 | "@types/mojang-minecraft": "^0.1.6" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 | 8 | 9 | 10 |

11 | 12 | ## About 13 | BeAPI (an abbreviation for "Bedrock edition API") is a tool that aims 14 | for a faster and more reliable development experience when working 15 | with Minecraft Bedrock edition gametests. We achieve these goals by putting together some of the most brilliant minds in the Minecraft Bedrock developer community to scheme up alternative ways to utilize the gametest framework so it's easier for you! We have also added the ability to easily add 3rd party plugins/modules via [npm](https://www.npmjs.com/). 16 | 17 | ## Support 18 | Gametest currently only supports [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript); because of this we are only really left with two primary language support options; [Typescript](https://www.typescriptlang.org/) and [Javascript](https://developer.mozilla.org/en-US/docs/Web/JavaScript) project scaffolds. 19 | 20 | ## How It Works 21 | BeAPI uses NPM's cli create app feature to provide you with a setup to scaffold your projects. This allows for a clean working environment separated from the core codebase. We also provide a cli for building and bundling your packs. 22 | 23 | ## Where Do I Start? 24 | Check out our [docs](https://mcbe-utilities.github.io/BeAPI)! 25 | 26 | ## Issues / Feature Request 27 | Please submit an issue following the guidelines on the proper template. 28 | 29 | ## Contributing 30 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 31 | 32 | Please make be sure to **TEST** all functionality before requesting. 33 | 34 | See [CONTRIBUTING.md](./CONTRIBUTING.md)! 35 | 36 | ## License 37 | [MIT](https://choosealicense.com/licenses/mit/) 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/proposal.yml: -------------------------------------------------------------------------------- 1 | name: 💥 Proposal 2 | description: Propose a non-trivial change to BeAPI 3 | labels: [proposal, 'status: needs triage'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | Common reasons for proposals include: 9 | 10 | - Altering the infrastructure (e.g. swapping tsup out with other bundlers); 11 | - Bumping a critical dependency's major version; 12 | - A significant improvement to a CLI command; 13 | - Significant refactor; 14 | - ... 15 | 16 | This is not for feature requests. If this involves new APIs or new behaviors, consider requesting a feature instead. 17 | 18 | We give you maximum freedom to write an elaborated proposal illustrating why you think the change is beneficial for us, and what steps we should take to turn this into reality. 19 | 20 | You should not use this to ditch the feature request or bug template; such action could make us identify the issue wrongly and close it without doing anything. 21 | 22 | - type: checkboxes 23 | attributes: 24 | label: Have you read the Issues Contributing Guidelines? 25 | options: 26 | - label: I have read the [Issues Contributing Guidelines](https://github.com/MCBE-Utilities/BeAPI/blob/beta/CONTRIBUTING.md#issues). 27 | required: true 28 | 29 | - type: textarea 30 | attributes: 31 | label: Motivation 32 | description: A clear and concise description of what the proposal is. 33 | validations: 34 | required: true 35 | 36 | - type: checkboxes 37 | attributes: 38 | label: Self-service 39 | description: | 40 | If you feel like you could contribute to this issue, please check the box below. This would tell us and other people looking for contributions that someone's working on it. 41 | If you do check this box, please send a pull request within 7 days after a maintainer's approval so we can still delegate this to someone else. 42 | 43 | Proposals usually involve significant code changes, so please reach consensus with the maintainers before rushing to implement it. This ensures that you don't waste your time and we don't waste ours reading the large diffs. 44 | options: 45 | - label: I'd be willing to do some initial work on this proposal myself. 46 | -------------------------------------------------------------------------------- /packages/beapi/src/poly.ts: -------------------------------------------------------------------------------- 1 | // Imports 2 | import { Client } from './client' 3 | import { Timers } from './polyfill/Timers' 4 | 5 | // Create original console warn reference. 6 | const log = console.warn 7 | 8 | // Override Default Console Methods 9 | // @ts-expect-error Console expects more methods. 10 | // Gametest only adds warn and error by default we add a few more. 11 | // TODO: Add formatting support for Objects, Array, Etc. 12 | globalThis.console = { 13 | /** 14 | * Sends a BeAPI log to the content log in-game. 15 | * @param {any} message Primary message. 16 | * @param {any} optionalParams Optional extra fragments. 17 | */ 18 | log(message: any, ...optionalParams: any[]) { 19 | log(`§9[BeAPI]§r §b[LOG]:§r ${message} ${optionalParams.join(' ')}`) 20 | }, 21 | /** 22 | * Sends a BeAPI error log to the content log in-game. 23 | * @param {any} message Primary message. 24 | * @param {any} optionalParams Optional extra fragments. 25 | */ 26 | error(message: any, ...optionalParams: any[]) { 27 | log(`§9[BeAPI]§r §c[ERROR]:§r ${message} ${optionalParams.join(' ')}`) 28 | }, 29 | /** 30 | * Sends a BeAPI warn log to the content log in-game. 31 | * @param {any} message Primary message. 32 | * @param {any} optionalParams Optional extra fragments. 33 | */ 34 | warn(message: any, ...optionalParams: any[]) { 35 | log(`§9[BeAPI]§r §g[WARN]:§r ${message} ${optionalParams.join(' ')}`) 36 | }, 37 | /** 38 | * Sends a BeAPI info log to the content log in-game. 39 | * @param {any} message Primary message. 40 | * @param {any} optionalParams Optional extra fragments. 41 | */ 42 | info(message: any, ...optionalParams: any[]) { 43 | log(`§9[BeAPI]§r §a[INFO]:§r ${message} ${optionalParams.join(' ')}`) 44 | }, 45 | /** 46 | * Sends a BeAPI debug log to the content log in-game. 47 | * @param {any} message Primary message. 48 | * @param {any} optionalParams Optional extra fragments. 49 | */ 50 | debug(message: any, ...optionalParams: any[]) { 51 | log(`§9[BeAPI]§r §d[DEBUG]:§r ${message} ${optionalParams.join(' ')}`) 52 | }, 53 | } 54 | 55 | // Initialize Minimal Client With Only Tick Event. 56 | export const client = new Client({ 57 | enableEvents: ['Tick'], 58 | }) 59 | 60 | // Create New Timers Util 61 | const timers = new Timers() 62 | 63 | // Start Timerss 64 | timers.start(client) 65 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Swing.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI swing event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Swing extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Swing') 24 | public readonly name = 'Swing' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI swing event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'swing') return 74 | // Emit to client. 75 | this._client.emit(this.name, data.player) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ItemDropped.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import { setProto, Client, Entity, AbstractEvent } from '..' 3 | 4 | /** 5 | * BeAPI item dropped event. Contains the logic 6 | * for translating Minecraft event data to BeAPI 7 | * wrapped data. 8 | */ 9 | export class ItemDropped extends AbstractEvent { 10 | // Predefined in AbstractEvent. 11 | protected readonly _logic = this.__logic.bind(this) 12 | // Predefined in AbstractEvent. 13 | protected readonly _client: Client 14 | // Predefined in AbstractEvent. 15 | protected _registered = false 16 | 17 | // Predefined in AbstractEvent. 18 | @setProto('ItemDropped') 19 | public readonly name = 'ItemDropped' 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('custom') 23 | public readonly iName = 'custom' 24 | 25 | // Predefined in AbstractEvent. 26 | public readonly alwaysCancel = false 27 | 28 | /** 29 | * BeAPI item dropped event. Contains the logic 30 | * for translating Minecraft event data to BeAPI 31 | * wrapped data. 32 | * @param client Client referece. 33 | */ 34 | public constructor(client: Client) { 35 | super() 36 | this._client = client 37 | } 38 | 39 | // Predefined in AbstractEvent. 40 | public on(): void { 41 | // If not already registered. 42 | if (!this._registered) { 43 | // Subscribe to Client event with needed logic 44 | // And use bound _logic for the callback. 45 | this._client.addListener('EntityCreated', this._logic) 46 | // Set registered to true so this cannot be called 47 | // Again before off being called. 48 | this._registered = true 49 | } 50 | } 51 | 52 | // Predefined in AbstractEvent. 53 | public off(): void { 54 | // If currently registered. 55 | if (this._registered) { 56 | // Remove Client event listener used 57 | // With bound _logic callback. 58 | this._client.removeListener('EntityCreated', this._logic) 59 | // Set registered to false so this cannot be called 60 | // Again before on being called. 61 | this._registered = false 62 | } 63 | } 64 | 65 | // Predefined in AbstractEvent. 66 | protected __logic(data: Entity): void { 67 | // If not minecraft item ignore. 68 | if (data.getId() !== 'minecraft:item') return 69 | 70 | // Item instance 71 | const item = data.getItemStack()! 72 | 73 | // Emit throw event. 74 | this._client.emit(this.name, { 75 | entity: data, 76 | item, 77 | }) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Landed.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI landed event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Landed extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Landed') 24 | public readonly name = 'Landed' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI landed event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | protected __logic(data: PlayerTagEvent): void { 71 | // If not correct tag return. 72 | if (data.tag !== 'land') return 73 | // Set grounded to true. 74 | data.player.isGrounded(true) 75 | // Emit the landed event. 76 | this._client.emit(this.name, data.player) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedSneaking.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started sneaking event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedSneaking extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedSneaking') 24 | public readonly name = 'StartedSneaking' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started sneaking event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'sneak') return 74 | // Emit through client. 75 | this._client.emit(this.name, data.player) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedSneaking.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped sneaking event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedSneaking extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedSneaking') 24 | public readonly name = 'StoppedSneaking' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped sneaking event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'unsneak') return 74 | // Emit event on client 75 | this._client.emit(this.name, data.player) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Jump.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI jump event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Jump extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Jump') 24 | public readonly name = 'Jump' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI jump event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'jump') return 74 | // Set isGrounded to false. 75 | data.player.isGrounded(false) 76 | 77 | // Emit jump event client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Respawn.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI respawn event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Respawn extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Respawn') 24 | public readonly name = 'Respawn' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI respawn event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'respawn') return 74 | // Set is alive to true. 75 | data.player.isAlive(true) 76 | // Emit to client. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedBurning.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped burning event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedBurning extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedBurning') 24 | public readonly name = 'StoppedBurning' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped burning event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | protected __logic(data: PlayerTagEvent): void { 71 | // If not correct tag return. 72 | if (data.tag !== 'off_fire') return 73 | // Set burning to galse. 74 | data.player.isBurning(false) 75 | 76 | // Emit event on client. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Death.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { setProto } from '../' 3 | import AbstractEvent from './AbstractEvent' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI death event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Death extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Death') 24 | public readonly name = 'Death' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI death event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If the beapi tag is not "died" return 73 | if (data.tag !== 'died') return 74 | // Set player isAlive to false cause they ded. 75 | data.player.isAlive(false) 76 | // Emit the deathed event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedMoving.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started moving event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedMoving extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedMoving') 24 | public readonly name = 'StartedMoving' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started moving event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return 73 | if (data.tag !== 'on_move') return 74 | // Set isMoving to true. 75 | data.player.isMoving(true) 76 | // Emit moving event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedRiding.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started riding event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedRiding extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedRiding') 24 | public readonly name = 'StartedRiding' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started riding event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'on_ride') return 74 | // Set isRiding to true. 75 | data.player.isRiding(true) 76 | // Emit riding event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedMoving.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped moving event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedMoving extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedMoving') 24 | public readonly name = 'StoppedMoving' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped moving event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'off_move') return 74 | // Set is moving to false. 75 | data.player.isMoving(false) 76 | // Emit event on client. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedBurning.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started burning event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedBurning extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedBurning') 24 | public readonly name = 'StartedBurning' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started burning event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'on_fire') return 74 | // Set is burning to true. 75 | data.player.isBurning(true) 76 | // Emit a client event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedSleeping.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started sleeping event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedSleeping extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedSleeping') 24 | public readonly name = 'StartedSleeping' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started sleeping event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'sleep') return 74 | // Set isSleeping to true. 75 | data.player.isSleeping(true) 76 | // Emit to client. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedRiding.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped riding event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedRiding extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedRiding') 24 | public readonly name = 'StoppedRiding' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped riding event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'off_ride') return 74 | // Set is riding to false. 75 | data.player.isRiding(false) 76 | 77 | // Emit event on client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EnteredWater.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client } from '../client' 7 | import type { PlayerTagEvent } from '..' 8 | 9 | /** 10 | * BeAPI entered water event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class EnteredWater extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('EnteredWater') 24 | public readonly name = 'EnteredWater' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI entered water event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If the beapi tag is not "in_water" return 73 | if (data.tag !== 'in_water') return 74 | // Set player isInWater to true. 75 | data.player.isInWater(true) 76 | // Emit in wator event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedSprinting.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started sprinting event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedSprinting extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedSprinting') 24 | public readonly name = 'StartedSprinting' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started sprinting event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'on_sprint') return 74 | // Set sprinting to true. 75 | data.player.isSprinting(true) 76 | // Emit client event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StartedSwimming.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI started swimming event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StartedSwimming extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StartedSwimming') 24 | public readonly name = 'StartedSwimming' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI started swimming event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'on_swim') return 74 | // Set swimming to true. 75 | data.player.isSwimming(true) 76 | 77 | // Emit event to client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedSleeping.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped sleeping event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedSleeping extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedSleeping') 24 | public readonly name = 'StoppedSleeping' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped sleeping event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'wake') return 74 | // Set is sleeping to false. 75 | data.player.isSleeping(false) 76 | 77 | // Emit event on client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedSwimming.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped swimming event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedSwimming extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedSwimming') 24 | public readonly name = 'StoppedSwimming' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped swimming event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'off_swim') return 74 | // Set swimming to false. 75 | data.player.isSwimming(false) 76 | 77 | // Emit event to client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/OnJoin.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { PlayerJoinEvent, world } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI join event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class OnJoin extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('OnJoin') 24 | public readonly name = 'OnJoin' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('playerJoin') 28 | public readonly iName = 'playerJoin' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI join event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: PlayerJoinEvent): void { 72 | // Create a player from the IPlayer object. 73 | const player = this._client.players.create(arg.player) 74 | // Add the player to player manager. 75 | this._client.players.add(player) 76 | // Emit the new player. 77 | this._client.emit(this.name, player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ExitedWater.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI exited water event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class ExitedWater extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('ExitedWater') 24 | public readonly name = 'ExitedWater' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI exited water event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If the beapi tag is not "exit_water" return. 73 | if (data.tag !== 'exit_water') return 74 | // Set isInWater to false cause they are not. 75 | data.player.isInWater(false) 76 | // Emit the waterless event. 77 | this._client.emit(this.name, data.player) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /packages/beapi/src/events/StoppedSprinting.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { PlayerTagEvent } from '..' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI stopped sprinting event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class StoppedSprinting extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('StoppedSprinting') 24 | public readonly name = 'StoppedSprinting' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('custom') 28 | public readonly iName = 'custom' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI stopped sprinting event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Client event with needed logic 49 | // And use bound _logic for the callback. 50 | this._client.addListener('PlayerTag', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerTag', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerTagEvent): void { 72 | // If not correct tag return. 73 | if (data.tag !== 'off_sprint') return 74 | // Set is sprinting to false. 75 | data.player.isSprinting(false) 76 | 77 | // Emit event to client. 78 | this._client.emit(this.name, data.player) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/beapi/src/events/AbstractEvent.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Client } from '../client/Client' 3 | 4 | /** 5 | * Abstract Event Class. This must extended when 6 | * creating a new event so Client methods know 7 | * how to handle the event and what properties 8 | * are available. 9 | */ 10 | export default abstract class { 11 | /** 12 | * Protected client circular reference. 13 | */ 14 | protected abstract readonly _client: Client 15 | /** 16 | * Protected logic *(bound to `this`)*. 17 | * See any of the events for example. 18 | */ 19 | protected abstract readonly _logic: CallableFunction 20 | 21 | /** 22 | * Used to ensure if `on` or `off` is accidently called twice 23 | * it wont add or remove two listeners. 24 | */ 25 | protected abstract _registered: boolean 26 | 27 | /** 28 | * Events name that will be used when emitting 29 | * events off the client. 30 | * 31 | * :::warning 32 | * 33 | * Don't forget to use the `@setProto` decorator 34 | * so name is readable on prototype. *(See any of the 35 | * premade events for example.)* 36 | * 37 | * ::: 38 | */ 39 | public abstract readonly name: string 40 | 41 | /** 42 | * Events name assigned by Minecraft. 43 | * If this is not a Minecraft event leave this 44 | * field as `custom` 45 | * 46 | * :::warning 47 | * 48 | * Don't forget to use the `@setProto` decorator 49 | * so name is readable on prototype. *(See any of the 50 | * premade events for example.)* 51 | * 52 | * ::: 53 | */ 54 | public abstract readonly iName: string 55 | 56 | /** 57 | * Unused by most events as it was never implemented. 58 | * was supposed to always cancel events. 59 | */ 60 | public abstract readonly alwaysCancel: boolean 61 | 62 | /** 63 | * Called by the event manager when read to enable the event 64 | * listeners. *(See any of the premade events for example.)* 65 | */ 66 | public abstract on(): void 67 | /** 68 | * Called by the event manager when event is disabled to remove 69 | * any listeners. *(See any of the premade events for example.)* 70 | */ 71 | public abstract off(): void 72 | 73 | /** 74 | * Actual logic before being bound to `this` for handling 75 | * the listener in `on` method. 76 | * 77 | * :::warning 78 | * 79 | * This method should not be used in the listener directly on, `on`. 80 | * It should be bound to `this` first then assigned to `_logic`. 81 | * *(See any of the premade events for example.)* 82 | * 83 | * ::: 84 | * @param args 85 | */ 86 | protected abstract __logic(...args: any[]): void 87 | } 88 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: 'CodeQL' 13 | 14 | on: 15 | push: 16 | branches: [beta, production] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [beta] 20 | schedule: 21 | - cron: '21 17 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ['javascript'] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EntityKilled.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client, EntityHurtEvent } from '..' 7 | 8 | /** 9 | * BeAPI entity hurt event. Contains the logic 10 | * for translating Minecraft event data to BeAPI 11 | * wrapped data. 12 | */ 13 | export class EntityKilled extends AbstractEvent { 14 | // Predefined in AbstractEvent. 15 | protected readonly _logic = this.__logic.bind(this) 16 | // Predefined in AbstractEvent. 17 | protected readonly _client: Client 18 | // Predefined in AbstractEvent. 19 | protected _registered = false 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('EntityKilled') 23 | public readonly name = 'EntityKilled' 24 | 25 | // Predefined in AbstractEvent. 26 | @setProto('EntityKilled') 27 | public readonly iName = 'custom' 28 | 29 | // Predefined in AbstractEvent. 30 | public readonly alwaysCancel = false 31 | 32 | /** 33 | * BeAPI entity hurt event. Contains the logic 34 | * for translating Minecraft event data to BeAPI 35 | * wrapped data. 36 | * @param client Client referece. 37 | */ 38 | public constructor(client: Client) { 39 | super() 40 | this._client = client 41 | } 42 | 43 | // Predefined in AbstractEvent. 44 | public on(): void { 45 | // If not already registered. 46 | if (!this._registered) { 47 | // Subscribe to Minecraft world event with IName 48 | // And use bound _logic for the callback. 49 | // @ts-ignore TEMP: util Minecraft typings are updated. 50 | this._client.addListener('EntityHurt', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | this._client.removeListener('EntityHurt', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: EntityHurtEvent): void { 72 | const health = data.target.getHealth() 73 | if (!health) return 74 | if (health.current > 0) return 75 | 76 | this._client.emit(this.name, { 77 | attacker: data.attacker, 78 | target: data.target, 79 | damage: data.damage, 80 | cause: data.cause, 81 | }) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/beapi/src/events/PlayerKilled.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client, PlayerHurtEvent } from '..' 7 | 8 | /** 9 | * BeAPI entity hurt event. Contains the logic 10 | * for translating Minecraft event data to BeAPI 11 | * wrapped data. 12 | */ 13 | export class PlayerKilled extends AbstractEvent { 14 | // Predefined in AbstractEvent. 15 | protected readonly _logic = this.__logic.bind(this) 16 | // Predefined in AbstractEvent. 17 | protected readonly _client: Client 18 | // Predefined in AbstractEvent. 19 | protected _registered = false 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('PlayerKilled') 23 | public readonly name = 'PlayerKilled' 24 | 25 | // Predefined in AbstractEvent. 26 | @setProto('PlayerKilled') 27 | public readonly iName = 'custom' 28 | 29 | // Predefined in AbstractEvent. 30 | public readonly alwaysCancel = false 31 | 32 | /** 33 | * BeAPI entity hurt event. Contains the logic 34 | * for translating Minecraft event data to BeAPI 35 | * wrapped data. 36 | * @param client Client referece. 37 | */ 38 | public constructor(client: Client) { 39 | super() 40 | this._client = client 41 | } 42 | 43 | // Predefined in AbstractEvent. 44 | public on(): void { 45 | // If not already registered. 46 | if (!this._registered) { 47 | // Subscribe to Minecraft world event with IName 48 | // And use bound _logic for the callback. 49 | // @ts-ignore TEMP: util Minecraft typings are updated. 50 | this._client.addListener('PlayerHurt', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | this._client.removeListener('PlayerHurt', this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(data: PlayerHurtEvent): void { 72 | const health = data.target.getHealth() 73 | if (!health) return 74 | if (health.current > 0) return 75 | 76 | this._client.emit(this.name, { 77 | attacker: data.attacker, 78 | target: data.target, 79 | damage: data.damage, 80 | cause: data.cause, 81 | }) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/beapi/src/events/OnLeave.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { PlayerLeaveEvent, world } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI leave event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class OnLeave extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('OnLeave') 24 | public readonly name = 'OnLeave' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('playerLeave') 28 | public readonly iName = 'playerLeave' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI leave event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: PlayerLeaveEvent): void { 72 | // Attempt to get player. 73 | const player = this._client.players.getByName(arg.playerName) 74 | 75 | // If no player return. 76 | if (!player) return 77 | 78 | // Emit left player data. 79 | this._client.emit(this.name, player) 80 | 81 | // Remove player from player manager. 82 | this._client.players.remove(player) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Explosion.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { BeforeExplosionEvent, world } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI explosion event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Explosion extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Explosion') 24 | public readonly name = 'Explosion' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('beforeExplosion') 28 | public readonly iName = 'beforeExplosion' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI explosion event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | protected __logic(arg: BeforeExplosionEvent): void { 71 | // Attempt to get the source entity. 72 | const entity = this._client.entities.getByIEntity(arg.source) 73 | 74 | // Emit the boom boom event. 75 | this._client.emit(this.name, { 76 | source: entity, 77 | dimension: this._client.world.getDimension(arg.dimension), 78 | impactedBlocks: arg.impactedBlocks, 79 | cancel() { 80 | arg.cancel = true 81 | }, 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Piston.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { Block } from '../block' 5 | import { BeforePistonActivateEvent, world } from 'mojang-minecraft' 6 | 7 | // Type imports. 8 | import type { Client } from '../client' 9 | 10 | /** 11 | * BeAPI piston event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class Piston extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('Piston') 25 | public readonly name = 'Piston' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('beforePistonActivate') 29 | public readonly iName = 'beforePistonActivate' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI piston event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(arg: BeforePistonActivateEvent): void { 73 | // Emit wrapped client event. 74 | this._client.emit(this.name, { 75 | block: new Block(this._client, arg.block), 76 | dimension: this._client.world.getDimension(arg.dimension), 77 | piston: arg.piston, 78 | extending: arg.isExpanding, 79 | cancel() { 80 | arg.cancel = true 81 | }, 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/database/DatabaseUtil.ts: -------------------------------------------------------------------------------- 1 | import { runCommand, stringToBin } from '../utils' 2 | import type { RawData } from '../types' 3 | 4 | /** 5 | * Dedicated namespace for random database utility methods. 6 | * Namespaces were chosen because they are easy to add on to and look 7 | * better. 8 | */ 9 | export namespace DatabaseUtil { 10 | /** 11 | * Retrieves all serialized data objects as rawdata. 12 | * @param name Modal name. 13 | * @returns 14 | */ 15 | export function retrieveSerializedData(name: string): RawData[] { 16 | const { statusMessage, err } = runCommand('scoreboard players list') 17 | if (err) return [] 18 | return (statusMessage.match(/<{\?name=\w+&id=\w+&bin=[01 ]+}>/gi) ?? []) 19 | .map((i) => DatabaseUtil.fromRaw(i)) 20 | .filter((i) => i.name === name) 21 | } 22 | /** 23 | * Retrieves all objective names. 24 | * @returns 25 | */ 26 | export function retrieveObjectiveNames(): string[] { 27 | const { err, statusMessage } = runCommand('scoreboard objectives list') 28 | if (err) return [] 29 | return statusMessage.match(/- (\w*):/gi)?.map((i) => i.replace(/- |:/g, '')) ?? [] 30 | } 31 | /** 32 | * Checks if an objective exists. 33 | * @param name Objective name 34 | * @returns 35 | */ 36 | export function tableExists(name: string): boolean { 37 | return DatabaseUtil.retrieveObjectiveNames().includes(name) 38 | } 39 | 40 | /** 41 | * Converts raw data into weird xml/url style encoded string we do. 42 | * @param name Modal name. 43 | * @param id Document id. 44 | * @param data Serialized data string. 45 | * @returns 46 | */ 47 | export function toRaw(name: string, id: string, data: string): string { 48 | return `<{?name=${name}&id=${id}&bin=${stringToBin(data)}}>` 49 | } 50 | 51 | /** 52 | * Converts weird raw xml/url thing into usable raw data. 53 | * @param raw Raw xml/url thing. 54 | * @returns 55 | */ 56 | export function fromRaw(raw: string): RawData { 57 | if (!/<{\?name=\w+&id=\w+&bin=[01 ]+}>/gi.test(raw)) { 58 | throw new Error(`Not a valid collection! ${raw}`) 59 | } 60 | const mapped = new Map( 61 | raw 62 | .replace(/<{\?|}>/g, '') 63 | .split('&') 64 | .map((i) => i.split('=')) as [string, string][], 65 | ) 66 | const id = mapped.get('id')! 67 | const name = mapped.get('name')! 68 | const bin = mapped.get('bin')!.trim() 69 | return { 70 | id, 71 | name, 72 | bin, 73 | } 74 | } 75 | 76 | /** 77 | * Checks if given name is considered valid by beapi standards. 78 | * @param name 79 | * @returns 80 | */ 81 | export function validName(name: string): boolean { 82 | return !/\W/.test(name) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/events/Tick.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import { TickEvent, world } from 'mojang-minecraft' 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI tick event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class Tick extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('Tick') 24 | public readonly name = 'Tick' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('tick') 28 | public readonly iName = 'tick' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | // Current tick of the server. 34 | protected currentTick = 0 35 | 36 | /** 37 | * BeAPI tick event. Contains the logic 38 | * for translating Minecraft event data to BeAPI 39 | * wrapped data. 40 | * @param client Client referece. 41 | */ 42 | public constructor(client: Client) { 43 | super() 44 | this._client = client 45 | } 46 | 47 | // Predefined in AbstractEvent. 48 | public on(): void { 49 | // If not already registered. 50 | if (!this._registered) { 51 | // Subscribe to Minecraft world event with IName 52 | // And use bound _logic for the callback. 53 | world.events[this.iName].subscribe(this._logic) 54 | // Set registered to true so this cannot be called 55 | // Again before off being called. 56 | this._registered = true 57 | } 58 | } 59 | 60 | // Predefined in AbstractEvent. 61 | public off(): void { 62 | // If currently registered. 63 | if (this._registered) { 64 | // Remove Minecraft event listener on IName 65 | // With bound _logic callback. 66 | world.events[this.iName].unsubscribe(this._logic) 67 | // Set registered to false so this cannot be called 68 | // Again before on being called. 69 | this._registered = false 70 | } 71 | } 72 | 73 | // Predefined in AbstractEvent. 74 | protected __logic(arg: TickEvent): void { 75 | // Set the current tick. 76 | this.currentTick = arg.currentTick 77 | // Emit the event through client. 78 | this._client.emit(this.name, { 79 | currentTick: arg.currentTick, 80 | deltaTime: arg.deltaTime, 81 | }) 82 | } 83 | 84 | /** 85 | * Get the current tick of the world 86 | */ 87 | public getCurrentTick(): number { 88 | return this.currentTick 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ItemUse.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { BeforeItemUseEvent, world, Player as IPlayer } from 'mojang-minecraft' 5 | import { Item } from '../item' 6 | 7 | // Type imports. 8 | import type { Client } from '../client' 9 | 10 | /** 11 | * BeAPI item use event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class ItemUse extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('ItemUse') 25 | public readonly name = 'ItemUse' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('beforeItemUse') 29 | public readonly iName = 'beforeItemUse' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI item use event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(arg: BeforeItemUseEvent): void { 73 | // Emit use item event stuffs. 74 | this._client.emit(this.name, { 75 | source: 76 | arg.source instanceof IPlayer 77 | ? this._client.players.getByIPlayer(arg.source) 78 | : this._client.entities.getByIEntity(arg.source), 79 | item: new Item(this._client, arg.item) ?? undefined, 80 | cancel() { 81 | arg.cancel = true 82 | }, 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EntityCreated.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { world, Player as IPlayer, EntityCreateEvent } from 'mojang-minecraft' 4 | import { setProto } from '../' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI entity created event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class EntityCreated extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('EntityCreated') 24 | public readonly name = 'EntityCreated' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('entityCreate') 28 | public readonly iName = 'entityCreate' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI entity created event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: EntityCreateEvent): void { 72 | // If entity is instance of a player we dont want. 73 | if (arg.entity instanceof IPlayer) return 74 | 75 | // Create a new entity using entity manager. 76 | const entity = this._client.entities.create(arg.entity) 77 | // Add the newly created entity to entity manager. 78 | this._client.entities.add(entity) 79 | 80 | // Emit event with new entity. 81 | this._client.emit(this.name, entity) 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EffectAdded.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { EffectAddEvent, world, Player as IPlayer } from 'mojang-minecraft' 4 | import { setProto } from '../' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI effect added event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class EffectAdded extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('EffectAdded') 24 | public readonly name = 'EffectAdded' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('effectAdd') 28 | public readonly iName = 'effectAdd' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI effect added event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: EffectAddEvent): void { 72 | // Emit dee effect event yuh. 73 | this._client.emit(this.name, { 74 | // Target can be entity or player and it has a change 75 | // of being undefined cause Minecraft. 76 | target: 77 | arg.entity instanceof IPlayer 78 | ? this._client.players.getByIPlayer(arg.entity) 79 | : this._client.entities.getByIEntity(arg.entity), 80 | effect: arg.effect, 81 | state: arg.effectState, 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/events/WeatherUpdated.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { WeatherChangeEvent, world } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | import type { DimensionType, DimensionNamespace } from '../types' 9 | 10 | /** 11 | * BeAPI weather updated event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class WeatherUpdated extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('WeatherUpdated') 25 | public readonly name = 'WeatherUpdated' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('weatherChange') 29 | public readonly iName = 'weatherChange' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI weather updated event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(arg: WeatherChangeEvent): void { 73 | // Get the dimension it occured in. 74 | const dimension = this._client.world.getDimension( 75 | `minecraft:${(arg.dimension as DimensionType).replace(/ /g, '_')}` as DimensionNamespace, 76 | ) 77 | // Emit event through client. 78 | this._client.emit(this.name, { 79 | lightning: arg.lightning, 80 | raining: arg.raining, 81 | dimension, 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /packages/beapi/src/events/OnChat.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { BeforeChatEvent, world } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI chat event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class OnChat extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('OnChat') 24 | public readonly name = 'OnChat' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('beforeChat') 28 | public readonly iName = 'beforeChat' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI chat event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | protected __logic(arg: BeforeChatEvent): void { 71 | // Attempt to get the sender of the message. 72 | const sender = arg.sender.name 73 | ? this._client.players.getByName(arg.sender.name) 74 | : this._client.players.getByNameTag(arg.sender.nameTag) 75 | 76 | // If no sender return. 77 | if (!sender) return 78 | 79 | // If the sender is muted cancel message from reaching chat. 80 | if (sender.isMuted()) arg.cancel = true 81 | 82 | // Emit event. 83 | this._client.emit(this.name, { 84 | sender, 85 | message: arg.message, 86 | cancel() { 87 | arg.cancel = true 88 | }, 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ChestOpened.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { setProto } from '..' 3 | import AbstractEvent from './AbstractEvent' 4 | 5 | // Type imports. 6 | import type { ItemInteractEvent } from '..' 7 | import type { Client } from '../client' 8 | import { Player } from '../player' 9 | 10 | /** 11 | * BeAPI chest opened event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class ChestOpened extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('ChestOpened') 25 | public readonly name = 'ChestOpened' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('custom') 29 | public readonly iName = 'custom' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI chest opened event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Client event with needed logic 50 | // And use bound _logic for the callback. 51 | this._client.addListener('ItemInteract', this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Client event listener used 63 | // With bound _logic callback. 64 | this._client.removeListener('ItemInteract', this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(data: ItemInteractEvent): void { 73 | // If event data does not contain a block inventory 74 | // or the source is not an instance of player return 75 | if (!data.block.getInventory() || !(data.source instanceof Player)) return 76 | 77 | // Chest block type. 78 | const type = data.block.getId().split(':')[1] 79 | 80 | // Emit this event on client using name defined above. 81 | this._client.emit(this.name, { 82 | block: data.block, 83 | player: data.source, 84 | type, 85 | cancel: () => { 86 | data.cancel() 87 | }, 88 | }) 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ItemEventTrigger.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { world, Player as IPlayer, BeforeItemDefinitionTriggeredEvent } from 'mojang-minecraft' 5 | import { Item } from '../item' 6 | 7 | // Type imports. 8 | import type { Client } from '../client' 9 | 10 | /** 11 | * BeAPI item event trigger event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class ItemEventTrigger extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('ItemEventTrigger') 25 | public readonly name = 'ItemEventTrigger' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('beforeItemDefinitionEvent') 29 | public readonly iName = 'beforeItemDefinitionEvent' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI item event trigger event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(arg: BeforeItemDefinitionTriggeredEvent): void { 73 | // Emit client event with wrapped stuffs. 74 | this._client.emit(this.name, { 75 | source: 76 | arg.source instanceof IPlayer 77 | ? this._client.players.getByIPlayer(arg.source) 78 | : this._client.entities.getByIEntity(arg.source), 79 | event: arg.eventName, 80 | item: new Item(this._client, arg.item), 81 | cancel: () => { 82 | arg.cancel = true 83 | }, 84 | }) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /packages/beapi/src/database/Document.ts: -------------------------------------------------------------------------------- 1 | // Type imports. 2 | import type { Modal } from './Modal' 3 | 4 | /** 5 | * BeAPI database document. Document is the main interaction point 6 | * for interacting with a specfic piece of stored data. 7 | * 8 | * Think of this as a file inside a folder. The folder or rather `Modal` 9 | * holds a lot of these which all contain the same keys but most likely 10 | * different values. 11 | */ 12 | // @ts-expect-error: We Augment Data In 13 | export class Document> implements T { 14 | /** 15 | * Protected reference to model. 16 | */ 17 | protected readonly __model__: Modal 18 | /** 19 | * Protected reference to the docs id. 20 | */ 21 | protected readonly __id__: string 22 | /** 23 | * Protected reference to the documents knownData. 24 | */ 25 | protected __knownData__: T 26 | 27 | /** 28 | * BeAPI database document. Document is the main interaction point 29 | * for interacting with a specfic piece of stored data. 30 | * 31 | * Think of this as a file inside a folder. The folder or rather `Modal` 32 | * holds a lot of these which all contain the same keys but most likely 33 | * different values. 34 | * @param model Documents modal handler. 35 | * @param _id Identifier of the document. 36 | * @param data Data document holds. 37 | */ 38 | public constructor(model: Modal, _id: string, data: T) { 39 | this.__id__ = _id 40 | this.__model__ = model 41 | this.__knownData__ = data 42 | Object.assign(this, data) 43 | } 44 | 45 | /** 46 | * Retrieves an immutable copy of the data 47 | * Minecraft internally remembers since the 48 | * last save. 49 | * @returns 50 | */ 51 | public retrieveKnownInternalData(): T { 52 | return Object.freeze(this.__knownData__) 53 | } 54 | 55 | /** 56 | * Returns the current document as an object containing the schema properties. 57 | * @returns 58 | */ 59 | public asObject(): T { 60 | // @ts-expect-error: We Augment Data In 61 | return Object.keys(this.__model__.schema.definition) 62 | .map((key: keyof T) => ({ [key]: (this as T)[key] })) 63 | .reduce( 64 | (obj, item) => ({ 65 | ...obj, 66 | ...item, 67 | }), 68 | {}, 69 | ) 70 | } 71 | 72 | /** 73 | * Returns a new reference of the documents identifier. 74 | * @returns 75 | */ 76 | public getId(): string { 77 | return String(this.__id__) 78 | } 79 | 80 | /** 81 | * Deletes the document from database. 82 | */ 83 | public delete(): void { 84 | this.__model__.delete(this.__id__) 85 | } 86 | 87 | /** 88 | * Saves the document to the database. Should be used anytime after you mutate 89 | * the augmented properties on this object. 90 | * @returns 91 | */ 92 | public save(): this { 93 | this.__model__.sync(this.__id__) 94 | this.__knownData__ = this.asObject() 95 | return this 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /packages/beapi/src/events/PlayerTag.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client } from '../client' 7 | 8 | /** 9 | * BeAPI player tag event. Contains the logic 10 | * for translating Minecraft event data to BeAPI 11 | * wrapped data. 12 | */ 13 | export class PlayerTag extends AbstractEvent { 14 | // Predefined in AbstractEvent. 15 | protected readonly _logic = this.__logic.bind(this) 16 | // Predefined in AbstractEvent. 17 | protected readonly _client: Client 18 | // Predefined in AbstractEvent. 19 | protected _registered = false 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('PlayerTag') 23 | public readonly name = 'PlayerTag' 24 | 25 | // Predefined in AbstractEvent. 26 | @setProto('custom') 27 | public readonly iName = 'custom' 28 | 29 | // Predefined in AbstractEvent. 30 | public readonly alwaysCancel = false 31 | 32 | /** 33 | * BeAPI player tag event. Contains the logic 34 | * for translating Minecraft event data to BeAPI 35 | * wrapped data. 36 | * @param client Client referece. 37 | */ 38 | public constructor(client: Client) { 39 | super() 40 | this._client = client 41 | } 42 | 43 | // Predefined in AbstractEvent. 44 | public on(): void { 45 | // If not already registered. 46 | if (!this._registered) { 47 | // Subscribe to Client event with needed logic 48 | // And use bound _logic for the callback. 49 | this._client.addListener('Tick', this._logic) 50 | // Set registered to true so this cannot be called 51 | // Again before off being called. 52 | this._registered = true 53 | } 54 | } 55 | 56 | // Predefined in AbstractEvent. 57 | public off(): void { 58 | // If currently registered. 59 | if (this._registered) { 60 | // Remove Client event listener used 61 | // With bound _logic callback. 62 | this._client.removeListener('Tick', this._logic) 63 | // Set registered to false so this cannot be called 64 | // Again before on being called. 65 | this._registered = false 66 | } 67 | } 68 | 69 | // Predefined in AbstractEvent. 70 | protected __logic(): void { 71 | // For every player in player manager, iterate. 72 | for (const [, player] of this._client.players.getAll()) { 73 | try { 74 | // For every tag the player has, iterate. 75 | for (const tag of player.getTags()) { 76 | // If tag does not start with "beapi:" continue to next itr. 77 | if (!tag.startsWith('beapi:')) continue 78 | // Remove tag from player. 79 | player.removeTag(tag) 80 | // Emit event to client. 81 | this._client.emit(this.name, { 82 | player, 83 | // Remove "beapi:" from tag. 84 | tag: tag.replace('beapi:', ''), 85 | }) 86 | } 87 | } catch {} 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EntityTag.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client } from '../client' 7 | 8 | /** 9 | * BeAPI entity tag event. Contains the logic 10 | * for translating Minecraft event data to BeAPI 11 | * wrapped data. 12 | */ 13 | export class EntityTag extends AbstractEvent { 14 | // Predefined in AbstractEvent. 15 | protected readonly _logic = this.__logic.bind(this) 16 | // Predefined in AbstractEvent. 17 | protected readonly _client: Client 18 | // Predefined in AbstractEvent. 19 | protected _registered = false 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('EntityTag') 23 | public readonly name = 'EntityTag' 24 | 25 | // Predefined in AbstractEvent. 26 | @setProto('custom') 27 | public readonly iName = 'custom' 28 | 29 | // Predefined in AbstractEvent. 30 | public readonly alwaysCancel = false 31 | 32 | /** 33 | * BeAPI entity tag event. Contains the logic 34 | * for translating Minecraft event data to BeAPI 35 | * wrapped data. 36 | * @param client Client referece. 37 | */ 38 | public constructor(client: Client) { 39 | super() 40 | this._client = client 41 | } 42 | 43 | // Predefined in AbstractEvent. 44 | public on(): void { 45 | // If not already registered. 46 | if (!this._registered) { 47 | // Subscribe to Client event with needed logic 48 | // And use bound _logic for the callback. 49 | this._client.addListener('Tick', this._logic) 50 | // Set registered to true so this cannot be called 51 | // Again before off being called. 52 | this._registered = true 53 | } 54 | } 55 | 56 | // Predefined in AbstractEvent. 57 | public off(): void { 58 | // If currently registered. 59 | if (this._registered) { 60 | // Remove Client event listener used 61 | // With bound _logic callback. 62 | this._client.removeListener('Tick', this._logic) 63 | // Set registered to false so this cannot be called 64 | // Again before on being called. 65 | this._registered = false 66 | } 67 | } 68 | 69 | // Predefined in AbstractEvent. 70 | protected __logic(): void { 71 | // For every entity in entity manager, iterate 72 | for (const [, entity] of this._client.entities.getAll()) { 73 | try { 74 | // For every tag the entity has, iterate. 75 | for (const tag of entity.getTags()) { 76 | // If tag does not start with "beapi:" continue 77 | if (!tag.startsWith('beapi:')) continue 78 | // Remove the "beapi:" tag from the player 79 | entity.removeTag(tag) 80 | // Emit entity tag event. 81 | this._client.emit(this.name, { 82 | entity, 83 | // Remove "beapi:" from tag. 84 | tag: tag.replace('beapi:', ''), 85 | }) 86 | } 87 | } catch {} 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /packages/beapi/src/events/ItemEvent.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { BeforeItemDefinitionTriggeredEvent, world, Player } from 'mojang-minecraft' 5 | import { Item } from '../item' 6 | 7 | // Type imports. 8 | import type { Client } from '../client' 9 | 10 | /** 11 | * BeAPI item event event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class ItemEvent extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('ItemEvent') 25 | public readonly name = 'ItemEvent' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('beforeItemDefinitionEvent') 29 | public readonly iName = 'beforeItemDefinitionEvent' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI item event event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | protected __logic(arg: BeforeItemDefinitionTriggeredEvent): void { 72 | // If source is a player we dont care return. 73 | if (arg.source.id !== 'minecraft:player') return 74 | 75 | // Attempt to get the player. 76 | const player = this._client.players.getByIPlayer(arg.source as Player) 77 | 78 | // If no player return. 79 | if (!player) return 80 | 81 | // Emit de item evente. 82 | this._client.emit(this.name, { 83 | player: player, 84 | item: new Item(this._client, arg.item), 85 | event: arg.eventName, 86 | cancel() { 87 | arg.cancel = true 88 | }, 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /packages/beapi/src/events/BlockHit.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { Block } from '../block' 4 | import { setProto } from '../' 5 | import { world, Player as IPlayer, EntityHitEvent } from 'mojang-minecraft' 6 | 7 | // Type imports. 8 | import type { Client } from '../client' 9 | 10 | /** 11 | * BeAPI block hit event. Contains the logic 12 | * for translating Minecraft event data to BeAPI 13 | * wrapped data. 14 | */ 15 | export class BlockHit extends AbstractEvent { 16 | // Predefined in AbstractEvent. 17 | protected readonly _logic = this.__logic.bind(this) 18 | // Predefined in AbstractEvent. 19 | protected readonly _client: Client 20 | // Predefined in AbstractEvent. 21 | protected _registered = false 22 | 23 | // Predefined in AbstractEvent. 24 | @setProto('BlockHit') 25 | public readonly name = 'BlockHit' 26 | 27 | // Predefined in AbstractEvent. 28 | @setProto('entityHit') 29 | public readonly iName = 'entityHit' 30 | 31 | // Predefined in AbstractEvent. 32 | public readonly alwaysCancel = false 33 | 34 | /** 35 | * BeAPI block hit event. Contains the logic 36 | * for translating Minecraft event data to BeAPI 37 | * wrapped data. 38 | * @param client Client referece. 39 | */ 40 | public constructor(client: Client) { 41 | super() 42 | this._client = client 43 | } 44 | 45 | // Predefined in AbstractEvent. 46 | public on(): void { 47 | // If not already registered. 48 | if (!this._registered) { 49 | // Subscribe to Minecraft world event with IName 50 | // And use bound _logic for the callback. 51 | world.events[this.iName].subscribe(this._logic) 52 | // Set registered to true so this cannot be called 53 | // Again before off being called. 54 | this._registered = true 55 | } 56 | } 57 | 58 | // Predefined in AbstractEvent. 59 | public off(): void { 60 | // If currently registered. 61 | if (this._registered) { 62 | // Remove Minecraft event listener on IName 63 | // With bound _logic callback. 64 | world.events[this.iName].unsubscribe(this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(data: EntityHitEvent): void { 73 | // If was not a block hit we dont care, return. 74 | if (!data.hitBlock) return 75 | 76 | // Attempt to get the entity who hit the block as a player. 77 | const player = this._client.players.getByIPlayer(data.entity as IPlayer) 78 | 79 | // If no player then return. 80 | if (!player) return 81 | 82 | // Emit this event on client using name defined above. 83 | return this._client.emit(this.name, { 84 | player, 85 | block: new Block(this._client, data.hitBlock), 86 | tool: player.getInventory().getItem(player.getSelectedSlot()), 87 | }) 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /packages/beapi/src/block/Permutation.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import { BlockType } from './' 3 | 4 | // Type imports. 5 | import type { Client } from '..' 6 | import type { BlockPermutation as IPermutation, IBlockProperty } from 'mojang-minecraft' 7 | 8 | /** 9 | * BeAPI wrapped block permutation. Acts as BeAPI Block and BlockType 10 | * counterpart. Allows for a smoother block permutation expierence. 11 | */ 12 | export class Permutation { 13 | /** 14 | * Circular client reference. 15 | */ 16 | protected readonly _client: Client 17 | /** 18 | * Minecraft IPermutation to wrap. 19 | */ 20 | protected readonly _IPermutation: IPermutation 21 | 22 | /** 23 | * BeAPI wrapped block permutation. Acts as BeAPI Block and BlockType 24 | * counterpart. Allows for a smoother block permutation expierence. 25 | * @param client Client reference. 26 | * @param IPermutation IPermutation to wrap. 27 | */ 28 | public constructor(client: Client, IPermutation: IPermutation) { 29 | this._client = client 30 | this._IPermutation = IPermutation 31 | } 32 | 33 | /** 34 | * Get Minecraft IPermutation being wrapped. 35 | * @returns 36 | */ 37 | public getIPermutation(): IPermutation { 38 | return this._IPermutation 39 | } 40 | 41 | /** 42 | * Get BeAPI wrapped block type. 43 | * @returns 44 | */ 45 | public getType(): BlockType { 46 | return new BlockType(this._client, this._IPermutation.type) 47 | } 48 | 49 | /** 50 | * Get permutation tags. 51 | * @returns 52 | */ 53 | public getTags(): string[] { 54 | return this._IPermutation.getTags() 55 | } 56 | 57 | /** 58 | * Check if permutation has a specific tag. 59 | * @param tag Tag to check. 60 | * @returns 61 | */ 62 | public hasTag(tag: string): boolean { 63 | return this._IPermutation.hasTag(tag) 64 | } 65 | 66 | /** 67 | * Gets permutation block properties. 68 | * @returns 69 | */ 70 | public getProperties(): IBlockProperty[] { 71 | return this._IPermutation.getAllProperties() 72 | } 73 | 74 | /** 75 | * Checks if permutation has a specific property. 76 | * @param property Property to check. 77 | * @returns 78 | */ 79 | public hasProperty(property: string): boolean { 80 | const check = this.getProperties().find((x) => x.name === property) 81 | if (!check) return false 82 | 83 | return true 84 | } 85 | 86 | /** 87 | * Gets a specific property from the permutation. 88 | * @param property Permutation to get. 89 | * @returns 90 | */ 91 | public getProperty(property: string): IBlockProperty { 92 | return this._IPermutation.getProperty(property) 93 | } 94 | 95 | /** 96 | * Clones the block permutation creating a seperate reference. 97 | * @returns 98 | */ 99 | public clone(): Permutation { 100 | return new Permutation(this._client, this._IPermutation.clone()) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EntityDestroyed.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | 5 | // Type imports. 6 | import type { Client } from '../client' 7 | 8 | /** 9 | * BeAPI entity destroyed event. Contains the logic 10 | * for translating Minecraft event data to BeAPI 11 | * wrapped data. 12 | */ 13 | export class EntityDestroyed extends AbstractEvent { 14 | // Predefined in AbstractEvent. 15 | protected readonly _logic = this.__logic.bind(this) 16 | // Predefined in AbstractEvent. 17 | protected readonly _client: Client 18 | // Predefined in AbstractEvent. 19 | protected _registered = false 20 | 21 | // Predefined in AbstractEvent. 22 | @setProto('EntityDestroyed') 23 | public readonly name = 'EntityDestroyed' 24 | 25 | // Predefined in AbstractEvent. 26 | @setProto('custom') 27 | public readonly iName = 'custom' 28 | 29 | // Predefined in AbstractEvent. 30 | public readonly alwaysCancel = false 31 | 32 | /** 33 | * BeAPI entity destroyed event. Contains the logic 34 | * for translating Minecraft event data to BeAPI 35 | * wrapped data. 36 | * @param client Client referece. 37 | */ 38 | public constructor(client: Client) { 39 | super() 40 | this._client = client 41 | } 42 | 43 | // Predefined in AbstractEvent. 44 | public on(): void { 45 | // If not already registered. 46 | if (!this._registered) { 47 | // Subscribe to Client event with needed logic 48 | // And use bound _logic for the callback. 49 | // TEMP: Mojang Needs To Add Entity Destroyed Event 50 | this._client.addListener('Tick', this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Client event listener used 62 | // With bound _logic callback. 63 | // TEMP: Mojang Needs To Add Entity Destroyed Event 64 | this._client.removeListener('Tick', this._logic) 65 | // Set registered to false so this cannot be called 66 | // Again before on being called. 67 | this._registered = false 68 | } 69 | } 70 | 71 | // Predefined in AbstractEvent. 72 | protected __logic(): void { 73 | // For every entity in the entity manager interate. 74 | for (const [, entity] of this._client.entities.getAll()) { 75 | // Try to get the entities id. If it returns an error 76 | // (which it will when its dead as you are trying to access 77 | // released memory through a now invalidated pointer) 78 | // Then emit the death event on the entity and remove it 79 | // from the entity manager 80 | try { 81 | entity.getIEntity().id 82 | } catch { 83 | this._client.emit(this.name, entity) 84 | this._client.entities.remove(entity) 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /packages/beapi/src/events/PlayerEventTrigger.ts: -------------------------------------------------------------------------------- 1 | // Normal imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { setProto } from '../' 4 | import { world, Player as IPlayer, BeforeDataDrivenEntityTriggerEvent } from 'mojang-minecraft' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI player event trigger event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class PlayerEventTrigger extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('PlayerEventTrigger') 24 | public readonly name = 'PlayerEventTrigger' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('beforeDataDrivenEntityTriggerEvent') 28 | public readonly iName = 'beforeDataDrivenEntityTriggerEvent' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI player event trigger event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: BeforeDataDrivenEntityTriggerEvent): void { 72 | // If not instance of player we dont care. 73 | if (!(arg.entity instanceof IPlayer)) return 74 | 75 | // Try to get the player from player manager. 76 | const player = this._client.players.getByIPlayer(arg.entity) 77 | 78 | // If no player return. 79 | if (!player) return 80 | 81 | // Emit the client event. 82 | this._client.emit(this.name, { 83 | player, 84 | event: arg.id, 85 | data: arg.modifiers, 86 | cancel: () => { 87 | arg.cancel = true 88 | }, 89 | }) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /packages/beapi/src/events/EntityEventTrigger.ts: -------------------------------------------------------------------------------- 1 | // Regular imports. 2 | import AbstractEvent from './AbstractEvent' 3 | import { world, Player as IPlayer, BeforeDataDrivenEntityTriggerEvent } from 'mojang-minecraft' 4 | import { setProto } from '../' 5 | 6 | // Type imports. 7 | import type { Client } from '../client' 8 | 9 | /** 10 | * BeAPI entity event trigger event. Contains the logic 11 | * for translating Minecraft event data to BeAPI 12 | * wrapped data. 13 | */ 14 | export class EntityEventTrigger extends AbstractEvent { 15 | // Predefined in AbstractEvent. 16 | protected readonly _logic = this.__logic.bind(this) 17 | // Predefined in AbstractEvent. 18 | protected readonly _client: Client 19 | // Predefined in AbstractEvent. 20 | protected _registered = false 21 | 22 | // Predefined in AbstractEvent. 23 | @setProto('EntityEventTrigger') 24 | public readonly name = 'EntityEventTrigger' 25 | 26 | // Predefined in AbstractEvent. 27 | @setProto('beforeDataDrivenEntityTriggerEvent') 28 | public readonly iName = 'beforeDataDrivenEntityTriggerEvent' 29 | 30 | // Predefined in AbstractEvent. 31 | public readonly alwaysCancel = false 32 | 33 | /** 34 | * BeAPI entity event trigger event. Contains the logic 35 | * for translating Minecraft event data to BeAPI 36 | * wrapped data. 37 | * @param client Client referece. 38 | */ 39 | public constructor(client: Client) { 40 | super() 41 | this._client = client 42 | } 43 | 44 | // Predefined in AbstractEvent. 45 | public on(): void { 46 | // If not already registered. 47 | if (!this._registered) { 48 | // Subscribe to Minecraft world event with IName 49 | // And use bound _logic for the callback. 50 | world.events[this.iName].subscribe(this._logic) 51 | // Set registered to true so this cannot be called 52 | // Again before off being called. 53 | this._registered = true 54 | } 55 | } 56 | 57 | // Predefined in AbstractEvent. 58 | public off(): void { 59 | // If currently registered. 60 | if (this._registered) { 61 | // Remove Minecraft event listener on IName 62 | // With bound _logic callback. 63 | world.events[this.iName].unsubscribe(this._logic) 64 | // Set registered to false so this cannot be called 65 | // Again before on being called. 66 | this._registered = false 67 | } 68 | } 69 | 70 | // Predefined in AbstractEvent. 71 | protected __logic(arg: BeforeDataDrivenEntityTriggerEvent): void { 72 | // If entity is instance of a player we dont want. 73 | if (arg.entity instanceof IPlayer) return 74 | 75 | // Try to get the entity from entity manager. 76 | const entity = this._client.entities.getByIEntity(arg.entity) 77 | 78 | // If not entity then return. 79 | if (!entity) return 80 | 81 | // Otherwise emit event event trigger through client. 82 | this._client.emit(this.name, { 83 | entity, 84 | event: arg.id, 85 | data: arg.modifiers, 86 | cancel: () => { 87 | arg.cancel = true 88 | }, 89 | }) 90 | } 91 | } 92 | --------------------------------------------------------------------------------