diff --git a/.gitignore b/.gitignore index b512c09..acaa0d4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules \ No newline at end of file +node_modules +test.js \ No newline at end of file diff --git a/README.md b/README.md index 92f8a1b..d8ee188 100644 --- a/README.md +++ b/README.md @@ -1,91 +1,140 @@ -# JustSkyAPI - Minecraft Bedrock Scripting API + + + + +![Bedrock-API](https://socialify.git.ci/JustSkyDev/Bedrock-API/image?description=1&descriptionEditable=Minecraft%20Bedrock%20Custom%20Scripting%20API&font=Source%20Code%20Pro&forks=1&issues=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2FJustSkyDev%2FBedrock-API%2Fmain%2Fpack_icon.png&name=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light) + +
+
+ +

Bedrock API

+ +

+ Bedrock API is a library built using Minecraft Bedrock Scripting API. This library will help you keep your code clean and make it easier to interact with the Scripting API, while including a lot of new classes/functions/methods for you to use! and some built-in custom command +
+ Docs Coming soon » +
+
+ View + · + Bug Report + · + Feature Request +

+ +--- + +[![MIT License](https://img.shields.io/github/license/JustSkyDev/Bedrock-API?style=for-the-badge)](https://github.com/notbeer/Gametest-API-Wrapper/blob/main/LICENSE.txt) [![Discord](https://img.shields.io/discord/898202806052347984?color=blue&label=Discord&style=for-the-badge)](https://discord.gg/g4EJ38HZ7R) [![YouTube](https://img.shields.io/youtube/channel/subscribers/UC9gjEs8-syrZcgftpm3gsyQ?label=YouTube&style=for-the-badge)](https://youtube.com/@JustSkyDev) -[![GitHub Releases](https://img.shields.io/github/downloads/JustSkyDev/JustSky-API/total?style=for-the-badge) -](https://github.com/JustSkyDev/JustSky-API/releases/latest) - -
- -![JustSky-API](https://socialify.git.ci/JustSkyDev/JustSky-API/image?description=1&descriptionEditable=Minecraft%20Bedrock%20Custom%20Scripting%20API&font=Source%20Code%20Pro&forks=1&issues=1&logo=https%3A%2F%2Fraw.githubusercontent.com%2FJustSkyDev%2FJustSky-API%2Fmain%2Fpack_icon.png&name=1&owner=1&pattern=Floating%20Cogs&pulls=1&stargazers=1&theme=Light) - -`JustSky-API` is an API based on the Scripting API in Minecraft bedrock, this API is very easy to use - -`Default Command Prefix`: **!** - -## 💎 Features -- **Easy-to-use** -- **Fast** -- **Built-in plugins (Custom Commands and Chat Ranks)** -- **Include Database, Collection (Map Extension)** -- **Include Command Builder, PlayerClass, EntityClass, ChatClass** -- **Include Formatter, Validation, Timer, CooldownClass** -- **ETC** - -## ⚙️ Experimental toggle -- Turn on the **Beta Api's** toggle in Experiments menu - -## 🔧 Installation -- **It is recommended to put API folder to** `development_behavior_pack`, **every time you reload the world or run the /reload command, the API will automatically reload** - -## 🛠️ Example usage -- **Command Builder** -- **PATH** PATH/Custom Command/yourCommand.js - -```javascript -// Import these two Class -import { Command, CommandRegistration } from "../class.chain.js"; - -// Create the registration information -const registration = new CommandRegistration() - .setName("yourcommandname") // Command name - .setDescription("Command description") - .setAliases(["y"]) // Command aliases - .setCategory("Custom"); // Command category - -// Build the command -Command.BuildCommand(registration, (interaction) => { - // Interaction list - const { DB, raw, sender, args, allCommandRegistration } = interaction; - /** - * DB is Database - * raw is Raw packet from ChatSendEvent - * sender is Who send the command - * args is Arguments, like player send command !help 2, args[0] would be "2" - * allCommandRegistration is Get all command registration from Command Builder - */ -}); -``` - -- **Database** -```javascript -const DB = new Database("dbName"); // Create new database with name "dbName" -db.set("key", "value"); // Set data to database -db.get("key); // Get data from database, this would return "value" -``` - -- **Collection** -```javascript -const collect = new Collection(); // Create new collection -collect.set("key", "value"); // Set data to collection -collect.get("key"); // Get data from collection -``` - -- **Entity & Player Class** -```javascript -// Entity coming soon - -// Player -const player = new PlayerClass(playerObject); -const score = player.getScore("money"); -const isOnline = player.isOnline("playerName"); -``` - -## 📑 Note -- **If you found bug or need more features, you can create/open Issues or Pull Request** +[![GitHub Releases](https://img.shields.io/github/downloads/JustSkyDev/Bedrock-API/total?style=for-the-badge) +](https://github.com/JustSkyDev/Bedrock-API/releases/latest) + +--- + +
+ + +
+

Table of Contents

+
    +
  1. + About The Project + +
  2. +
  3. + Getting Started + +
  4. +
  5. Usage
  6. +
  7. Contributing
  8. +
  9. License
  10. +
  11. Contact
  12. +
  13. Acknowledgements
  14. +
+
+ + +
+ +## About The Project + +JSBedrock-API will provide you with a lot of classes and methods for you to use. There be a lot of useful custom methods for you to use. There are also classes like Database and Collection. Scripting API doesn't come with a Database or Collection as of now, so I have added a way for you to easily store and get access to the data. There are a lot more stuff in this API/Lib! + +### Built With + +- [Scripting API Docs](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/) + + +
+ +## Getting Started + +Easy Method + +- Download this zip folder and name it to `.mcpack` and import it by double clicking on the folder. This method will only work if you have Minecraft Bedrock Edition on the same device you are doing this action on. + +Recommended Method + +- Another Method would be to take the zipped folder and unzip/extract it. Take your folder and move it to the folder 'development_behavior_packs', which can be found in a path like `PATH/TO/development_behavior_packs`. This will make your life way easier, while developing this pack. It will update the content inside your game everytime you make any changes to the script. For the changes to apply you must leave and rejoin your world where the pack is applied at. +
+ +### Installation + +1. Clone the repo + ```sh + git clone https://github.com/JustSkyDev/Bedrock-API.git + ``` +
+ +## Usage + +IMPORTANT: `If you are going to apply any Scripting related scripts to your world, please make a copy of your world before you do so! I'm not responsible if anything goes wrong-` + +Create a new world, since Scripting API is still experimental. Make sure in your settings you have `Beta API's` in `Experiments` menu. +I have some examples on how you can use this library. Specifically on custom commands. Type in the game chat `!help` for the list of custom commands or `!help [command name]` to get information on a specific command! + + +
+ +## Roadmap + +See the [open issues](https://github.com/JustSkyDev/Bedrock-API/issues) for a list of proposed features (and known issues). + + +
+ +## License + +Distributed under the MIT License. See `LICENSE` for more information. + + +
+ +## Contact + +Discord - JustSky#2117 + + +
+ +## Acknowledgements + +- [Scripting API Docs](https://learn.microsoft.com/en-us/minecraft/creator/scriptapi/) + +
-## ⭐ Star +## Star + +[![Star History Chart](https://api.star-history.com/svg?repos=JustSkyDev/Bedrock-API&type=Date)](https://star-history.com/#JustSkyDev/Bedrock-API&Date) -[![Star History Chart](https://api.star-history.com/svg?repos=JustSkyDev/JustSky-API&type=Date)](https://star-history.com/#JustSkyDev/JustSky-API&Date) \ No newline at end of file diff --git a/manifest.json b/manifest.json index 7ee6057..9fe49f4 100644 --- a/manifest.json +++ b/manifest.json @@ -1,10 +1,10 @@ { "format_version": 2, "header": { - "name": "§eJSAPI", + "name": "§eJSBedrock-API", "description": "§cMade By §fJustSkyDev(YouTube)", "uuid": "405e8f7a-db2d-11ed-afa1-0242ac120002", - "version": [1, 0, 0], + "version": [1, 0, 1], "min_engine_version": [1, 20, 0] }, "modules": [ diff --git a/scripts/JS/@modules/export.modules.js b/scripts/JS/@modules/export.modules.js index 9db5e7a..df0cb04 100644 --- a/scripts/JS/@modules/export.modules.js +++ b/scripts/JS/@modules/export.modules.js @@ -2,8 +2,9 @@ export { Command } from "./handlers/command/Command.Class.js"; export { CommandRegistration } from "./handlers/command/CommandRegistration.Class.js"; export { Collection } from "./handlers/data/Collection.Class.js"; export { PlayerClass } from "./handlers/entity/Player.Class.js"; -//export { EntityClass } from "./handlers/entity/Entity.Class.js"; +export { EntityClass } from "./handlers/entity/Entity.Class.js"; export { ChatClass } from "./handlers/message/Chat.Class.js"; +export { ErrorClass } from "./handlers/message/Error.Class.js"; export { FailedClass } from "./handlers/message/Failed.Class.js"; export { Database } from "./storages/Database.Class.js"; diff --git a/scripts/JS/@modules/handlers/command/Command.Class.js b/scripts/JS/@modules/handlers/command/Command.Class.js index 63fba1f..7985d9c 100644 --- a/scripts/JS/@modules/handlers/command/Command.Class.js +++ b/scripts/JS/@modules/handlers/command/Command.Class.js @@ -2,6 +2,8 @@ import { world } from "@minecraft/server"; import { Collection } from "../data/Collection.Class.js"; import { FailedClass } from "../message/Failed.Class.js"; import { Database } from "../../storages/Database.Class.js"; +import { ErrorClass } from "../message/Error.Class.js"; +import * as Validation from "../../utils/Validation.Function.js"; import { Config } from "../../../config.js"; class CommandClass { @@ -14,6 +16,8 @@ class CommandClass { /**@private */ this.failed = new FailedClass(); /**@private */ + this.error = new ErrorClass(); + /**@private */ this.db = new Database("GlobalDB"); /**@private */ this.commandPrefix = this.db.get("commandPrefix") ?? Config.defaultPrefix; @@ -62,6 +66,28 @@ class CommandClass { return this.commandPrefix; } + /** + * Set command prefix + * @param {String} prefix + */ + setPrefix(prefix) { + if (!prefix) + this.error.CustomError( + "CommandClass", + "setPrefix", + "prefix cannot be empty" + ); + + if (!Validation.isString(prefix)) + this.error.CustomError( + "CommandClass", + "setPrefix", + "prefix must be string" + ); + + this.db.set("currentPrefix", prefix); + } + /** * Execute * @private diff --git a/scripts/JS/@modules/handlers/command/CommandRegistration.Class.js b/scripts/JS/@modules/handlers/command/CommandRegistration.Class.js index 75522db..1a28223 100644 --- a/scripts/JS/@modules/handlers/command/CommandRegistration.Class.js +++ b/scripts/JS/@modules/handlers/command/CommandRegistration.Class.js @@ -1,4 +1,4 @@ -import { Validation } from "../../export.modules.js"; +import * as Validation from "../../utils/Validation.Function.js"; class CommandRegistration { /** @@ -12,15 +12,15 @@ class CommandRegistration { /**@private */ this.private = false; /**@private */ - this.category = ""; + this.category = "Global"; /**@private */ - this.requireTags = []; + this.requireTags = [null]; /**@private */ - this.aliases = []; + this.aliases = [null]; /**@private */ - this.usage = []; + this.usage = [null]; /**@private */ - this.example = []; + this.example = [null]; } /** * Set command name diff --git a/scripts/JS/@modules/handlers/entity/Entity.Class.js b/scripts/JS/@modules/handlers/entity/Entity.Class.js index e69de29..a0a43b6 100644 --- a/scripts/JS/@modules/handlers/entity/Entity.Class.js +++ b/scripts/JS/@modules/handlers/entity/Entity.Class.js @@ -0,0 +1,63 @@ +import { Entity } from "@minecraft/server"; +import { ErrorClass } from "../message/Error.Class.js"; + +class EntityClass { + /** + * Entity class + * @param {Entity} entityObject - Entity object + */ + constructor(entityObject) { + /**@private */ + this.entity = entityObject; + /**@private */ + this.error = new ErrorClass(); + + if (!entityObject) + this.error.CustomError( + "EntityClass", + "constructor", + "EntityObject cannot be empty" + ); + } + + /** + * Get player all tag + * @returns {Array} + * @example getTags(); + */ + getTags() { + return this.entity.getTags(); + } + + /** + * Check player if had tag + * @param {String} tag - Tag + * @returns {Boolean} + * @example hasTag("tag"); + */ + hasTag(tag) { + if (!tag) + this.error.CustomError("EntityClass", "hasTag", "tag cannot be empty"); + + return this.entity.hasTag(tag); + } + + /** + * Get player specific tag + * @returns {Boolean|String} + * @example getSpecificTag("tag:"); + */ + getSpecificTag(startswith) { + if (!this.startswith) + this.error.CustomError( + "EntityClass", + "getSpecificTagg", + "startswith cannot be empty" + ); + + const check = this.getTags()?.find((tag) => tag.startsWith(startswith)); + return check ? check : false; + } +} + +export { EntityClass }; diff --git a/scripts/JS/@modules/handlers/entity/Player.Class.js b/scripts/JS/@modules/handlers/entity/Player.Class.js index c5e82b1..b1071c6 100644 --- a/scripts/JS/@modules/handlers/entity/Player.Class.js +++ b/scripts/JS/@modules/handlers/entity/Player.Class.js @@ -1,13 +1,25 @@ import { world, Player } from "@minecraft/server"; +import { EntityClass } from "./Entity.Class.js"; +import { ErrorClass } from "../message/Error.Class.js"; -class PlayerClass { +class PlayerClass extends EntityClass { /** * Player class * @param {Player} playerObject - Player object */ constructor(playerObject) { + super(playerObject); + /**@private */ this.playerObject = playerObject; - if (!playerObject) throw new Error("PlayerObject cannot be empty"); + /**@private */ + this.error = new ErrorClass(); + + if (!playerObject) + this.error.CustomError( + "PlayerClass", + "constructor", + "PlayerObject cannot be empty" + ); } /** @@ -33,43 +45,16 @@ class PlayerClass { return this.playerObject.level; } - /** - * Get player specific tag - * @returns {Boolean|String} - * @example getSpecificTag("tag:"); - */ - getSpecificTag(startswith) { - const check = this.getTags()?.find((tag) => tag.startsWith(startswith)); - return check ? check : false; - } - - /** - * Get player all tag - * @returns {Array} - * @example getTags(); - */ - getTags() { - return this.playerObject.getTags(); - } - - /** - * Check player if had tag - * @param {String} tag - Tag - * @returns {Boolean} - * @example hasTag("tag"); - */ - hasTag(tag) { - return this.playerObject.hasTag(tag); - } - /** * Check player if online + * @param {Player.nameTag} target - Player nametag * @returns {Boolean} * @example isOnline("JustSky001"); */ isOnline(target) { return ( - this.getAllPlayers().find((name) => name === target) !== undefined + this.getAllPlayers().find((player) => player.nameTag === target) !== + undefined ); } diff --git a/scripts/JS/@modules/handlers/message/Chat.Class.js b/scripts/JS/@modules/handlers/message/Chat.Class.js index b06b46f..5ff6d17 100644 --- a/scripts/JS/@modules/handlers/message/Chat.Class.js +++ b/scripts/JS/@modules/handlers/message/Chat.Class.js @@ -1,10 +1,11 @@ -import { world } from "@minecraft/server"; +import { Player, world } from "@minecraft/server"; +import { ErrorClass } from "./Error.Class.js"; class ChatClass { /** * Broadcast message in chat * @param {Object} rawtext - The text must be Object - * @param {String} player - Player name (Optional) + * @param {Player|Player.nameTag} player - Player name (Optional) * @returns {any} * @example broadcast({ text: "Hello world!" }); */ @@ -24,6 +25,13 @@ class ChatClass { * @example runCommand("say Hello world!"); */ runCommand(command, dimension = "overworld", debugMode = false) { + if (command.startsWith("/")) + new ErrorClass().CustomError( + "ChatClass", + "runCommand", + 'command cannot starts with "/" at ' + ); + return debugMode ? console.warn(JSON.stringify(this.runCommand(command))) : world.getDimension(dimension).runCommand(command); @@ -35,6 +43,13 @@ class ChatClass { * @example runCommands([ "say Hello", "say World!" ]); */ runCommands(commands) { + if (commands.some((slash) => slash.startsWith("/"))) + new ErrorClass().CustomError( + "ChatClass", + "runCommands", + 'commands cannot starts with "/" at ' + ); + commands.forEach((cmd) => { this.runCommand(cmd); }); diff --git a/scripts/JS/@modules/handlers/message/Error.Class.js b/scripts/JS/@modules/handlers/message/Error.Class.js new file mode 100644 index 0000000..35d7161 --- /dev/null +++ b/scripts/JS/@modules/handlers/message/Error.Class.js @@ -0,0 +1,13 @@ +class ErrorClass { + /** + * Custom error + * @param {any} className + * @param {any} functionName + * @param {any} errorMessage + */ + CustomError(className, functionName, errorMessage) { + throw new Error(`${className}::${functionName} ${errorMessage}`); + } +} + +export { ErrorClass }; diff --git a/scripts/JS/@modules/storages/Database.Class.js b/scripts/JS/@modules/storages/Database.Class.js index be2453f..89d403b 100644 --- a/scripts/JS/@modules/storages/Database.Class.js +++ b/scripts/JS/@modules/storages/Database.Class.js @@ -1,10 +1,9 @@ import { system, world } from "@minecraft/server"; -import { - Collection, - Validation, - Formatter, - ChatClass, -} from "../export.modules.js"; +import { Collection } from "../handlers/data/Collection.Class.js"; +import { ChatClass } from "../handlers/message/Chat.Class.js"; +import { ErrorClass } from "../handlers/message/Error.Class.js"; +import * as Validation from "../utils/Validation.Function.js"; +import * as Formatter from "../utils/Formatter.Function.js"; class Database { /** @@ -18,14 +17,27 @@ class Database { this.DB_SAVED_NAMES = []; /**@private */ this.RESTORED_DATA = new Collection(); + /**@private */ + this.error = new ErrorClass(); - if (!name) throw new Error("Database name cannot be empty"); + if (!name) + this.error.CustomError( + "Database", + "constructor", + "Database name cannot be empty" + ); if (this.DB_SAVED_NAMES.includes(name)) - throw new Error(`Database with name ${name} already exist`); + this.error.CustomError( + "Database", + "constructor", + `Database with name ${name} already exist` + ); if (name.length > 13 || name.length === 0) - throw new Error( + this.error.CustomError( + "Database", + "constructor", "Database names can't be more than 13 characters or empty" ); @@ -54,7 +66,7 @@ class Database { */ set(key, value) { if (!Validation.isString(value)) - throw new Error("Database::set value must be string"); + this.error.CustomError("Database", "set", "value must be string"); const encryptKey = Formatter.EncryptText(key); const encryptValue = Formatter.EncryptText(value); diff --git a/scripts/JS/@modules/utils/Cooldown.Class.js b/scripts/JS/@modules/utils/Cooldown.Class.js index c0732da..4ad6317 100644 --- a/scripts/JS/@modules/utils/Cooldown.Class.js +++ b/scripts/JS/@modules/utils/Cooldown.Class.js @@ -1,46 +1,49 @@ +import { setTickTimeout } from "./Timer.Function.js"; + class CooldownClass { /** * Cooldown system * @param {String} name - Cooldown name */ constructor(name) { - /**@private */ - this.cooldowns = new Map(); /**@private */ this.name = name; + /**@private */ + this.endTime = null; } /** - * Start the cooldown - * @param {Number} duration - Duration + * Start cooldown + * @param {Number} duration - Duration in seconds */ start(duration) { - const endTime = Date.now() + duration * 1000; - this.cooldowns.set(this.name, endTime); + if (this.isActive()) return; + + this.endTime = Date.now() + duration * 1000; + + setTickTimeout(() => { + this.endTime = null; + }, duration * 20); } /** - * Check if cooldown is active + * Check cooldown * @returns {Boolean} */ isActive() { - const endTime = this.cooldowns.get(this.name); - if (!endTime) { - return false; - } - return Date.now() < endTime; + return this.endTime !== null && this.endTime > Date.now(); } /** - * Get cooldown time left + * Get cooldown time remaining * @returns {Number} */ - getTime() { - const endTime = this.cooldowns.get(this.name); - if (!endTime) { - return 0; + getCooldown() { + if (this.isActive()) { + const remainingTime = Math.max(0, this.endTime - Date.now()); + return Math.round(remainingTime / 1000); } - return Math.max(0, endTime - Date.now()); + return 0; } } diff --git a/scripts/JS/@modules/utils/Formatter.Function.js b/scripts/JS/@modules/utils/Formatter.Function.js index 2323621..4f4253a 100644 --- a/scripts/JS/@modules/utils/Formatter.Function.js +++ b/scripts/JS/@modules/utils/Formatter.Function.js @@ -1,3 +1,68 @@ +/** + * Turn text into colored text + * @param {String} text - The text you want to format to rainbow colors. + * @returns {String} + * @example rainbowText('This is rainbow text!'); + */ +function rainbowText(text) { + const rainbowCode = [ + "§4", + "§c", + "§6", + "§e", + "§g", + "§2", + "§a", + "§b", + "§3", + "§9", + "§5", + "§d", + ]; + const letter = text.replace(/§./g, "").split(""); + + let newMessage = ""; + let rainbowIndex = 0; + + letter.forEach((letter) => { + if (letter !== " ") { + newMessage += `${rainbowCode[rainbowIndex]}${letter}`; + rainbowIndex + 1 >= rainbowCode.length + ? (rainbowIndex = 0) + : rainbowIndex++; + } else newMessage += " "; + }); + + return newMessage; +} + +/** + * This will display in text in thousands, millions and etc... For ex: "1400 -> "1.4k", "1000000" -> "1M", etc... + * @param {Number} number - The number you want to convert + * @returns {String} + * @example metricNumbers(15000); + */ +function metricNumbers(value) { + const types = ["", "k", "M", "G", "T", "P", "E", "Z", "Y"]; + const selectType = (Math.log10(value) / 3) | 0; + + if (selectType == 0) return value; + let scaled = value / Math.pow(10, selectType * 3); + + return scaled.toFixed(1) + types[selectType]; +} + +/** + * Will format your number. For ex: "1400" -> "1,400", "1000000" -> "1,000,000", etc... + * @param {Number} number - The number you want to convert + * @returns {String} + * @example thousandsSeparator(15000); + */ +function thousandsSeparator(value) { + if (typeof value !== "number") return; + return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); +} + /** * Encrypt text * @param {String} text @@ -26,4 +91,10 @@ function DecryptText(encrypt) { .join(""); } -export { EncryptText, DecryptText }; +export { + rainbowText, + metricNumbers, + thousandsSeparator, + EncryptText, + DecryptText, +}; diff --git a/scripts/JS/@modules/utils/Validation.Function.js b/scripts/JS/@modules/utils/Validation.Function.js index 4f65093..f646da5 100644 --- a/scripts/JS/@modules/utils/Validation.Function.js +++ b/scripts/JS/@modules/utils/Validation.Function.js @@ -54,6 +54,41 @@ function isArray(array) { return Array.isArray(array); } -export { isString, isNumber, isInteger, isBoolean, isObject, isArray }; +/** + * Check if null + * @param {Object} object + * @returns + */ +function isNull(object) { + return object === null; +} + +/** + * Check if undefined + * @param {Object} object + * @returns + */ +function isUndefined(object) { + return object === undefined; +} + +/** + * Check if error + * @param {Error} error + * @returns + */ +function isError(error) { + return error instanceof Error && "message" in error; +} -// world.scoreboard.getParticipants().find((sb) => sb.displayName == player) +export { + isString, + isNumber, + isInteger, + isBoolean, + isObject, + isArray, + isNull, + isUndefined, + isError, +}; diff --git a/scripts/JS/config.js b/scripts/JS/config.js index 29180ae..43bc62a 100644 --- a/scripts/JS/config.js +++ b/scripts/JS/config.js @@ -1,7 +1,7 @@ const Config = { defaultPrefix: "!", // Default custom command prefix disableWatchDog: true, // Change to true when your world crashes - version: "1.0.0-release", + version: "1.0.1-release", }; export { Config }; diff --git a/scripts/JS/plugins/Chat Rank/config.js b/scripts/JS/plugins/Chat Ranks/config.js similarity index 100% rename from scripts/JS/plugins/Chat Rank/config.js rename to scripts/JS/plugins/Chat Ranks/config.js diff --git a/scripts/JS/plugins/Chat Rank/system.js b/scripts/JS/plugins/Chat Ranks/system.js similarity index 100% rename from scripts/JS/plugins/Chat Rank/system.js rename to scripts/JS/plugins/Chat Ranks/system.js diff --git a/scripts/JS/plugins/Custom Command/built-in/ping.js b/scripts/JS/plugins/Custom Command/built-in/ping.js deleted file mode 100644 index bfd5c86..0000000 --- a/scripts/JS/plugins/Custom Command/built-in/ping.js +++ /dev/null @@ -1,11 +0,0 @@ -import * as API from "../../class.chain.js"; - -const registration = new API.CommandRegistration() - .setName("ping") - .setDescription("Ping command") - .setCategory("Built-in") - .setAliases(["p"]); - -API.Command.BuildCommand(registration, (interaction) => { - interaction.sender.sendMessage("Pong!"); -}); diff --git a/scripts/JS/plugins/Custom Commands/built-in/checkOnline.js b/scripts/JS/plugins/Custom Commands/built-in/checkOnline.js new file mode 100644 index 0000000..21525c4 --- /dev/null +++ b/scripts/JS/plugins/Custom Commands/built-in/checkOnline.js @@ -0,0 +1,28 @@ +import { + Command, + CommandRegistration, + PlayerClass, +} from "../../class.chain.js"; + +const registration = new CommandRegistration() + .setName("checkonline") + .setDescription("Get player status, online or offline") + .setAliases(["con", "checkon"]) + .setCategory("Built-in") + .setUsage([""]) + .setExample(["checkonline JustSky001"]); + +Command.BuildCommand(registration, (interaction) => { + const { sender } = interaction; + const player = new PlayerClass(sender); + + if (!args[0]) + return sender.sendMessage("§cSeconds arguments cannot be empty"); + + const checkPlayer = player.isOnline(args[0]); + return sender.sendMessage( + checkPlayer + ? `§aPlayer with names §f${args[0]} §ais online` + : `§cPlayer with names §f${args[0]} §cnot found or offline` + ); +}); diff --git a/scripts/JS/plugins/Custom Command/built-in/help.js b/scripts/JS/plugins/Custom Commands/built-in/help.js similarity index 57% rename from scripts/JS/plugins/Custom Command/built-in/help.js rename to scripts/JS/plugins/Custom Commands/built-in/help.js index f0a4f90..f37fc12 100644 --- a/scripts/JS/plugins/Custom Command/built-in/help.js +++ b/scripts/JS/plugins/Custom Commands/built-in/help.js @@ -1,20 +1,20 @@ -import * as API from "../../class.chain.js"; +import { Command, CommandRegistration, Validation } from "../../class.chain.js"; -const registration = new API.CommandRegistration() +const registration = new CommandRegistration() .setName("help") .setDescription("Help command") .setCategory("Built-in") .setAliases(["?", "h"]) - .setUsage([""]) + .setUsage([""]) .setExample(["help ping", "help 1", "help"]); const PAGE_LIMIT = 12; -API.Command.BuildCommand(registration, (interaction) => { +Command.BuildCommand(registration, (interaction) => { const { sender, args, allCommandRegistration } = interaction; - if (isNaN(args[0]) && args[0] !== undefined) { - const item = API.Command.getCommand(args[0]); + if (isNaN(args[0]) && !Validation.isUndefined(args[0])) { + const item = Command.getCommand(args[0]); if (!item) return sender.sendMessage( @@ -24,21 +24,22 @@ API.Command.BuildCommand(registration, (interaction) => { return sender.sendMessage( `§bName: §f${item.name}\n§bDescription: §f${ item.description - }\n§bCategory: §f${item.category ?? "No category"}\n§bAliases: §f${ - item.aliases ?? "No aliases" - }\n§bUsage: ${item.usage || "No usage"}` + }\n§bCategory: §f${item.category}\n§bAliases: §f${ + item.aliases?.join(", ") || "No aliases" + }\n§bUsage: ${item.usage?.join(", ") || "No usage"}` ); } else { const startIndex = ((args[0] ?? 1) - 1) * PAGE_LIMIT; const endIndex = (args[0] ?? 1) * PAGE_LIMIT; - const items = Array.from(allCommandRegistration.values()).slice( - startIndex, - endIndex - ); + const items = Array.from(allCommandRegistration.values()) + .slice(startIndex, endIndex) + .filter((command) => !command.private) + .sort((a, b) => a.name.localeCompare(b.name)); let messages = ""; let currentCategory = ""; + messages += `§aShowing page\n\n`; messages += items .map((item) => { let categoryLine = ""; @@ -46,7 +47,7 @@ API.Command.BuildCommand(registration, (interaction) => { categoryLine = `§e${item.category}:\n`; currentCategory = item.category; } - return `§a${categoryLine} §a${API.Command.getPrefix()}${item.name}: ${ + return `§a${categoryLine} §a${Command.getPrefix()}${item.name}: ${ item.description }`; }) @@ -57,15 +58,14 @@ API.Command.BuildCommand(registration, (interaction) => { PAGE_LIMIT ); if (remainingItems.length > 0) { - messages += - "\n§eTo view the next page, use §fhelp 2 §eor §fhelp 3§e, and so on"; + messages += `\n§eTo view the next page, use §f${Command.getPrefix()}help 2 §eor §f${Command.getPrefix()}help 3§e, and so on`; } } else { const remainingItems = Array.from(allCommandRegistration.values()).slice( endIndex ); if (remainingItems.length > 0) { - messages += `\n§eTo view the next page, use §fhelp ${ + messages += `\n§eTo view the next page, use §f${Command.getPrefix()}help ${ (args[0] ?? 1) + 1 }`; } diff --git a/scripts/JS/plugins/Custom Commands/built-in/ping.js b/scripts/JS/plugins/Custom Commands/built-in/ping.js new file mode 100644 index 0000000..27a8f62 --- /dev/null +++ b/scripts/JS/plugins/Custom Commands/built-in/ping.js @@ -0,0 +1,11 @@ +import { Command, CommandRegistration } from "../../class.chain.js"; + +const registration = new CommandRegistration() + .setName("ping") + .setDescription("Ping command") + .setCategory("Built-in") + .setAliases(["p"]); + +Command.BuildCommand(registration, (interaction) => { + interaction.sender.sendMessage("Pong!"); +}); diff --git a/scripts/JS/plugins/Custom Commands/built-in/version.js b/scripts/JS/plugins/Custom Commands/built-in/version.js new file mode 100644 index 0000000..9339680 --- /dev/null +++ b/scripts/JS/plugins/Custom Commands/built-in/version.js @@ -0,0 +1,12 @@ +import { Command, CommandRegistration } from "../../class.chain.js"; + +const registration = new CommandRegistration() + .setName("version") + .setDescription("Get API version") + .setAliases(["v", "ver", "versi"]) + .setCategory("Built-in"); + +Command.BuildCommand(registration, (interaction) => { + const { sender, config } = interaction; + return sender.sendMessage(`§aAPI version: §f${config.version}`); +}); diff --git a/scripts/JS/plugins/Custom Command/example/example.js b/scripts/JS/plugins/Custom Commands/example/example.js similarity index 100% rename from scripts/JS/plugins/Custom Command/example/example.js rename to scripts/JS/plugins/Custom Commands/example/example.js diff --git a/scripts/JS/plugins/Custom Command/example/types.js b/scripts/JS/plugins/Custom Commands/example/types.js similarity index 100% rename from scripts/JS/plugins/Custom Command/example/types.js rename to scripts/JS/plugins/Custom Commands/example/types.js diff --git a/scripts/JS/plugins/Custom Command/system.js b/scripts/JS/plugins/Custom Commands/system.js similarity index 62% rename from scripts/JS/plugins/Custom Command/system.js rename to scripts/JS/plugins/Custom Commands/system.js index 7ce95a6..caa5ede 100644 --- a/scripts/JS/plugins/Custom Command/system.js +++ b/scripts/JS/plugins/Custom Commands/system.js @@ -1,5 +1,7 @@ // Import your command import "./built-in/ping.js"; import "./built-in/help.js"; +import "./built-in/checkOnline.js"; +import "./built-in/version.js"; import "./example/example.js"; diff --git a/scripts/JS/plugins/class.chain.js b/scripts/JS/plugins/class.chain.js index 13ff9b0..5f3d38b 100644 --- a/scripts/JS/plugins/class.chain.js +++ b/scripts/JS/plugins/class.chain.js @@ -4,6 +4,7 @@ export { Collection, PlayerClass, ChatClass, + ErrorClass, FailedClass, Database, CooldownClass, diff --git a/scripts/JS/plugins/import.plugins.js b/scripts/JS/plugins/import.plugins.js index 338701f..d3e947c 100644 --- a/scripts/JS/plugins/import.plugins.js +++ b/scripts/JS/plugins/import.plugins.js @@ -7,8 +7,8 @@ const pluginFolder = [ // Import Plugin (Folder Name) - "Chat Rank", - "Custom Command", + "Chat Ranks", + "Custom Commands", ];