chrxmaticc-framework 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -1
- package/core/AIWrapper.js +3 -3
- package/core/ChrxCommandBuilder.js +155 -0
- package/core/Client.js +35 -35
- package/core/CommandLoader.js +3 -2
- package/core/EventLoader.js +2 -1
- package/core/MusicManager.js +2 -1
- package/core/index.js +2 -1
- package/core/songMarkers.js +1 -1
- package/index.js +23 -10
- package/package.json +1 -1
- /package/plugins/{Reminder.js → Reminders.js} +0 -0
package/README.md
CHANGED
|
@@ -183,4 +183,78 @@ AI_KEY=your_ai_key
|
|
|
183
183
|
```
|
|
184
184
|
---
|
|
185
185
|
|
|
186
|
-
##
|
|
186
|
+
## Slash Command Addon
|
|
187
|
+
|
|
188
|
+
## chrxmaticc-framework v2.0.0
|
|
189
|
+
|
|
190
|
+
### What's new
|
|
191
|
+
|
|
192
|
+
**ChrxCommandBuilder** — write commands in as little as 6 lines.
|
|
193
|
+
|
|
194
|
+
No more `SlashCommandBuilder` boilerplate, no more manual `module.exports = { data, execute }`, no more writing cooldowns and permission checks yourself. Just name, description, and your logic.
|
|
195
|
+
|
|
196
|
+
### How it works
|
|
197
|
+
```js
|
|
198
|
+
const { ChrxCommandBuilder } = require("chrxmaticc-framework");
|
|
199
|
+
|
|
200
|
+
module.exports = new ChrxCommandBuilder({
|
|
201
|
+
name: "balance",
|
|
202
|
+
description: "Check your coin balance",
|
|
203
|
+
cooldown: 5,
|
|
204
|
+
options: [
|
|
205
|
+
{ name: "user", description: "User to check", type: "user", required: false }
|
|
206
|
+
],
|
|
207
|
+
async run(interaction, { economy }) {
|
|
208
|
+
const target = interaction.options.getUser("user") ?? interaction.user;
|
|
209
|
+
const data = await economy.getBalance(target.id, interaction.guild.id);
|
|
210
|
+
interaction.reply(`💰 **${target.username}** — ${data.balance} coins`);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Features
|
|
216
|
+
|
|
217
|
+
- **Auto option type mapping** — write `"user"` instead of `ApplicationCommandOptionType.User`. Supports `string`, `number`, `integer`, `boolean`, `user`, `channel`, `role`, `mentionable`, `attachment`
|
|
218
|
+
- **Built-in cooldowns** — just pass `cooldown: 5` (seconds), handled automatically per user
|
|
219
|
+
- **Built-in permission checks** — pass `permission: "BanMembers"` and it checks before running
|
|
220
|
+
- **Built-in error handling** — any error in `run()` is caught and sends a clean error message automatically. Custom errors via `throw new Error("your message")`
|
|
221
|
+
- **Plugin injection** — all plugins injected into `run()` automatically, no manual requires needed. Access `economy`, `moderation`, `giveaways`, `tickets`, `welcome`, `polls`, `reminders`, `starboard`, `automod`, `xp`, `ai`, `db`
|
|
222
|
+
- **Owner only** — pass `ownerOnly: true` to restrict a command to the bot owner
|
|
223
|
+
- **Choices** — pass `choices: [{ name, value }]` on string/integer/number options for dropdown menus
|
|
224
|
+
- **Still fully flexible** — `run()` is raw discord.js, no ceiling, do anything you could do in a normal command
|
|
225
|
+
|
|
226
|
+
### Changes
|
|
227
|
+
- Added `ChrxCommandBuilder` to core
|
|
228
|
+
- Updated `Client.js` with `registerPlugin()` method for automatic plugin injection
|
|
229
|
+
- Updated `index.js` to export `ChrxCommandBuilder`
|
|
230
|
+
- Added `GuildMessageReactions` intent and `Partials.Reaction` automatically for Starboard plugin
|
|
231
|
+
|
|
232
|
+
### Breaking changes
|
|
233
|
+
- None — all v1.x code works as is
|
|
234
|
+
|
|
235
|
+
### Migration from raw commands
|
|
236
|
+
|
|
237
|
+
**Before:**
|
|
238
|
+
```js
|
|
239
|
+
const { SlashCommandBuilder } = require("discord.js");
|
|
240
|
+
module.exports = {
|
|
241
|
+
data: new SlashCommandBuilder()
|
|
242
|
+
.setName("ping")
|
|
243
|
+
.setDescription("Pong!"),
|
|
244
|
+
async execute(interaction) {
|
|
245
|
+
interaction.reply("Pong!");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**After:**
|
|
251
|
+
```js
|
|
252
|
+
module.exports = new ChrxCommandBuilder({
|
|
253
|
+
name: "ping",
|
|
254
|
+
description: "Pong!",
|
|
255
|
+
cooldown: 5,
|
|
256
|
+
async run(interaction) {
|
|
257
|
+
interaction.reply("Pong!");
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
```
|
package/core/AIWrapper.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/modules/AIWrapper.js
|
|
3
|
-
* Lightweight wrapper for AI completions.
|
|
4
|
-
*
|
|
3
|
+
* Lightweight wrapper for AI completions. Nothing big.
|
|
4
|
+
* Put in your API key and model in the options.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
class AIWrapper {
|
|
@@ -70,4 +70,4 @@ class AIWrapper {
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
module.exports = AIWrapper;
|
|
73
|
+
module.exports = AIWrapper;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/ChrxCommandBuilder.js
|
|
3
|
+
* Simple command builder — write a command in 10 lines.
|
|
4
|
+
* Handles SlashCommandBuilder, option types, and plugin injection automatically.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { SlashCommandBuilder, PermissionFlagsBits } = require("discord.js");
|
|
8
|
+
|
|
9
|
+
// ── Option type map ───────────────────────────────────────────────────────
|
|
10
|
+
// Write "user" instead of ApplicationCommandOptionType.User etc.
|
|
11
|
+
const TYPE_MAP = {
|
|
12
|
+
string: "addStringOption",
|
|
13
|
+
number: "addNumberOption",
|
|
14
|
+
integer: "addIntegerOption",
|
|
15
|
+
boolean: "addBooleanOption",
|
|
16
|
+
user: "addUserOption",
|
|
17
|
+
channel: "addChannelOption",
|
|
18
|
+
role: "addRoleOption",
|
|
19
|
+
mentionable: "addMentionableOption",
|
|
20
|
+
attachment: "addAttachmentOption",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
class ChrxCommandBuilder {
|
|
24
|
+
/**
|
|
25
|
+
* @param {object} options
|
|
26
|
+
* @param {string} options.name Command name (lowercase, no spaces)
|
|
27
|
+
* @param {string} options.description Command description
|
|
28
|
+
* @param {object[]} [options.options] Command options/arguments
|
|
29
|
+
* @param {string} options.options[].name Option name
|
|
30
|
+
* @param {string} options.options[].description Option description
|
|
31
|
+
* @param {string} options.options[].type Option type — "string" | "number" | "integer" | "boolean" | "user" | "channel" | "role" | "mentionable" | "attachment"
|
|
32
|
+
* @param {boolean} [options.options[].required] Whether option is required (default: false)
|
|
33
|
+
* @param {Array} [options.options[].choices] Choices array [{ name, value }]
|
|
34
|
+
* @param {string} [options.category] Category label for help menus
|
|
35
|
+
* @param {string} [options.permission] Required permission e.g. "BanMembers"
|
|
36
|
+
* @param {boolean} [options.ownerOnly] Restrict to bot owner
|
|
37
|
+
* @param {boolean} [options.guildOnly] Restrict to guilds only (default: true)
|
|
38
|
+
* @param {number} [options.cooldown] Cooldown in seconds
|
|
39
|
+
* @param {Function} options.run Command function (interaction, plugins) => void
|
|
40
|
+
*/
|
|
41
|
+
constructor(options = {}) {
|
|
42
|
+
if (!options.name) throw new Error("[ChrxCommand] name is required.");
|
|
43
|
+
if (!options.description) throw new Error("[ChrxCommand] description is required.");
|
|
44
|
+
if (!options.run) throw new Error("[ChrxCommand] run function is required.");
|
|
45
|
+
|
|
46
|
+
this._options = options;
|
|
47
|
+
this._cooldowns = new Map();
|
|
48
|
+
|
|
49
|
+
// ── Build SlashCommandBuilder ─────────────────────────────────────────
|
|
50
|
+
const builder = new SlashCommandBuilder()
|
|
51
|
+
.setName(options.name)
|
|
52
|
+
.setDescription(options.description);
|
|
53
|
+
|
|
54
|
+
if (options.permission) {
|
|
55
|
+
builder.setDefaultMemberPermissions(PermissionFlagsBits[options.permission]);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (options.guildOnly !== false) {
|
|
59
|
+
builder.setDMPermission(false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ── Add options ───────────────────────────────────────────────────────
|
|
63
|
+
for (const opt of options.options ?? []) {
|
|
64
|
+
const method = TYPE_MAP[opt.type ?? "string"];
|
|
65
|
+
if (!method) throw new Error(`[ChrxCommand] Unknown option type: "${opt.type}"`);
|
|
66
|
+
|
|
67
|
+
builder[method]((o) => {
|
|
68
|
+
o.setName(opt.name).setDescription(opt.description);
|
|
69
|
+
if (opt.required) o.setRequired(true);
|
|
70
|
+
if (opt.choices && (opt.type === "string" || opt.type === "integer" || opt.type === "number")) {
|
|
71
|
+
o.addChoices(...opt.choices);
|
|
72
|
+
}
|
|
73
|
+
return o;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.data = builder;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Called by CommandLoader automatically.
|
|
82
|
+
* Handles cooldowns, permissions, ownerOnly, then calls run().
|
|
83
|
+
*/
|
|
84
|
+
async execute(interaction) {
|
|
85
|
+
const client = interaction.client;
|
|
86
|
+
const opts = this._options;
|
|
87
|
+
|
|
88
|
+
// ── Guild only ────────────────────────────────────────────────────────
|
|
89
|
+
if (opts.guildOnly !== false && !interaction.guild) {
|
|
90
|
+
return interaction.reply({ content: "❌ This command can only be used in a server.", ephemeral: true });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ── Owner only ────────────────────────────────────────────────────────
|
|
94
|
+
if (opts.ownerOnly && interaction.user.id !== process.env.OWNER_ID) {
|
|
95
|
+
return interaction.reply({ content: "❌ This command is restricted to the bot owner.", ephemeral: true });
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ── Permission check ──────────────────────────────────────────────────
|
|
99
|
+
if (opts.permission) {
|
|
100
|
+
const member = interaction.member;
|
|
101
|
+
if (!member?.permissions.has(PermissionFlagsBits[opts.permission])) {
|
|
102
|
+
return interaction.reply({ content: `❌ You need the **${opts.permission}** permission to use this.`, ephemeral: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── Cooldown ──────────────────────────────────────────────────────────
|
|
107
|
+
if (opts.cooldown) {
|
|
108
|
+
const key = `${interaction.user.id}-${opts.name}`;
|
|
109
|
+
const now = Date.now();
|
|
110
|
+
if (this._cooldowns.has(key)) {
|
|
111
|
+
const remaining = (opts.cooldown * 1000) - (now - this._cooldowns.get(key));
|
|
112
|
+
if (remaining > 0) {
|
|
113
|
+
return interaction.reply({
|
|
114
|
+
content: `⏱ Slow down! Wait **${(remaining / 1000).toFixed(1)}s** before using this again.`,
|
|
115
|
+
ephemeral: true,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
this._cooldowns.set(key, now);
|
|
120
|
+
setTimeout(() => this._cooldowns.delete(key), opts.cooldown * 1000);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ── Inject plugins from client ────────────────────────────────────────
|
|
124
|
+
// Plugins are attached to client.chrx.* if using ChrxClient
|
|
125
|
+
const plugins = {
|
|
126
|
+
economy: client.chrx?.economy,
|
|
127
|
+
moderation: client.chrx?.moderation,
|
|
128
|
+
giveaways: client.chrx?.giveaways,
|
|
129
|
+
tickets: client.chrx?.tickets,
|
|
130
|
+
welcome: client.chrx?.welcome,
|
|
131
|
+
polls: client.chrx?.polls,
|
|
132
|
+
reminders: client.chrx?.reminders,
|
|
133
|
+
starboard: client.chrx?.starboard,
|
|
134
|
+
automod: client.chrx?.automod,
|
|
135
|
+
xp: client.chrx?.xp,
|
|
136
|
+
ai: client.chrx?.ai,
|
|
137
|
+
db: client.db,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// ── Run ───────────────────────────────────────────────────────────────
|
|
141
|
+
try {
|
|
142
|
+
await opts.run(interaction, plugins);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.error(`[ChrxCommand] Error in /${opts.name}:`, err);
|
|
145
|
+
const msg = { content: "❌ Something went wrong running this command.", ephemeral: true };
|
|
146
|
+
if (interaction.replied || interaction.deferred) {
|
|
147
|
+
interaction.followUp(msg).catch(() => {});
|
|
148
|
+
} else {
|
|
149
|
+
interaction.reply(msg).catch(() => {});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
module.exports = ChrxCommandBuilder;
|
package/core/Client.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* The main ChrxClient class
|
|
4
|
-
* auto loaders, Lavalink, and optional modules.
|
|
2
|
+
* core/Client.js
|
|
3
|
+
* The main ChrxClient class.
|
|
5
4
|
*/
|
|
6
5
|
|
|
6
|
+
require("dotenv").config();
|
|
7
7
|
const { Client, GatewayIntentBits, Collection, Partials } = require("discord.js");
|
|
8
8
|
const { LavalinkManager } = require("lavalink-client");
|
|
9
9
|
const CommandLoader = require("./CommandLoader");
|
|
@@ -14,29 +14,12 @@ const XPSystem = require("./XPSystem");
|
|
|
14
14
|
const AIWrapper = require("./AIWrapper");
|
|
15
15
|
|
|
16
16
|
class ChrxClient {
|
|
17
|
-
/**
|
|
18
|
-
* @param {object} options
|
|
19
|
-
* @param {string} options.token - Bot token
|
|
20
|
-
* @param {string} [options.commandsPath] - Path to commands folder (default: ./commands)
|
|
21
|
-
* @param {string} [options.eventsPath] - Path to events folder (default: ./events)
|
|
22
|
-
* @param {object} [options.lavalink] - Lavalink config
|
|
23
|
-
* @param {string} options.lavalink.host
|
|
24
|
-
* @param {number} [options.lavalink.port]
|
|
25
|
-
* @param {string} options.lavalink.password
|
|
26
|
-
* @param {boolean} [options.lavalink.secure]
|
|
27
|
-
* @param {object} [options.modules] - Optional modules to enable
|
|
28
|
-
* @param {boolean} [options.modules.music] - Enable music system
|
|
29
|
-
* @param {boolean} [options.modules.xp] - Enable XP system
|
|
30
|
-
* @param {boolean} [options.modules.ai] - Enable AI wrapper
|
|
31
|
-
* @param {string} [options.modules.database] - Postgres connection string
|
|
32
|
-
* @param {number[]} [options.intents] - Override default intents
|
|
33
|
-
*/
|
|
34
17
|
constructor(options = {}) {
|
|
35
|
-
if (!options.token) throw new Error("[ChrxClient] token is required.");
|
|
18
|
+
if (!options.token) throw new Error("[ChrxClient] token is required. Check your bot token or this must be a error with the package.");
|
|
36
19
|
|
|
37
20
|
this._options = options;
|
|
38
21
|
|
|
39
|
-
// ── Discord client
|
|
22
|
+
// ── Discord client ────────────────────────────────────────────────────
|
|
40
23
|
this.client = new Client({
|
|
41
24
|
intents: options.intents ?? [
|
|
42
25
|
GatewayIntentBits.Guilds,
|
|
@@ -45,19 +28,32 @@ class ChrxClient {
|
|
|
45
28
|
GatewayIntentBits.GuildMembers,
|
|
46
29
|
GatewayIntentBits.GuildVoiceStates,
|
|
47
30
|
GatewayIntentBits.DirectMessages,
|
|
31
|
+
GatewayIntentBits.GuildMessageReactions,
|
|
48
32
|
],
|
|
49
|
-
partials: [Partials.Channel, Partials.Message],
|
|
33
|
+
partials: [Partials.Channel, Partials.Message, Partials.Reaction],
|
|
50
34
|
});
|
|
51
35
|
|
|
52
36
|
this.client.commands = new Collection();
|
|
53
|
-
this.client.chrx
|
|
54
|
-
|
|
55
|
-
// ──
|
|
37
|
+
this.client.chrx = this; // expose framework on client for plugin injection
|
|
38
|
+
|
|
39
|
+
// ── Plugin registry ───────────────────────────────────────────────────
|
|
40
|
+
// Plugins attach themselves here via registerPlugin()
|
|
41
|
+
this.economy = null;
|
|
42
|
+
this.moderation = null;
|
|
43
|
+
this.giveaways = null;
|
|
44
|
+
this.tickets = null;
|
|
45
|
+
this.welcome = null;
|
|
46
|
+
this.polls = null;
|
|
47
|
+
this.reminders = null;
|
|
48
|
+
this.starboard = null;
|
|
49
|
+
this.automod = null;
|
|
50
|
+
|
|
51
|
+
// ── Lavalink ──────────────────────────────────────────────────────────
|
|
56
52
|
if (options.lavalink && options.modules?.music !== false) {
|
|
57
53
|
this._setupLavalink(options.lavalink);
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
// ──
|
|
56
|
+
// ── Built-in modules ──────────────────────────────────────────────────
|
|
61
57
|
if (options.modules?.database) {
|
|
62
58
|
this.db = new Database(options.modules.database);
|
|
63
59
|
this.client.db = this.db;
|
|
@@ -74,9 +70,9 @@ class ChrxClient {
|
|
|
74
70
|
|
|
75
71
|
// ── Loaders ───────────────────────────────────────────────────────────
|
|
76
72
|
this._commandLoader = new CommandLoader(this.client, options.commandsPath);
|
|
77
|
-
this._eventLoader
|
|
73
|
+
this._eventLoader = new EventLoader(this.client, options.eventsPath);
|
|
78
74
|
|
|
79
|
-
// ── Ready
|
|
75
|
+
// ── Ready ─────────────────────────────────────────────────────────────
|
|
80
76
|
this.client.once("ready", async () => {
|
|
81
77
|
if (this.client.lavalink) {
|
|
82
78
|
await this.client.lavalink.init({
|
|
@@ -94,7 +90,7 @@ class ChrxClient {
|
|
|
94
90
|
console.log(`[ChrxClient] Ready! Logged in as ${this.client.user.tag}`);
|
|
95
91
|
});
|
|
96
92
|
|
|
97
|
-
// ── Voice state forwarding
|
|
93
|
+
// ── Voice state forwarding ────────────────────────────────────────────
|
|
98
94
|
this.client.on("raw", (d) => {
|
|
99
95
|
if (d.t === "VOICE_SERVER_UPDATE" || d.t === "VOICE_STATE_UPDATE") {
|
|
100
96
|
this.client.lavalink?.sendRawData(d);
|
|
@@ -111,8 +107,16 @@ class ChrxClient {
|
|
|
111
107
|
}
|
|
112
108
|
|
|
113
109
|
/**
|
|
114
|
-
*
|
|
110
|
+
* Register a plugin so it gets injected into ChrxCommand run() calls.
|
|
111
|
+
* Called automatically when you do new Economy(bot.client) etc.
|
|
112
|
+
* Or call manually: bot.registerPlugin("economy", economyInstance)
|
|
115
113
|
*/
|
|
114
|
+
registerPlugin(name, instance) {
|
|
115
|
+
this[name] = instance;
|
|
116
|
+
this.client.chrx[name] = instance;
|
|
117
|
+
console.log(`[ChrxClient] Plugin registered: ${name}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
116
120
|
_setupLavalink(cfg) {
|
|
117
121
|
this.client.lavalink = new LavalinkManager({
|
|
118
122
|
nodes: [
|
|
@@ -139,7 +143,6 @@ class ChrxClient {
|
|
|
139
143
|
},
|
|
140
144
|
});
|
|
141
145
|
|
|
142
|
-
// Attach music manager (handles events + marker system)
|
|
143
146
|
this.music = new MusicManager(this.client);
|
|
144
147
|
|
|
145
148
|
this.client.lavalink.on("nodeConnect", (node) =>
|
|
@@ -150,9 +153,6 @@ class ChrxClient {
|
|
|
150
153
|
);
|
|
151
154
|
}
|
|
152
155
|
|
|
153
|
-
/**
|
|
154
|
-
* Load commands and events then log in.
|
|
155
|
-
*/
|
|
156
156
|
async start() {
|
|
157
157
|
this._commandLoader.load();
|
|
158
158
|
this._eventLoader.load();
|
package/core/CommandLoader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/core/CommandLoader.js
|
|
3
3
|
* Auto-loads slash commands from the user's commands folder.
|
|
4
|
+
* Also. Please have a deploy-commands.js file or anything that refreshes (loads) commands.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const fs = require("fs");
|
|
@@ -14,7 +15,7 @@ class CommandLoader {
|
|
|
14
15
|
|
|
15
16
|
load() {
|
|
16
17
|
if (!fs.existsSync(this.commandsPath)) {
|
|
17
|
-
console.warn(`[CommandLoader] Commands folder not found at ${this.commandsPath}
|
|
18
|
+
console.warn(`[CommandLoader] Commands folder not found at ${this.commandsPath}. Make a commands folder with your remaining commands.`);
|
|
18
19
|
return;
|
|
19
20
|
}
|
|
20
21
|
|
|
@@ -48,4 +49,4 @@ class CommandLoader {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
module.exports = CommandLoader;
|
|
52
|
+
module.exports = CommandLoader;
|
package/core/EventLoader.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/core/EventLoader.js
|
|
3
3
|
* Auto-loads events from the user's events folder.
|
|
4
|
+
* Make a events folder, its not needed but can be useful for other materials if making a discord bot.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const fs = require("fs");
|
|
@@ -35,4 +36,4 @@ class EventLoader {
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
module.exports = EventLoader;
|
|
39
|
+
module.exports = EventLoader;
|
package/core/MusicManager.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/music/MusicManager.js
|
|
3
3
|
* Handles all Lavalink events and wires in the song marker system.
|
|
4
|
+
* Make music commands, this wont have pre-commands. Make an /play command, /stop and extras if needed.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const { EmbedBuilder } = require("discord.js");
|
|
@@ -75,4 +76,4 @@ class MusicManager {
|
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
module.exports = MusicManager;
|
|
79
|
+
module.exports = MusicManager;
|
package/core/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* src/index.js
|
|
3
3
|
* Main entry point — exports everything the user needs.
|
|
4
|
+
* An duplicate of index.js. You can delete if you want.
|
|
4
5
|
*/
|
|
5
6
|
|
|
6
7
|
const { ChrxClient } = require("./Client");
|
|
@@ -38,4 +39,4 @@ module.exports = {
|
|
|
38
39
|
applyStartMarker,
|
|
39
40
|
startEndMarkerWatcher,
|
|
40
41
|
stopEndMarkerWatcher,
|
|
41
|
-
};
|
|
42
|
+
};
|
package/core/songMarkers.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Per-track start/end marker system — lavalink-client v2 compatible.
|
|
4
4
|
*
|
|
5
5
|
* Markers are stored in memory. They persist as long as the bot is running
|
|
6
|
-
* but reset on restart. Swap the Map for Postgres if you want them permanent.
|
|
6
|
+
* but reset on restart. Swap the Map for Postgres or MongoDB if you want them permanent.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
// Key: track URI (or title fallback) → { start?: ms, end?: ms, loop?: bool }
|
package/index.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* index.js (not for a discord bot)
|
|
3
|
+
* Main entry point, will ALWAYS export everything.
|
|
4
|
+
* Listen to Project4play / SVJ at SoundCloud NOW!
|
|
5
|
+
*/
|
|
6
|
+
|
|
3
7
|
const { ChrxClient } = require("./core/Client");
|
|
4
8
|
const Database = require("./core/Database");
|
|
5
9
|
const XPSystem = require("./core/XPSystem");
|
|
6
10
|
const AIWrapper = require("./core/AIWrapper");
|
|
7
11
|
const MusicManager = require("./core/MusicManager");
|
|
12
|
+
const ChrxCommandBuilder = require("./core/ChrxCommandBuilder");
|
|
8
13
|
const {
|
|
9
14
|
parseTime,
|
|
10
15
|
formatTime,
|
|
@@ -17,22 +22,28 @@ const {
|
|
|
17
22
|
} = require("./core/songMarkers");
|
|
18
23
|
|
|
19
24
|
// ── Plugins ───────────────────────────────────────────────────────────────
|
|
20
|
-
const Economy
|
|
25
|
+
const Economy = require("./plugins/Economy");
|
|
21
26
|
const Moderation = require("./plugins/Moderation");
|
|
22
|
-
const Giveaways
|
|
23
|
-
const Tickets
|
|
24
|
-
const Welcome
|
|
25
|
-
const Polls
|
|
26
|
-
const Reminders
|
|
27
|
-
const Starboard
|
|
28
|
-
const AutoMod
|
|
27
|
+
const Giveaways = require("./plugins/Giveaways");
|
|
28
|
+
const Tickets = require("./plugins/Tickets");
|
|
29
|
+
const Welcome = require("./plugins/Welcome");
|
|
30
|
+
const Polls = require("./plugins/Polls");
|
|
31
|
+
const Reminders = require("./plugins/Reminders");
|
|
32
|
+
const Starboard = require("./plugins/Starboard");
|
|
33
|
+
const AutoMod = require("./plugins/AutoMod");
|
|
29
34
|
|
|
30
35
|
module.exports = {
|
|
36
|
+
// Core
|
|
31
37
|
ChrxClient,
|
|
38
|
+
ChrxCommandBuilder,
|
|
39
|
+
|
|
40
|
+
// Modules
|
|
32
41
|
Database,
|
|
33
42
|
XPSystem,
|
|
34
43
|
AIWrapper,
|
|
35
44
|
MusicManager,
|
|
45
|
+
|
|
46
|
+
// Song marker utilities
|
|
36
47
|
parseTime,
|
|
37
48
|
formatTime,
|
|
38
49
|
setMarker,
|
|
@@ -41,6 +52,8 @@ module.exports = {
|
|
|
41
52
|
applyStartMarker,
|
|
42
53
|
startEndMarkerWatcher,
|
|
43
54
|
stopEndMarkerWatcher,
|
|
55
|
+
|
|
56
|
+
// Plugins
|
|
44
57
|
Economy,
|
|
45
58
|
Moderation,
|
|
46
59
|
Giveaways,
|
package/package.json
CHANGED
|
File without changes
|